using CommonAI.Zone.ZoneEditor;
using CommonAIClient.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ZeusServerTestClient
{
    public class NodeTestBattleClient : AbstractBattle
    {
        public string PlayerUUID { get { return player_uuid; } }

        private readonly string player_uuid;
        private readonly string display_name;
        private readonly int unit_template_id;
        private readonly byte force;

        private readonly NodeTestPlayer mPlayer;

        private readonly HashMap<string, object> mAttributes = new HashMap<string, object>();
        private readonly ZoneNodeCodec codec = new ZoneNodeCodec(ZoneNodeManager.MessageFactory);

        public NodeTestBattleClient(EditorTemplates data_root, string player_uuid, string display_name, int unit_template_id, byte force)
            : base(data_root)
        {
            this.player_uuid = player_uuid;
            this.display_name = display_name;
            this.unit_template_id = unit_template_id;
            this.force = force;
            this.mPlayer = new NodeTestPlayer(player_uuid, display_name, unit_template_id, force, node);
            this.mPlayer.OnMessageSentToClient += mPlayer_OnMessageSentToClient;
        }
        private void mPlayer_OnMessageSentToClient(IMessage msg)
        {
            mRecvPack++;
            Layer.ProcessMessage(msg as IMessage);
        }

        //--------------------------------------------------------------------------------------------
        #region BattleClient
        private int mRecvPack = 0;
        private int mSentPack = 0;
        public override long RecvPackages { get { return mRecvPack; } }
        public override long SendPackages { get { return mSentPack; } }
        public override int CurrentPing { get { return 0; } }
        public override bool IsNet { get { return true; } }
        public override RoomService.Net.BsServer.KickedByServerNotifyB2C KickMessage { get { return null; } }
        public override void SendAction(CommonAI.Zone.Action action)
        {
            byte[] data;
            if (codec.doEncode(action, out data))
            {
                mSentPack++;
                node.OnPlayerReceivedMessage(mPlayer, data);
            }
        }
        #endregion

        //--------------------------------------------------------------------------------------------
        public void Start()
        {
            PlayerEnterRoomS2R enter = new PlayerEnterRoomS2R();
            enter.Pos = new CommonAI.RTS.Vector2(0, 0);
            enter.UnitData = new CommonAI.ZoneServer.CreateUnitInfoR2B();
            enter.UnitData.Force = force;
            enter.UnitData.StartFlag = null;
            enter.UnitData.UnitTemplateID = unit_template_id;
            enter.UnitData.UnitPropData = new ZeusCommon.Plugin.ZeusUnitProperties();
            node.OnPlayerEnter(mPlayer, enter);
        }
        public void Stop()
        {
            node.OnPlayerLeave(mPlayer);
        }
    }


    public class NodeTestClientGroup
    {
        private long mLastUpdateTime = 0;

        private List<NodeTestBattleClient> clients = new List<NodeTestBattleClient>();

        public void Update()
        {
            long curTime = CommonLang.CUtils.CurrentTimeMS;
            if (mLastUpdateTime == 0)
            {
                mLastUpdateTime = curTime;
            }
            int intervalMS = (int)(curTime - mLastUpdateTime);
            this.mLastUpdateTime = curTime;
            foreach (NodeTestBattleClient client in clients)
            {
                client.BeginUpdate(intervalMS);
                client.Update(intervalMS);
            }
        }
        public void AddClient(NodeTestBattleClient client)
        {
            if (!clients.Contains(client))
            {
                client.Layer.ActorAdded += (layer, actor) =>
                {
                    actor.SendUnitGuard(true);
                };
                clients.Add(client);
                client.Start();
            }
        }
        public void Leave(NodeTestBattleClient client)
        {
            if (clients.Contains(client))
            {
                client.Stop();
            }
        }
    }
}