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

namespace CommonAI.Zone.ZoneEditor.EventTrigger
{

    [DescAttribute("手动控制", "单位 - 手动控制")]
    public abstract class ManualUnitAction : AbstractAction
    {
        public abstract string ToActionString();
    }

    [DescAttribute("单位待机", "单位 - 手动控制")]
    public class ManualUnitIdleAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("待机时间")]
        public RealValue TimeSEC = new RealValue.VALUE();

        public override string ToString()
        {
            return string.Format("手动控制({0})待机{1}秒", Unit, TimeSEC);
        }
        public override string ToActionString()
        {
            return string.Format("待机{0}秒", TimeSEC);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            if (unit != null)
            {
                unit.queueIdle(TimeSEC.GetValue(api, args));
            }
        }
    }

    [DescAttribute("单位做动作", "单位 - 手动控制")]
    public class ManualUnitDoClientAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("动作名字")]
        public string ActionName;

        [DescAttribute("动作持续时间(秒)")]
        public RealValue TimeSEC = new RealValue.VALUE();

        public override string ToString()
        {
            return string.Format("手动控制({0})做动作{1}", Unit, ActionName);
        }
        public override string ToActionString()
        {
            return string.Format("做动作{0}", ActionName);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            if (unit != null)
            {
                unit.queueDoAction(TimeSEC.GetValue(api, args), ActionName);
            }
        }
    }

    [DescAttribute("单位移动", "单位 - 手动控制")]
    public class ManualUnitMoveAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("位置")]
        public PositionValue Pos = new PositionValue.VALUE();

        public override string ToString()
        {
            return string.Format("手动控制({0})移动到{1}", Unit, Pos);
        }
        public override string ToActionString()
        {
            return string.Format("移动到{0}", Pos);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            Vector2 pos = Pos.GetValue(api, args);
            if (unit != null && pos != null)
            {
                unit.startMoveTo(pos.X, pos.Y);
            }
        }
    }

    [DescAttribute("单位改变朝向", "单位 - 手动控制")]
    public class ManualUnitFaceToAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("方向")]
        public RealValue Direction = new RealValue.VALUE();

        public override string ToString()
        {
            return string.Format("手动控制({0})转向到{1}", Unit, Direction);
        }
        public override string ToActionString()
        {
            return string.Format("转向到{0}", Direction);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            if (unit != null)
            {
                unit.faceTo(Direction.GetValue(api, args));
            }
        }
    }

    [DescAttribute("单位释放技能", "单位 - 手动控制")]
    public class ManualUnitLaunchSkillAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("随机技能,如果为True,则SkillTemplateID无效")]
        public BooleanValue RandomSkill = new BooleanValue.VALUE();

        [TemplateIDAttribute(typeof(SkillTemplate))]
        [DescAttribute("技能模板ID")]
        public int SkillTemplateID;

        public override string ToString()
        {
            return string.Format("手动控制({0})释放技能{1}", Unit, SkillTemplateID);
        }
        public override string ToActionString()
        {
            return string.Format("释放技能{0}", SkillTemplateID);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            if (unit != null)
            {
                unit.launchSkill(SkillTemplateID, new InstanceUnit.LaunchSkillParam());
            }
        }
    }

    [DescAttribute("开始攻击单位", "单位 - 手动控制")]
    public class ManualUnitFocuseAttackAction : ManualUnitAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();
        [DescAttribute("目标")]
        public UnitValue Target = new UnitValue.Editor();

        public override string ToString()
        {
            return string.Format("手动控制({0})开始攻击单位{1}", Unit, Target);
        }
        public override string ToActionString()
        {
            return string.Format("开始攻击单位{0}", Target);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            InstanceUnit target = Target.GetValue(api, args);
            if (unit != null && target != null)
            {
                unit.focuseAttack(target);
            }
        }
    }




    [DescAttribute("等待下一条指令(仅队列中有效)", "单位 - 手动控制")]
    public class ManualUnitWaitCommandAction : ManualUnitAction
    {
        [DescAttribute("等待时间")]
        public RealValue WaitTimeSEC = new RealValue.VALUE();

        public override string ToString()
        {
            return string.Format("等待{0}秒", WaitTimeSEC);
        }
        public override string ToActionString()
        {
            return string.Format("等待{0}秒", WaitTimeSEC);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {

        }
    }

    [DescAttribute("一系列动作", "单位 - 手动控制")]
    public class ManualUnitControlQueue : AbstractAction
    {
        [DescAttribute("单位")]
        public UnitValue Unit = new UnitValue.Editor();

        [DescAttribute("动作序列")]
        [ListAttribute(typeof(ManualUnitAction))]
        public List<ManualUnitAction> Actions = new List<ManualUnitAction>();

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (ManualUnitAction act in Actions)
            {
                sb.Append(act.ToActionString() + " -> ");
            }
            sb.Append("END");
            return string.Format("({0})执行序列: {1}", Unit, sb);
        }
        override public void DoAction(EventTriggerAdapter api, EventArguments args)
        {
            InstanceManual unit = Unit.GetValue(api, args) as InstanceManual;
            if (unit != null && Actions.Count > 0)
            {
                new ActionQueueExecuter(api, args, unit, Actions).doNextAction();
            }
        }

        class ActionQueueExecuter
        {
            private EventTriggerAdapter api;
            private EventArguments args;
            private InstanceManual unit;
            private Queue<ManualUnitAction> actions;

            public ActionQueueExecuter(EventTriggerAdapter api, EventArguments args, InstanceManual manual, List<ManualUnitAction> actions)
            {
                this.api = api;
                this.args = args;
                this.unit = manual;
                this.actions = new Queue<ManualUnitAction>(actions);
            }

            public void doNextAction()
            {
                if (actions.Count > 0)
                {
                    ManualUnitAction act = actions.Dequeue();
                    if (act is ManualUnitIdleAction)
                    {
                        doIdle(act as ManualUnitIdleAction);
                    }
                    else if (act is ManualUnitMoveAction)
                    {
                        doMove(act as ManualUnitMoveAction);
                    }
                    else if (act is ManualUnitFaceToAction)
                    {
                        doFaceTo(act as ManualUnitFaceToAction);
                    }
                    else if (act is ManualUnitLaunchSkillAction)
                    {
                        doLaunchSkill(act as ManualUnitLaunchSkillAction);
                    }
                    else if (act is ManualUnitDoClientAction)
                    {
                        doClientAction(act as ManualUnitDoClientAction);
                    }
                    else if (act is ManualUnitFocuseAttackAction)
                    {
                        doAttackAction(act as ManualUnitFocuseAttackAction);
                    }
                    else if (act is ManualUnitWaitCommandAction)
                    {
                        doWaitCommand(act as ManualUnitWaitCommandAction);
                    }
                }
            }

            private void doIdle(ManualUnitIdleAction idle)
            {
                unit.queueIdle(idle.TimeSEC.GetValue(api, args), (InstanceUnit u, InstanceUnit.State os) =>
                {
                    doNextAction();
                });
            }

            private void doMove(ManualUnitMoveAction move)
            {
                Vector2 pos = move.Pos.GetValue(api, args);
                if (pos != null)
                {
                    unit.queueMoveTo(pos.X, pos.Y, (InstanceUnit u, InstanceUnit.State os) =>
                    {
                        doNextAction();
                    });
                }
                else
                {
                    doNextAction();
                }
            }

            private void doFaceTo(ManualUnitFaceToAction faceTo)
            {
                unit.faceTo(faceTo.Direction.GetValue(api, args));
                doNextAction();
            }

            private void doLaunchSkill(ManualUnitLaunchSkillAction skill)
            {
                unit.queueLaunchSkill(skill.SkillTemplateID, skill.RandomSkill.GetValue(api, args), (InstanceUnit u, InstanceUnit.State os) =>
                {
                    doNextAction();
                });
            }

            private void doClientAction(ManualUnitDoClientAction skill)
            {
                unit.queueDoAction(skill.TimeSEC.GetValue(api, args), skill.ActionName, (InstanceUnit u, InstanceUnit.State os) =>
                {
                    doNextAction();
                });
            }

            private void doAttackAction(ManualUnitFocuseAttackAction act)
            {
                InstanceUnit targget = act.Target.GetValue(api, args);
                if (targget != null)
                {
                    unit.focuseAttack(targget);
                }
                doNextAction();
            }

            private void doWaitCommand(ManualUnitWaitCommandAction act)
            {
                unit.wait(act.WaitTimeSEC.GetValue(api, args), () => { doNextAction(); });
            }
        }

    }
}