/*
 * 由SharpDevelop创建。
 * 用户： Administrator
 * 日期: 2018-04-02
 * 时间: 21:11
 *
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */

using System;
using System.ComponentModel;
using MessagePack;
using Newtonsoft.Json;

#if Server
using Server.Core;
#else
using GameFramework;
#endif

namespace GameData
{
    /// <summary>
    /// 包头协议 描述
    /// </summary>
    [MessagePackObject]
    public class PackHead
        : IReference
    {
        /// <summary>
        /// 包类型
        /// </summary>
        [Key(0)] public int packlx;

        /// <summary>
        /// userid
        /// </summary>
        [Key(1)] public int userid;


        /// <summary>
        /// 平台0PC 1Android 2Ios 3MiniGame 4WebGl
        /// </summary>
        [Key(2)] public string plat;

        /// <summary>
        /// 平台 整数值 后续把上面的plat移除
        /// </summary>
        [Key(3)] public int platValue;

        /// <summary>
        /// 客户端版本
        /// </summary>
        [Key(4)] public int clientVer;

        /// <summary>
        /// 其他int参数
        /// </summary>
        [Key(5)] public int[] otherInt;

        /// <summary>
        /// 其他字符串参数
        /// </summary>
        [Key(6)] public string[] otherString;

        /// <summary>
        /// 客户端的标识，每个客户端都是唯一的
        /// </summary>
        [Key(7)] public string clientSign;

        /// <summary>
        /// 会话ID
        /// </summary>
        [IgnoreMember] public string SessionUUID;
        
#if Server
        /// <summary>
        /// 中转包类型
        /// </summary>
        [IgnoreMember] public int transfer;

        [IgnoreMember] [JsonIgnore] public bool IsFromPool { get; set; }

        [IgnoreMember] [JsonIgnore] public long ReferenceId { get; set; }

        /// <summary>
        /// http 请求ID
        /// </summary>
        [DefaultValue(-1)] [IgnoreMember] public int requestId = -1;

        /// <summary>
        /// 时间验证
        /// </summary>
        [DefaultValue(-1)] [IgnoreMember] public long doid = -1;

        /// <summary>
        /// 发送的模块
        /// </summary>
        [IgnoreMember] public ModuleUtile sendutil;

        /// <summary>
        /// 通讯模块
        /// </summary>
        [IgnoreMember] public ServerNode Util;

        /// <summary>
        /// IP地址
        /// </summary>
        [IgnoreMember] public string ip;

        /// <summary>
        /// 游戏节点
        /// </summary>
        //[ProtoBuf.ProtoMember(14)]
        [IgnoreMember] public ServerNode gameNode;

        [IgnoreMember] public ServerNode[] utils;

        /// <summary>
        /// 添加模块
        /// </summary>
        /// <param name="util">添加的模块</param>
        public bool AddModule(ModuleUtile util)
        {
            if (utils == null)
            {
                utils = new ModuleUtile[] { util };
                return true;
            }

            int len = utils.Length;
            if (len > 0)
            {
                return false;
            }

            for (int i = 0; i < len; i++)
            {
                if (util.id == utils[i].id)
                    return false;
            }

            ModuleUtile[] temp = new ModuleUtile[len + 1];
            temp[len] = util;
            Array.Copy(utils, 0, temp, 0, len);
            utils = temp;
            return true;
        }

        public ServerNode GetUtil()
        {
            if (Util != null)
            {
                return Util;
            }

            if (utils != null && utils.Length > 0)
            {
                return utils[0];
            }

            return null;
        }
#endif

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            plat = null;
            otherInt = null;
            otherString = null;
            clientSign = null;
#if Server
            Util = null;
            sendutil = null;
            ip = null;
            ReferencePool.Recycle(this);
#endif
        }

#if Server
        public static PackHead Create()
        {
            PackHead head = ReferencePool.Fetch<PackHead>();
            return head;
        }

        public static PackHead Create(int packLx)
        {
            PackHead head = ReferencePool.Fetch<PackHead>();
            head.packlx = packLx;
            return head;
        }
#else
        /// <summary>
        /// 
        /// </summary>
        public PackHead()
        {
        }

        public PackHead(int packLx)
        {
            this.packlx = packLx;
        }

        public static PackHead Create(int packLx)
        {
            PackHead head = ReferencePool.Acquire<PackHead>();
            head.packlx = packLx;
            return head;
        }   

        public void Clear()
        {
            Dispose();
        }
#endif
    }

#if Server
    /// <summary>
    /// 平台枚举
    /// </summary>
    public enum PlatEnum
    {
        /// <summary>
        /// 桌面模式
        /// </summary>
        Window = 0,

        /// <summary>
        /// 安卓平台
        /// </summary>
        Android = 1,

        /// <summary>
        /// 苹果平台
        /// </summary>
        Ios = 2,

        /// <summary>
        /// 小游戏
        /// </summary>
        MiniGame = 3,

        /// <summary>
        /// WebGl
        /// </summary>
        WebGL = 4,
    }
#endif
}