using System;
using System.Collections.Generic;
using System.Text;
using CommonAI.RTS;
using CommonLang.Vector;
using CommonLang;
using CommonAI.Zone;
using CommonAI.Zone.ZoneEditor;
using CommonAI.Zone.Instance;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Attributes;
using CommonAI.ZoneClient.Agent;
using CommonLang.Concurrent;

namespace CommonAI.ZoneClient
{
    public abstract class ZoneLayerObject : GameEntity
    {
        private static AtomicInteger s_active_object_count = new AtomicInteger(0);
        private static AtomicInteger s_alloc_object_count = new AtomicInteger(0);
        /// <summary>
        /// 实例数量
        /// </summary>
        public static int ActiveObjectCount { get { return s_active_object_count.Value; } }
        /// <summary>
        /// 实例数量
        /// </summary>
        public static int AllocObjectCount { get { return s_alloc_object_count.Value; } }

        virtual public float X { get { return mPos.X; } }
        virtual public float Y { get { return mPos.Y; } }
        /// <summary>
        /// 这里表示高度
        /// </summary>
        virtual public float Z { get; protected set; }

        protected readonly Vector2 mPos = new Vector2();
        private readonly ZoneLayer mParent;

        public ZoneLayerObject(ZoneLayer parent)
        {
            s_alloc_object_count++;
            s_active_object_count++;
            this.mParent = parent;
            this.Z = 0;
        }
        ~ZoneLayerObject()
        {
            s_alloc_object_count--;
        }

        public ZoneLayer Parent
        {
            get { return mParent; }
        }
        public TemplateManager Templates
        {
            get { return mParent.Templates; }
        }
        protected override void Disposing()
        {
            base.Disposing();
            s_active_object_count--;
        }
        virtual public void ForceSyncPos(float x, float y)
        {
            mPos.SetX(x);
            mPos.SetY(y);
        }
    }

    public abstract class ZoneObject : ZoneLayerObject, IPositionObject
    {
        /// <summary>
        /// 单位ID
        /// </summary>
        public uint ObjectID { get { return ObjID; } }
        /// <summary>
        /// 是否在场景里
        /// </summary>
        public bool IsEnable { get; private set; }
        public abstract string Name { get; }
        public abstract string DisplayName { get; }
        public virtual bool TouchObj { get { return false; } }
        public virtual bool TouchMap { get { return false; } }
        virtual public float Direction { get { return mDirection; } internal set { mDirection = value; } }
        abstract public float RadiusSize { get; }

        readonly private uint ObjID;

        protected float mDirection;

        internal readonly SpaceDivision.ObjectCellNode mCurrentCellNode;

        private Vector2 mLastPos = new Vector2();


        public ZoneObject(uint objectID, ZoneLayer parent) : base(parent)
        {
            this.IsEnable = true;
            this.ObjID = objectID;
            this.mCurrentCellNode = new SpaceDivision.ObjectCellNode(this);
        }
        protected internal virtual void OnAdded() { }

        protected override void Disposing()
        {
            base.Disposing();
            IsEnable = false;
            mOnDoEvent = null;
        }

        internal protected abstract void DoEvent(ObjectEvent e);

        //-------------------------------------------------------------------------------------

        internal protected virtual void UpdateAI() { }
        internal protected abstract void Update();
        internal bool UpdatePos()
        {
            if (mLastPos.X != this.X || mLastPos.Y != this.Y)
            {
                mLastPos.SetX(this.X);
                mLastPos.SetY(this.Y);
                mCurrentCellNode.MarkPosDirty(true);
                Parent.SwapSpace(this);
                return true;
            }
            mCurrentCellNode.MarkPosDirty(false);
            return false;
        }

        //-------------------------------------------------------------------------------------

        virtual public void SyncPos(ref SyncPosEvent.UnitPos pos)
        {
            this.mPos.SetX(pos.X);
            this.mPos.SetY(pos.Y);
            this.Direction = pos.Direction;
            if (Parent.IsSyncZ) { this.Z = pos.Z; }
        }
        virtual public void SyncPos(ref SyncPosEvent.UnitState pos)
        {

        }

        virtual public void SetClientLocalCurrentState(UnitActionStatus state, object evt) 
        { 
        
        }
        //-------------------------------------------------------------------------------------

        public delegate void OnDoEventHandler(ZoneObject obj, ObjectEvent e);
        internal OnDoEventHandler mOnDoEvent;
        [EventTriggerDescAttribute("单位接收到服务端事件")]
        public event OnDoEventHandler OnDoEvent { add { mOnDoEvent += value; } remove { mOnDoEvent -= value; } }

        //-------------------------------------------------------------------------------------
    }


}