using Server.Mobiles;
using Server.Network;
using System;
using System.Collections;
using Server.ContextMenus;
using System.Collections.Generic;

namespace Server.Items
{
    public class CrusadersShield : LevelHeaterShield
    {
        private int m_Bonus = 0;
        private int m_KoBonus = 0;
        private bool m_Activated = false;

        //     		[CommandProperty(AccessLevel.GameMaster)]
        public int Bonus { get { return m_Bonus; } set { m_Bonus = Math.Min(value, 10); InvalidateProperties(); } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int KoBonus { get { return m_KoBonus; } set { m_KoBonus = value; InvalidateProperties(); } }

        public int SpellDmgReduction
        {
            get
            {
                if (m_KoBonus > 19)
                    return m_KoBonus + 2;
                else if (m_KoBonus > 9)
                    return m_KoBonus + 1;
                else
                    return m_KoBonus;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool Activated { get { return m_Activated; } set { m_Activated = value; InvalidateProperties(); } }

        public bool UpgradeTier()
        {
            if (m_Bonus + 1 > 10) //max tier
                return false;

            m_Bonus++;

            this.SkillBonuses.Skill_1_Value += 2.0;
            this.Attributes.WeaponDamage += 2;
            this.Attributes.AttackChance += 2;
            this.Attributes.Luck += 5;
            this.Attributes.ReflectPhysical += 2;
            this.Attributes.SpellDamage += 1;
            this.Attributes.BonusHits += 2;
            this.ArmorAttributes.LowerStatReq = (m_Bonus * 10);

            if (m_Bonus > 4)
            {
                this.SkillBonuses.SetValues(2, SkillName.Magery, 10.0);
                this.Attributes.SpellChanneling = 1;
            }

            this.SkillBonuses.SetValues(1, SkillName.Chivalry, (m_Bonus * 2));

            return true;
        }

        public bool UpgradeKoTier()
        {
            if (m_KoBonus + 1 > 25 || !m_Activated) //max tier
                return false;

            m_KoBonus++;
            return true;
        }

        public static bool FullCrusadersSetPresent(Mobile from)
        {
            if (from.Weapon is CrusadersWarMace && from.FindItemOnLayer(Layer.TwoHanded) is CrusadersShield)
                return true;
            else
                return false;
        }

        public class ActivateEntry : ContextMenuEntry
        {
            private Item m_Item;
            private Mobile m_From;

            public ActivateEntry(Item item, Mobile from) : base(6170, 1)
            {
                m_Item = item;
                m_From = from;
            }

            public override void OnClick()
            {
                if (m_Item is CrusadersShield || m_Item is CrusadersWarMace)
                {
                    if (m_From.Backpack == null)
                        return;

                    Item[] predmety = m_From.Backpack.FindItemsByType(typeof(Predmet));
                    Item predmet = null;

                    if (predmety == null || predmety.Length < 1)
                    {
                        m_From.SendMessage("Nemas u sebe predmet potrebny pro aktivaci");
                        return;
                    }

                    // CrusadersShield
                    if (m_Item is CrusadersShield)
                    {
                        if (((CrusadersShield)m_Item).Activated)
                        {
                            m_From.SendMessage("Stit je jiz aktivovany");
                            return;
                        }

                        foreach (Item p in predmety)
                        {
                            if (p != null && p.Name.Equals("gem of magic absorb", StringComparison.OrdinalIgnoreCase))
                            {
                                predmet = p;
                                break;
                            }
                        }


                        if (predmet != null)
                        {
                            m_Item.BlessedFor = m_From;
                            ((CrusadersShield)m_Item).Activated = true;
                            predmet.Consume();
                        }
                        else
                        {
                            m_From.SendMessage("Nemas u sebe Gem of magic absorb potrebny pro aktivaci");
                            return;
                        }
                    }

                    // CrusadersWarMace
                    if (m_Item is CrusadersWarMace)
                    {
                        if (((CrusadersWarMace)m_Item).Activated)
                        {
                            m_From.SendMessage("Zbran je jiz aktivovana");
                            return;
                        }

                        foreach (Item p in predmety)
                        {
                            if (p != null && p.Name.Equals("elixir of death", StringComparison.OrdinalIgnoreCase))
                            {
                                predmet = p;
                                break;
                            }
                        }


                        if (predmet != null)
                        {
                            m_Item.BlessedFor = m_From;
                            ((CrusadersWarMace)m_Item).Activated = true;
                            predmet.Consume();
                        }
                        else
                        {
                            m_From.SendMessage("Nemas u sebe Elixir of death potrebny pro aktivaci");
                            return;
                        }
                    }

                    m_From.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist);
                    m_From.PlaySound(487);
                    m_From.SendMessage("Predmet byl aktivovan!");
                    predmety = null;
                }
            }
        }

        public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
        {
            if (IsChildOf(from.Backpack) && !m_Activated) // Make sure its in their pack
            {
                list.Add(new ActivateEntry(this, from));
            }

            base.GetContextMenuEntries(from, list);
        }

        #region Effects

        private DateTime m_NextAngel;

        public void SummonAngel(Mobile from)
        {
            if (m_NextAngel > DateTime.Now || GuardianAngel.HasAngel(from))
                return;

            m_NextAngel = DateTime.Now + TimeSpan.FromMinutes(5.0);
            BaseCreature angel = new GuardianAngel();
            angel.Name = (from.RawName + "'s Guardian Angel").ToLower();
            Server.Spells.SpellHelper.Summon(angel, from, 0x2F8, TimeSpan.FromMinutes(1.0), false, false);
            angel.ControlOrder = OrderType.Guard;
            GuardianAngel.AddAngel(from, angel);
        }

        public static void UnsummonAngel(Mobile from)
        {
            if (GuardianAngel.HasAngel(from))
            {
                BaseCreature angel = GuardianAngel.GetAngel(from);

                if (angel == null || angel.Deleted)
                    return;

                //             Effects.SendLocationParticles( EffectItem.Create( angel.Location, angel.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
                // 			   Effects.PlaySound( angel, angel.Map, 0x201 );
                Effects.SendLocationEffect(angel.Location, angel.Map, 0x3728, 13, 1, 0x461, 4);
                angel.Delete();
            }
        }

        private DateTime m_NextBloodbath;
        public DateTime NextBloodbath { get { return m_NextBloodbath; } set { m_NextBloodbath = value; } }

        public static void Bloodbath(Mobile attacker)
        {
            Item item = attacker.FindItemOnLayer(Layer.TwoHanded);

            if (!(item is CrusadersShield))
                return;

            CrusadersShield shield = (CrusadersShield)item;

            if (shield == null || !FullCrusadersSetPresent(attacker) || shield.NextBloodbath > DateTime.Now)
                return;

            shield.NextBloodbath = DateTime.Now + TimeSpan.FromSeconds(10.0);

            ArrayList targets = Utilitky.GetPlayerTargets(attacker, 3);

            for (int i = 0; i < targets.Count; ++i)
            {
                Mobile m = (Mobile)targets[i];

                if (m == null || m.Deleted/* || (m is BaseCreature && ((BaseCreature)m).BleedImmune)*/ )
                    continue;

                m.RevealingAction();
                m.PlaySound(0x133);
                m.FixedParticles(0x377A, 244, 25, 9950, 31, 0, EffectLayer.Waist);
                BleedAttack.BeginBleed(m, attacker);
                attacker.Hits += AOS.Scale(attacker.HitsMax, 10);
            }

            targets = null;
        }

        private DateTime m_NextSpecial;
        public DateTime NextSpecial { get { return m_NextSpecial; } set { m_NextSpecial = value; } }

        public static void BlessedHammer(Mobile attacker, Mobile defender, int damage)
        {
            Item item = attacker.FindItemOnLayer(Layer.TwoHanded);

            if (!(item is CrusadersShield))
                return;

            CrusadersShield shield = (CrusadersShield)item;

            if (shield == null || !FullCrusadersSetPresent(attacker) || shield.NextSpecial > DateTime.Now)
                return;

            ArrayList targets = Utilitky.GetPlayerTargets(defender, 5);
            int count = targets.Count;

            if (count < 2)
                return;

            shield.NextSpecial = DateTime.Now + TimeSpan.FromSeconds(20.0);
            attacker.PublicOverheadMessage(MessageType.Regular, 0x3B2, true, "Blessed Hammer");
            AOS.Damage(defender, attacker, damage * 2, true, 0, 0, 0, 0, 100);

            for (int i = 0; i < Math.Min(count, 10); ++i)
            {
                Mobile m = (Mobile)targets[i];

                if (m == null || m.Deleted || m == defender)
                    continue;

                Timer.DelayCall(TimeSpan.FromSeconds(((double)i) + 1.5), new TimerStateCallback(TriggerBlessedHammer), new object[] { attacker, m, AOS.Scale(damage, Math.Max(220 - (i * 10), 200)) });
            }
        }

        private static void TriggerBlessedHammer(object state)
        {
            object[] args = (object[])state;
            Mobile attacker = (Mobile)args[0];
            Mobile defender = (Mobile)args[1];
            int damage = (int)args[2];

            if (defender == null || defender.Deleted || !defender.Alive || attacker == null || attacker.Deleted || !attacker.Alive)
                return;

            // 			attacker.DoHarmful( defender );
            defender.RevealingAction();
            AOS.Damage(defender, attacker, damage * 2, true, 0, 0, 0, 0, 100);
            defender.PlaySound(567);
            defender.FixedParticles(0, 1, 0, 9946, EffectLayer.Head);
            BaseWeapon.PlayHurtAnimation(defender);
            attacker.Hits += AOS.Scale(attacker.HitsMax, 20);

            Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(defender.X, defender.Y, defender.Z + 50), defender.Map), new Entity(Serial.Zero, new Point3D(defender.X, defender.Y, defender.Z + 20), defender.Map), 5126, 1, 0, false, false, 0, 3, 9501, 1, 0, EffectLayer.Head, 0x100);
            ((BaseCreature)defender).Pacify(attacker, DateTime.Now + TimeSpan.FromSeconds(5.0));
        }

        public static string PropsString
        {
            get { return "<basefont color=#DA70D6>Guardian Angel, Bloodbath ability\nSlayer Opposition Ignore\nBlessed Hammer, Silence Immunity"; }
        }
        #endregion

        public override int ArtifactRarity { get { return 70; } }
        public override int InitMinHits { get { return 125; } }
        public override int InitMaxHits { get { return 125; } }

        public override int BasePhysicalResistance { get { return 15; } }

        [Constructable]
        public CrusadersShield()
        {
            this.Weight = 5;
            this.Name = "<bodytext=#DA70D6><center>Crusader's Shield";
            this.ItemID = 0x2B01;
            this.Hue = 2638;
            this.SkillBonuses.SetValues(0, SkillName.Parry, 10.0);
            this.Attributes.LowerManaCost = 10;
            this.Attributes.BonusDex = 10;
            this.Attributes.Luck = 200;
            this.Attributes.ReflectPhysical = 25;
            this.Attributes.DefendChance = 35;
            this.Attributes.CastRecovery = 4;
            this.Attributes.BonusMana = 10;
            this.Attributes.BonusHits = 10;

            this.ArmorAttributes.SelfRepair = 10;
            this.ArmorAttributes.LowerStatReq = 10;
            this.ArmorAttributes.MageArmor = 1;
        }

        public CrusadersShield(Serial serial) : base(serial)
        {
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);

            if (this.Hue == 2638)
            {
                list.Add(1072378);
                list.Add(PropsString + (!m_Activated ? "<basefont color=White>" : "\nMagic absorb:<basefont color=White> +" + (m_Activated ? SpellDmgReduction.ToString() + "%" : "XXX")));
            }
        }

        public override void AddNameProperties(ObjectPropertyList list)
        {
            base.AddNameProperties(list);

            // 			if ( m_Bonus > 0 )
            list.Add(1072819, "<basefont color=#9999FF>" + String.Format("{0} [{1}]", m_Bonus, m_Activated ? m_KoBonus.ToString() : "XXX") + "<basefont color=White>");//Current Tier: ~1_TIER~

            list.Add(1072376, "2");

            if (this.Parent is Mobile)
            {
                if (this.Hue == 2628)
                {
                    list.Add(1072377);
                    list.Add(PropsString + (!m_Activated ? "<basefont color=White>" : "\nMagic absorb:<basefont color=White> +" + (m_Activated ? SpellDmgReduction.ToString() + "%" : "XXX")));
                }
            }
        }

        public override bool OnEquip(Mobile from)
        {

            BaseWeapon mace = from.FindItemOnLayer(Layer.OneHanded) as BaseWeapon;

            if (mace != null && mace is CrusadersWarMace)
            {
                Effects.PlaySound(from.Location, from.Map, 503);
                from.FixedParticles(0x376A, 9, 32, 5030, EffectLayer.Waist);

                Hue = 2628;
                mace.Hue = 2628;
                mace.InvalidateProperties();
            }

            this.InvalidateProperties();

            return base.OnEquip(from);
        }

        public override void OnRemoved(object parent)
        {
            if (parent is Mobile)
            {
                Mobile m = (Mobile)parent;
                Hue = 2638;
                m.FixedParticles(0x3779, 10, 15, 5009, EffectLayer.Waist);
                Effects.PlaySound(m.Location, m.Map, 0x1E6);

                if (m.FindItemOnLayer(Layer.OneHanded) is CrusadersWarMace)
                {
                    BaseWeapon mace = m.FindItemOnLayer(Layer.OneHanded) as BaseWeapon;
                    mace.Hue = 2638;
                    mace.InvalidateProperties();
                }

                UnsummonAngel(m);
                this.InvalidateProperties();
            }

            base.OnRemoved(parent);
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write(2);
            // version 2
            writer.Write(m_KoBonus);
            writer.Write(m_Activated);
            // version 1
            writer.Write(m_Bonus);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            switch (version)
            {
                case 2:
                    {
                        m_KoBonus = reader.ReadInt();
                        m_Activated = reader.ReadBool();
                        goto case 1;
                    }
                case 1:
                    {
                        m_Bonus = reader.ReadInt();
                        break;
                    }
            }
        }
    }
}
