using CommonAI.Data;
using CommonAI.Zone.Formula;
using CommonAI.Zone.Helper;
using CommonAI.ZoneClient;
using CommonAI.ZoneServer.JSGModule;
using CommonLang.Property;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace CommonAI.Zone.Instance
{
	partial class InstanceUnit
	{
		//-----------------------------------------------------------------------------------------------------------

		#region _sync_fields_

		protected readonly SyncUnitInfo mSyncInfo;
		private UnitFieldChangedEvent mSyncFields;
		private int m_dummy_0, m_dummy_1, m_dummy_2, m_dummy_3, m_dummy_4, m_dummy_5, m_dummy_6;

		//是否触发过破碎效果
		private bool isTriggerBroken = false;

		public void SetMaxHP(int value, bool auto_update_hp = false)
		{
			if (__mCurrentHP.SetMax(value, auto_update_hp))
			{
				syncFields(UnitFieldChangedEvent.MASK_HP | UnitFieldChangedEvent.MASK_MAX_HP);
			}
		}

		[DescAttribute("最大血量")]
		public int MaxHP
		{
			get { return __mCurrentHP.Max; }
			set
			{
				if (__mCurrentHP.SetMax(value, true))
				{
					syncFields(UnitFieldChangedEvent.MASK_HP | UnitFieldChangedEvent.MASK_MAX_HP);
				}
			}
		}
		[DescAttribute("最大能量")]
		public int MaxMP
		{
			get { return __mCurrentMP.Max; }
			set
			{
				if (__mCurrentMP.SetMax(value, true))
				{
					syncFields(UnitFieldChangedEvent.MASK_MP | UnitFieldChangedEvent.MASK_MAX_MP);
				}
			}
		}

		[DescAttribute("当前血量")]
		public int CurrentHP
		{
			get { return __mCurrentHP.Value; }
			set
			{
				if (!IsDead() && __mCurrentHP.SetValue(value))
				{
					syncFields(UnitFieldChangedEvent.MASK_HP);
				}
			}
		}
		[DescAttribute("当前能量")]
		public int CurrentMP
		{
			get { return __mCurrentMP.Value; }
			set
			{
				if (!IsDead() && __mCurrentMP.SetValue(value))
				{
					syncFields(UnitFieldChangedEvent.MASK_MP);
				}
			}
		}

		[DescAttribute("当前血量百分比")]
		public float CurrentHP_Pct { get { return __mCurrentHP.Value * 100f / __mCurrentHP.Max; } }
		[DescAttribute("当前能量百分比")]
		public float CurrentMP_Pct { get { return __mCurrentMP.Value * 100f / __mCurrentMP.Max; } }

		[DescAttribute("当前金币")]
		public int CurrentMoney
		{
			get { return mMoney; }
			set
			{
				if (mMoney != value)
				{
					int add = value - mMoney;
					mMoney = value;
					syncFields(UnitFieldChangedEvent.MASK_MONEY);
					Parent.cb_unitGotMoneyCallBack(this, add);
				}
			}
		}
		[DescAttribute("当前等级")]
		public int Level
		{
			get { return mLevel; }
			set
			{
				if (mLevel != value)
				{
					mLevel = value;
					syncFields(UnitFieldChangedEvent.MASK_LEVEL);
				}
			}
		}

		[DescAttribute("单位职业")]
		public int UnitPro()
		{
			return (int)this.Virtual.GetUnitPro();
		}

		[DescAttribute("性别0-男1-女")]
		public int UnitSex()
		{
			return (int)this.Virtual.GetUnitSex();
		}

		[DescAttribute("玩家职业")]
		public int PlayerPro()
		{
			if (this.IsPlayer)
			{
				return (int)this.Virtual.GetUnitPro();
			}

			return 0;
		}

		private void DoAddHP(int hp)
		{
			if (!IsDead())
			{

				if (__mCurrentHP.Add(hp))
				{
					syncFields(UnitFieldChangedEvent.MASK_HP);

					// 触发破碎效果
					if (this.Info.HitBreakPrecent > 0 && !this.isTriggerBroken)
					{
						int precent = (int)((double)this.CurrentHP / this.MaxHP * 100);
						if (precent <= this.Info.HitBreakPrecent)
						{
							//Console.WriteLine("触发破碎");
							this.isTriggerBroken = true;
							UnitHitBreak hitBreak = new UnitHitBreak(this.ID);
							this.Parent.queueObjectEvent(this, hitBreak);
						}
					}
				}
			}
		}

		private void DoAddMP(int mp, bool force = false)
		{
			if (IsDead() || (mp < 0 && !this.Virtual.IsCanReduceMP(force)))
			{
				return;
			}

			if (__mCurrentMP.Add(mp))
			{
				syncFields(UnitFieldChangedEvent.MASK_MP);

				//进入破定状态
				if (__mCurrentMP.Value == 0 && this.CurrentActionStatus != UnitActionStatus.BreakShield)
				{
					this.changeState(new StateBreakShield(this), true);
				}
				//System.Console.WriteLine("更新定力值:" + this.Info.Name + ", " + __mCurrentMP.Value);
			}
		}

		public void AddSP(int st)
		{
			//    if (!IsDead)
			//    {
			//        if (__mCurrentSP.Add(st))
			//        {
			//            syncFields(UnitFieldChangedEvent.MASK_SP);
			//        }
			//    }
		}


		public int AddHP(int hp, InstanceUnit sender, bool sendHit = true, AttackSource source = null)
		{
			int finalHP = ReduceHP(-hp, sender, sendHit);

			//排除怪物回血
#if JSG_DMG_LOG
			int atkPropID = (source == null || source.Attack == null || source.Attack.Properties == null) ? 0 : source.Attack.Properties.GetAttackID();
			if (atkPropID != 9999901 && (finalHP < -100000000 || finalHP > 100000000) && !(this.IsMonster && hp == this.MaxHP))
			{
				string stackInfo = new StackTrace().ToString();
				log.Error("伤害异常: " + finalHP + ", ID" + this.Info.ID + ", " + (sender == null ? "-1" : sender.PlayerUUID)
					+ JSGModule.GetAttackSourceDes(source) + ", " + stackInfo);
			}
#endif
			return finalHP;
		}

		public void AddHP_Pct(float percent, InstanceUnit sender)
		{
			AddHP((int)(percent / 100f * MaxHP), sender);
		}

		/// <summary>
		/// 直接设置移动速度
		/// </summary>
		/// <param name="speed"></param>
		public void SetMoveSpeed(float speed)
		{
			if (speed < 0)
			{
				speed = 0;
			}
			if (speed != __mCurrentMoveSpeedSEC)
			{
				__mCurrentMoveSpeedSEC = speed;
				syncFields(UnitFieldChangedEvent.MASK_SPEED);
			}
		}

		/// <summary>
		/// 直接设置攻速
		/// </summary>
		/// <param name="speed"></param>
		public void SetAttackSpeed(int speed)
		{
			if (speed <= 0)
			{
				speed = GlobalData.DEFAULT_ATTACK_SPEED;
			}
			if (speed != __mCurrentAttackSpeed)
			{
				__mCurrentAttackSpeed = speed;
			}
		}

		public int GetAttackSpeed()
		{
			return this.__mCurrentAttackSpeed;
		}

		/// <summary>
		/// 直接设置当前技能cd减少
		/// </summary>
		/// <param name="value"></param>
		public void SetSkillCdReduce(float value)
		{
			if (value < 0)
			{
				value = 0;
			}
			if (value != __mCurrentSkillCdReduce)
			{
				__mCurrentSkillCdReduce = value;
				syncFields(UnitFieldChangedEvent.MASK_SKILL_CD_ACC);
			}
		}

		/// <summary>
		/// 直接设置受到控制效果的持续时间减少
		/// </summary>
		/// <param name="value"></param>
		public void SetControledTimeReduce(float value)
		{
			if (value < 0)
			{
				value = 0;
			}
			if (value != __mCurrentControledTimeReduce)
			{
				__mCurrentControledTimeReduce = value;
				syncFields(UnitFieldChangedEvent.MASK_CONTROLED_ACC);
			}
		}


		public void SetControledTimeAdd(float value)
		{
			if (value < 0)
			{
				value = 0;
			}
			if (value != __mControledTimeAdd)
			{
				__mControledTimeAdd = value;
				syncFields(UnitFieldChangedEvent.MASK_CONTROLED_ACC);
			}
		}

		/// <summary>
		/// 设置所有技能动作速度加成
		/// </summary>
		/// <param name="rate"></param>
		public void SetSkillActionSpeedRate(float rate)
		{
			if (rate < 0)
			{
				rate = 0;
			}
			if (rate != __mSkillActionSpeedRate)
			{
				__mSkillActionSpeedRate = rate;
			}
		}

		/** 是否满血 */
		public bool IsFullHP()
		{
			return this.CurrentHP == this.MaxHP;
		}

		/// <summary>
		/// 设置当前快速施法速度(基准0)(1是1倍速)
		/// </summary>
		/// <param name="fcr"></param>
		public void SetFastCastRate(float fcr)
		{
			if (mFastCastRate != fcr)
			{
				mFastCastRate = fcr;
				syncFields(UnitFieldChangedEvent.MASK_FCR);
			}
		}
		public int Dummy_0
		{
			get { return m_dummy_0; }
			set
			{
				if (m_dummy_0 != value)
				{
					m_dummy_0 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_0);
				}
			}
		}
		public int Dummy_1
		{
			get { return m_dummy_1; }
			set
			{
				if (m_dummy_1 != value)
				{
					m_dummy_1 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_1);
				}
			}
		}
		public int Dummy_2
		{
			get { return m_dummy_2; }
			set
			{
				if (m_dummy_2 != value)
				{
					m_dummy_2 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_2);
				}
			}
		}
		public int Dummy_3
		{
			get { return m_dummy_3; }
			set
			{
				if (m_dummy_3 != value)
				{
					m_dummy_3 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_3);
				}
			}
		}
		public int Dummy_4
		{
			get { return m_dummy_4; }
			set
			{
				if (m_dummy_4 != value)
				{
					m_dummy_4 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_4);
				}
			}
		}
		public int Dummy_5
		{
			get { return m_dummy_5; }
			set
			{
				if (m_dummy_5 != value)
				{
					m_dummy_5 = value;
					syncFields(UnitFieldChangedEvent.MASK_DUMMY_5);
				}
			}
		}

		public void syncFields(uint mask)
		{
			if (mSyncFields == null)
			{
				mSyncFields = new UnitFieldChangedEvent();
			}
			mSyncFields.mask |= mask;
		}
		private void updateSyncFields()
		{
			if (mSyncFields != null)
			{
				GenSyncFields(mSyncFields);
				queueEvent(mSyncFields);
				mSyncFields = null;
			}
		}
		public void GenSyncFields(UnitFieldChangedEvent sync)
		{
			sync.currentHP = __mCurrentHP.Value;
			sync.currentMP = __mCurrentMP.Value;
			sync.maxHP = __mCurrentHP.Max;
			sync.maxMP = __mCurrentMP.Max;
			sync.maxSP = 0;
			sync.currentSP = 0;
			sync.currentSpeed = __mCurrentMoveSpeedSEC;
			sync.currentFCR = mFastCastRate;
			sync.currentMoney = mMoney;
			sync.level = mLevel;

			sync.dummy_0 = m_dummy_0;
			sync.dummy_1 = m_dummy_1;
			sync.dummy_2 = m_dummy_2;
			sync.dummy_3 = m_dummy_3;
			sync.dummy_4 = m_dummy_4;
			sync.dummy_5 = m_dummy_5;
		}
		public override SyncObjectInfo GenSyncInfo(bool net)
		{
			return GenSyncUnitInfo(net);
		}
		public SyncUnitInfo GenSyncUnitInfo(bool net = false)
		{
			mSyncInfo.status = (byte)CurrentActionStatus;
			mSyncInfo.sub_status = (byte)CurrentActionSubstate;
			mSyncInfo.sub_flag = mSubStateExt;

			mSyncInfo.Force = mForce;
			mSyncInfo.Level = mLevel;
			mSyncInfo.x = X;
			mSyncInfo.y = Y;
			mSyncInfo.direction = this.Direction;
			if (net)
			{
				mSyncInfo.CurrentBuffStatus = this.GetCurrentBuffStatus();
				mSyncInfo.fields.mask = UnitFieldChangedEvent.MASK_ALL;
				GenSyncFields(mSyncInfo.fields);
			}
			return mSyncInfo;
		}

		/// <summary>
		/// 设置单位显示信息
		/// </summary>
		/// <param name="visible_data"></param>
		public void SetVisibleInfo(IUnitVisibleData visible_data)
		{
			mSyncInfo.VisibleInfo = visible_data;
		}

		public void SetDiaplayerName(String name)
		{
			if (mSyncInfo.VisibleInfo != null)
			{
				mSyncInfo.VisibleInfo.setVisibleName(name);
			}

			this.mSyncInfo.Name = name;
		}

		public override String GetTemplateData()
		{
			return "Unit:" + this.mInfo.ID;
		}

		//设置自动拾取范围
		public virtual void SetAutoPickRange(int value) { }
		#endregion

		//-----------------------------------------------------------------------------------------------------------
		#region script_support

		public string get_name()
		{
			return mName;
		}

		public int get_force()
		{
			return mForce;
		}

		public int get_level()
		{
			return mLevel;
		}

		public bool is_dead()
		{
			return IsDead();
		}

		public bool is_enable()
		{
			return Enable;
		}

		public bool is_paused()
		{
			return IsPaused;
		}

		public bool is_none_block()
		{
			return IsNoneBlock;
		}

		public bool is_none_skill()
		{
			return IsNoneSkill;
		}

		public uint get_id()
		{
			return ID;
		}

		public UnitInfo get_info()
		{
			return mInfo;
		}

		public Random get_random()
		{
			return RandomN;
		}

		public float get_x()
		{
			return X;
		}

		public float get_y()
		{
			return Y;
		}

		public float get_direction()
		{
			return Direction;
		}

		public float set_direction(float d)
		{
			this.faceTo(d);
			return d;
		}

		public string get_unit_tag()
		{
			return UnitTag;
		}

		public string set_unit_tag(string str)
		{
			UnitTag = str;
			return str;
		}

		public int get_max_hp()
		{
			return MaxHP;
		}

		public int set_max_hp(int max)
		{
			MaxHP = max;
			return max;
		}

		public int get_max_mp()
		{
			return MaxMP;
		}

		//public int set_max_mp(int mp)
		//{
		//    MaxMP = mp;
		//    return mp;
		//}

		public int get_current_hp()
		{
			return __mCurrentHP.Value;
		}

		public int set_current_hp(int hp)
		{
			CurrentHP = hp;
			return hp;
		}

		public int get_current_mp()
		{
			return __mCurrentMP.Value;
		}

		//public int set_current_mp(int mp)
		//{
		//    CurrentMP = mp;
		//    return mp;
		//}

		public int set_level(int lv)
		{
			Level = lv;
			return lv;
		}

		//public void add_mp(int mp)
		//{
		//    AddMP(mp);
		//}

		public void add_hp(int hp)
		{
			AddHP(hp, this);
		}

		public void add_sp(int sp)
		{
			AddSP(sp);
		}

		public void add_buff(int buffID)
		{
			AddBuff(buffID);
		}

		public void clear_buff()
		{
			clearBuffs();
		}

		public void use_item(int itemTemplateID)
		{
			ItemTemplate item = Templates.getItem(itemTemplateID);
			if (item != null)
			{
				UseItem(item);
			}
		}

		#endregion
	}
}