using CommonAI.RTS;
using CommonLang.Vector;
using CommonAI.Zone.Instance;
using CommonLang;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonAI.Zone.Helper
{
    public class TeamFormationGroup
    {
        private readonly ZoneRegion mRegion;
        private readonly TeamFormation mData;
        public ZoneRegion Region { get { return mRegion; } }
        public InstanceZone Zone { get { return mRegion.Parent; } }
        public TeamFormation Data { get { return mData; } }
        public TeamFormation.Formation TFormation { get { return mData.TFormation; } }

        // 单位和预期坐标对应关系 //
        private List<TeamMember> mObjects = new List<TeamMember>();

        public TeamFormationGroup(TeamFormation team, ZoneRegion region)
        {
            this.mData = team;
            this.mRegion = region;
        }

        public void AddPos(float x, float y, float dr)
        {
            mObjects.Add(new TeamMember(x, y, dr));
        }

        /// <summary>
        /// 初始化,直接放置坐标位置
        /// </summary>
        public void ResetPos()
        {
            IVector2 center = mRegion.Pos;
            switch (mData.TFormation)
            {
                case TeamFormation.Formation.Random:
                    ResetRandom(center);
                    break;
                case TeamFormation.Formation.Square:
                    ResetSquare(center);
                    break;
                case TeamFormation.Formation.Round:
                    ResetRound(center);
                    break;
                case TeamFormation.Formation.Cycle:
                    ResetCycle(center);
                    break;
                case TeamFormation.Formation.Beehive:
                    ResetBeehive(center);
                    break;
                case TeamFormation.Formation.Line:
                    ResetLine(center);
                    break;
                default:
                    ResetRandom(center);
                    break;
            }
            for (int i = mObjects.Count - 1; i >= 0; i--)
            {
                var tm = mObjects[i];
                tm.SetToExpect(mRegion);
            }
        }
        public TeamMember PopPos()
        {
            if (mObjects.Count > 0)
            {
                var index = mObjects.Count - 1;
                var ret = mObjects[index];
                mObjects.RemoveAt(index);
                return ret;
            }
            return null;
        }
        public void Clear()
        {
            mObjects.Clear();
        }

        private void ResetRandom(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeRandom(center, mObjects, mData.SpacingSize, Zone.RandomN);
        }
        private void ResetSquare(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeSquare(center, mObjects, mData.SpacingSize);
        }
        private void ResetRound(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeRound(center, mObjects, mData.SpacingSize);
        }
        private void ResetCycle(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeCycle(center, mObjects, mData.SpacingSize);
        }
        private void ResetBeehive(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeBeehive(center, mObjects, mData.SpacingSize);
        }
        private void ResetLine(IVector2 center)
        {
            VectorGroupHelper.DistributeSpacingSizeLine(center, mObjects, mData.SpacingSize);
        }

        public class TeamMember : IPositionObject, IVector2
        {
            //private InstanceZoneObject unit;
            private float expect_x;
            private float expect_y;
            private float expect_direction;

            public TeamMember(float x, float y, float dr)
            {
                //this.unit = obj;
                this.expect_x = x;
                this.expect_y = y;
                this.expect_direction = dr;
            }
            public float X { get { return expect_x; } set { expect_x = value; } }
            public float Y { get { return expect_y; } set { expect_y = value; } }
            public float Direction { get { return expect_direction; } set { expect_direction = value; } }
            public float RadiusSize { get { return 1; } }
            //public InstanceZoneObject Unit { get { return unit; } }

            internal void SetToExpect(ZoneRegion region)
            {
                region.keepInRegion(ref expect_x, ref expect_y);
            }

			public void SetX(float value)
			{
				expect_x = value;
			}

			public void SetY(float value)
			{
				expect_y = value;
			}

			public void AddX(float value)
			{
				expect_x += value;
			}

			public void AddY(float value)
			{
				expect_y += value;
			}
		}
    }
}