using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FObjBase
{

    public class Pack_Proto : IPack 
    {
        private UInt16 plen;
        public UInt32 destid;
        public UInt32 srcid;
        public UInt32 magic;
        public UInt16 info;
        public byte[] buf;


        public byte[] ToBytes()
        {
            List<byte> buf = new List<byte>();
            plen = (UInt16)(2 + 4 * 3 + 2);
            if(this.buf!=null)
                plen = (UInt16)(plen + this.buf.Length);
            

            buf.AddRange(BitConverter.GetBytes(plen));
            buf.AddRange(BitConverter.GetBytes(destid));
            buf.AddRange(BitConverter.GetBytes(srcid));
            buf.AddRange(BitConverter.GetBytes(magic));
            buf.AddRange(BitConverter.GetBytes(info));
            if(this.buf!=null)
                buf.AddRange(this.buf);

            return buf.ToArray();
        }

        public bool TryParse(byte[] value)
        {
            if(value.Length<(2 + 4 * 3 + 2))
                return false;
            int index = 0;
            plen = BitConverter.ToUInt16(value, index);
            index += 2;
            if(value.Length!=plen)
                return false;

            destid = BitConverter.ToUInt32(value, index);
            index += 4;
            srcid = BitConverter.ToUInt32(value, index);
            index += 4;
            magic = BitConverter.ToUInt32(value, index);
            index += 4;
            info = BitConverter.ToUInt16(value, index);
            index += 2;
            int len = value.Length - index;
            if (len <= 0)
                return true;

            buf = new byte[len];
            Array.Copy(value, index, buf, 0, len);
            return true;
        }
    }
    public class Proto
    { 
        #region client->server
        /// <summary>
        /// client->server;
        /// setvalue 不能改！！！
        /// </summary>
        public const  UInt16 INFO_SET_VALUE = 0x0002;
        /// <summary>
        /// client->server;
        /// getvalue 不能改！！！
        /// </summary>
        public const  UInt16 INFO_GET_VALUE = 0x0003;
        /// <summary>
        /// client->server;
        /// callfunction 不能改！！！
        /// </summary>
        public const  UInt16 INFO_CALL_FUNCTION = 0x0004;
        /// <summary>
        /// client->server;
        /// config_sense 不能改！！！
        /// </summary>
        public const  UInt16 INFO_CONFIG_SENSE_OBJ = 0x0005;
        /// <summary>
        /// client->server
        /// callfunction 的参数很长，需要多次发送
        /// </summary>
        public const UInt16 INFO_CALL_FUNCTION_REQUEST_BIGSIZE = 0x0006;
        /// <summary>
        /// client->server
        /// callfunction 的返回很长，需要多次请求获取
        /// </summary>
        public const UInt16 INFO_CALL_FUNCTION_REPONSE_BIGSIZE = 0x0007;
        /// <summary>
        /// client->server
        /// obj 已经不在了， 释放资源
        /// </summary>
        public const UInt16 INFO_OBJ_DISPOSE = 0x0009;
        #endregion

        #region server->client
        /// <summary>
        /// server->client;
        /// getvalue 返回 不能改！！！
        /// </summary>
        public const UInt16 INFO_PUSH_GET_VALUE = 0x0403;
        /// <summary>
        /// server->client;
        /// callfunction 返回 不能改！！！
        /// </summary>
        public const UInt16 INFO_PUSH_CALL_FUNCTION = 0x0404;
        /// <summary>
        /// server->client;
        /// pushinfo 不能改！！！
        /// </summary>
        public const UInt16 INFO_PUSH_EVENT=0x0410;
        /// <summary>
        /// server->client
        /// callfunction 的参数很长，需要多次发送
        /// </summary>
        public const UInt16 INFO_PUSH_CALL_FUNCTION_REQUEST_BIGSIZE = 0x0406;
        /// <summary>
        /// server->client
        /// callfunction 的返回很长，需要多次请求获取
        /// </summary>
        public const UInt16 INFO_PUSH_CALL_FUNCTION_REPONSE_BIGSIZE = 0x0407;
        #endregion
    }
    public class Pack_BigSize : IPack 
    {
        public UInt16 funcid;
        public int size;
        public int position;
        public byte[] buf;
        public byte[] ToBytes()
        {
            List<byte> buf = new List<byte>();
            buf.AddRange(BitConverter.GetBytes(funcid));
            buf.AddRange(BitConverter.GetBytes(size));
            buf.AddRange(BitConverter.GetBytes(position));
            buf.AddRange(BitConverter.GetBytes(this.buf.Length));
            buf.AddRange(this.buf);
            return buf.ToArray();
        }

        public bool TryParse(byte[] value)
        {
            int cnt = 2 + 4 * 3;
            if (value.Length < cnt)
                return false;
            int idx = 0;
            funcid = BitConverter.ToUInt16(value, idx);
            idx += 2;
            size = BitConverter.ToInt32(value, idx);
            idx += 4;
            position = BitConverter.ToInt32(value, idx);
            idx += 4;
            int len = BitConverter.ToInt32(value, idx);
            idx += 4;
            cnt += len;
            if (value.Length < cnt)
                return false;
            buf = new byte[len];
            Array.Copy(value, idx, buf, 0, buf.Length);
            return true;
        }
    }
    public class Pack_GetSetPushCall : IPack 
    {
        public UInt16 infoid;
        public byte[] infodata = null;


        public byte[] ToBytes()
        {
            List<byte> buf = new List<byte>();
            buf.AddRange(BitConverter.GetBytes(infoid));
            if (infodata != null)
            {
                buf.AddRange(infodata);
            }
            return buf.ToArray();
        }

        public bool TryParse(byte[] value)
        {
            if (value.Length < 2)
                return false;
            infoid = BitConverter.ToUInt16(value, 0);
            int info_len = value.Length - 2;
            
            if (info_len > 0)
            {
                infodata = new byte[info_len];
                Buffer.BlockCopy(value, 2, infodata, 0, info_len);
            }
            else
                infodata = null;
            return true;
        }
    }
}


