using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using CommonLang.Log;
using System;
using XmdsCommon.Plugin;
using XmdsCommonServer.Plugin.Units;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator;
using CommonAI.Zone;
using XmdsCommonServer.XLS.Data;

namespace XmdsCommonServer.Plugin
{
    public class XmdsBattleHelper
    {
        protected static Logger log = LoggerFactory.GetLogger("XmdsBattleSkill");

        private static int GetPercentValue(float src, float percent)
        {
            return CUtils.CastInt(src * percent);
        }


        #region 获得召唤单位宿主的XmdsVirtual.

        public static XmdsVirtual GetSummonMaster(XmdsVirtual summonunit)
        {
            XmdsVirtual ret = null;

            ISummonedUnit u = summonunit.mUnit as ISummonedUnit;

            if (u != null && u.SummonerUnit != null && u.SummonerUnit.IsActive)
            {
                ret = XmdsZoneServerFactory.ToVirtual(u.SummonerUnit);
            }

            return ret;
        }

        #endregion

        #region 获得一定范围内离单位最近的目标.

        public static InstanceUnit GetNearestFirstTarget(
            InstanceUnit unit, float x, float y, int range,
            CommonAI.Zone.SkillTemplate.CastTarget exceptTarget,
            AttackReason reason,
            InstanceUnit ingore = null)
        {
            InstanceUnit ret = null;
            using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
            {
                unit.Parent.getObjectsRoundRange<InstanceUnit>(
                    (obj, dx, dy, dr) =>
                    {
                        var u = obj as InstanceUnit;
                        if (u != ingore && u.Parent.IsAttackable(unit, u, exceptTarget, reason, unit.Info))
                        {
                            return CMath.includeRoundPoint(dx, dy, dr, u.X, u.Y);
                        }
                        return false;
                    },
                    x,
                    y,
                    range,
                    list, 
                    unit.AoiStatus);
                if (list.Count > 0)
                {
                    list.Sort(new ObjectSorterNearest<InstanceUnit>(x, y));
                    ret = list[0];
                }
            }
            return ret;
        }

        /// <summary>
        /// 获得一定范围内离单位最近的单位列表.
        /// </summary>
        /// <param name="unit"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="range"></param>
        /// <param name="exceptTarget"></param>
        /// <param name="reason"></param>
        /// <param name="do_action"></param>
        public static void ForEachRangedAttackableTargets(
            InstanceUnit unit, float x, float y, int range,
            CommonAI.Zone.SkillTemplate.CastTarget exceptTarget,
            AttackReason reason,
            Action<InstanceUnit> do_action)
        {
            unit.Parent.ForEachNearObjects(x, y, range, (InstanceZoneObject o, ref bool cancel) =>
            {
                if (o is InstanceUnit)
                {
                    var u = o as InstanceUnit;
                    if (u.Parent.IsAttackable(unit, u, exceptTarget, reason, unit.Info))
                    {
                        if (CMath.includeRoundPoint(x, y, range, u.X, u.Y))
                        {
                            do_action(u);
                        }
                    }
                }
            });
        }


        #endregion


        public static bool BuffIsStealthAbility(XmdsBuffProperties.XmdsBuffAbility ability)
        {
            bool ret = false;

            if (ability == XmdsBuffProperties.XmdsBuffAbility.Stealth)
            {
                ret = true;
            }

            return ret;
        }

        public static int GetTargetFormulaValue(int lv, int[] formula, int skill)
        {
            int ret = 0;

            int v = lv - 1;

            if (v < 0 || formula.Length == 0)
            {
                LogError(string.Format("GetTargetFormulaValue Error:skill id = {0} lv = {1}", skill, lv));
            }
            else if (v >= formula.Length)
            {
                ret = formula[formula.Length - 1];
            }
            else
            {
                ret = formula[v];
            }

            return ret;
        }

        public static void LogError(string text)
        {
            log.Error(text);
        }

		public static void LogWarn(string text)
		{
			log.Warn(text);
		}
		#region 是否为友军判断.

		/*
        /// <summary>
        /// 是否为友军,根据单位PK模式不同结果不同.
        /// </summary>
        /// <param name="src"></param>
        /// <param name="target"></param>
        /// <param name="exceptTarget"></param>
        /// <returns></returns>
        public static bool IsAllies(InstanceUnit src, InstanceUnit target, SkillTemplate.CastTarget exceptTarget)
        {
            bool ret = false;

            var srcVirtual = src.Virtual as XmdsVirtual;
            var targetVirtual = target.Virtual as XmdsVirtual;

            //获得当前PK模式.
            PKInfo.PKMode mode = srcVirtual.GetCurPKMode();

            ret = IsAllies(srcVirtual, targetVirtual, exceptTarget, mode);

            return ret;
        }

        private static bool IsAllies(XmdsVirtual src, XmdsVirtual target, SkillTemplate.CastTarget expectTarget, PKInfo.PKMode mode)
        {
            bool includeSelf = false;
            bool ret = false;
            InstanceUnit u = target.mUnit;
            InstanceUnit temp = null;

            if (expectTarget == SkillTemplate.CastTarget.AlliesIncludeSelf) { includeSelf = true; }



            if (u is XmdsInstanceMonster)
            {
                ret = IsMember(src, temp, mode, includeSelf);
            }
            else if (u is XmdsInstancePlayer)
            {
                ret = IsMember(src, temp, mode, includeSelf);
            }
            else if (u is XmdsInstanceSummonUnit)
            {
                temp = (u as XmdsInstanceSummonUnit).SummonerUnit;

                //召唤物的主人是自己.
                ret = IsMember(src, temp, mode, includeSelf);
            }
            else if (u is InstancePet)
            {
                temp = (u as InstancePet).Master;

                ret = IsMember(src, temp, mode, includeSelf);
            }

            return ret;
        }

        private static bool IsMember(XmdsVirtual src, InstanceUnit target, PKInfo.PKMode mode, bool includeSelf)
        {
            bool ret = false;
            XmdsVirtual zv = null;
            if (src.mUnit == target)
            {
                if (includeSelf) { return true; }
                else { return false; }
            }



            switch (mode)
            {
                case PKInfo.PKMode.Peace://和平模式使用默认出生的force.
                    ret = src.mUnit.Force == src.mUnit.Force ? true : false;
                    break;
                case PKInfo.PKMode.Camp://阵营模式使用Camp.
                    zv = (target.Virtual) as XmdsVirtual;
                    ret = src.IsCampMember(zv.GetCampID());
                    //非同势力时,还需判断是否为队友.
                    if (ret == false && target is XmdsInstancePlayer)
                    {
                        ret = src.IsTeamMember((target as XmdsInstancePlayer).PlayerUUID);
                    }
                    break;
                case PKInfo.PKMode.Guild:
                    ret = src.IsGuildMember((target as XmdsInstancePlayer).PlayerUUID);
                    //非公会成员时还需判断单位是否为为队友.
                    if (ret == false)
                    {
                        ret = src.IsTeamMember((target as XmdsInstancePlayer).PlayerUUID);
                    }
                    break;
                case PKInfo.PKMode.Justice:
                    zv = (target.Virtual) as XmdsVirtual;
                    //非红名玩家才算友军.
                    ret = zv.GetCurPKLevel() == PKLevel.White ? true : false;
                    //非红名时还需判断单位是否为为队友.
                    if (ret == false)
                    {
                        ret = src.IsTeamMember((target as XmdsInstancePlayer).PlayerUUID);
                    }
                    break;
                case PKInfo.PKMode.Server:
                    zv = (target.Virtual) as XmdsVirtual;
                    if (zv != null) { ret = src.IsServerMember(zv.GetServerID()); }
                    //非友军时还需判断单位是否为为队友.
                    if (ret == false)
                    {
                        ret = src.IsTeamMember((target as XmdsInstancePlayer).PlayerUUID);
                    }
                    break;
                case PKInfo.PKMode.Team:
                case PKInfo.PKMode.All:
                    ret = src.IsTeamMember((target as XmdsInstancePlayer).PlayerUUID);
                    break;
            }


            return ret;
        }
        */

		#endregion
	}
}