using System;

using Solar.Zone.Handlers;

namespace Solar.Zone.Game
{
    public class AttackSequence__
    {
        public enum AnimationState
        {
            Starting,
            Running,
            Ended
        }
        public struct Attack
        {
            public ushort Damage;
            public bool Crit;
            public ushort MoveTime;
            public ushort Skill;

            public Attack(ushort dmg, bool crit, ushort movetime, ushort skill = 0)
            {
                Damage = dmg;
                Crit = crit;
                MoveTime = movetime;
                Skill = skill;
            }
        }

        private static byte _counter = 0;
        public static byte Counter { get { return _counter++; } }

        public AnimationState State { get; set; }
        private MapObject From;
        private MapObject To; // Could be a player too (PvP or EvP)
        private ushort _ToID;
        private DateTime _nextSequence;

        private ushort attackSpeed;
        private byte stance = 0;
        private ushort skillid = 0xFFFF;
        private bool IsSkill { get { return skillid == 0xFFFF; } }

        public AttackSequence__(MapObject from, MapObject to, ushort skill = 0xFFFF, ushort attackspeed = 1400)
        {
            From = from;
            To = to;
            _ToID = to.MapObjectID;
            State = AnimationState.Running;
            _nextSequence = Program.CurrentTime;
            attackSpeed = attackspeed;
            skillid = skill;
        }

        private void SetNewSequenceTime(ushort msecs)
        {
            _nextSequence = Program.CurrentTime.AddMilliseconds(msecs);
        }

        private uint GetHPLeft()
        {
            if (To == null || To.IsDead)
            {
                return 0;
            }
            else
            {
                return To.HP;
            }
        }

        private void Handle()
        {
            if (To != null)
            {
                ushort seed = (ushort)Program.Randomizer.Next(0, 100); //we use one seed & base damage on it

                ushort Damage = (ushort)Program.Randomizer.Next(0, seed);
                bool Crit = seed >= 80;
                stance = (byte)(Program.Randomizer.Next(0, 3));
                To.Damage(From, Damage);
                Handler9.SendAttackAnimation(From, _ToID, attackSpeed, stance);
                Handler9.SendAttackDamage(From, _ToID, Damage, Crit, GetHPLeft(), To.UpdateCounter);

                if (To.IsDead)
                {
                    if (To is Mob && From is ZoneCharacter)
                    {
                        uint exp = (To as Mob).InfoServer.MonEXP;
                        (From as ZoneCharacter).GiveEXP(exp, _ToID);
                    }
                    Handler9.SendDieAnimation(From, _ToID);
                    State = AnimationState.Ended;
                    To = null;
                }
                else
                {
                    SetNewSequenceTime(attackSpeed);
                }
            }
        }

        public void Update(DateTime time)
        {
            if ((To != null && To.IsDead) || (From != null && From.IsDead))
            {
                State = AnimationState.Ended;
            }

            if (State == AnimationState.Ended || _nextSequence > time) return;

            if (State == AnimationState.Running)
            {
                Handle();
            }
        }
        
    }
}
