using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Misc;
using Server.Spells;
using Server.Items;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;


namespace Server.Mobiles
{
    [CorpseName("a medusa corpse")]
    public class Medusa : BasePeerless, ICarvable
    {
        [Constructable]
        public Medusa() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
        {
            Name = "Medusa";
            Body = 728;

            SetStr(1235, 1391);
            SetDex(128, 139);
            SetInt(537, 664);

            SetHits(150000);

            SetDamage(21, 28);

            SetDamageType(ResistanceType.Physical, 60);
            SetDamageType(ResistanceType.Fire, 20);
            SetDamageType(ResistanceType.Energy, 20);

            SetResistance(ResistanceType.Physical, 55, 65);
            SetResistance(ResistanceType.Fire, 55, 65);
            SetResistance(ResistanceType.Cold, 55, 65);
            SetResistance(ResistanceType.Poison, 80, 90);
            SetResistance(ResistanceType.Energy, 60, 75);

            SetSkill(SkillName.Anatomy, 110.6, 116.1);
            SetSkill(SkillName.Archery, 125.5, 130.0);
            SetSkill(SkillName.EvalInt, 100.0, 114.4);
            SetSkill(SkillName.Magery, 100.0);
            SetSkill(SkillName.Poisoning, 160.0);
            SetSkill(SkillName.Meditation, 118.2, 127.8);
            SetSkill(SkillName.MagicResist, 120.0);
            SetSkill(SkillName.Tactics, 111.9, 134.5);
            SetSkill(SkillName.Wrestling, 119.7, 128.9);

            Fame = 20000;
            Karma = -20000;

            VirtualArmor = 60;

            PackItem(new Arrow(Utility.RandomMinMax(600, 700)));

            IronwoodCompositeBow Bow = new IronwoodCompositeBow();
            Bow.Movable = false;
            AddItem(Bow);

            m_Scales = Utility.Random(5) + 1;
        }

        public override int GetIdleSound() { return 1557; }
        public override int GetAngerSound() { return 1554; }
        public override int GetHurtSound() { return 1556; }
        public override int GetDeathSound() { return 1555; }

        private int m_Scales;

        public void Carve(Mobile from, Item item)
        {
            if (m_Scales > 0 && from.Backpack != null)
            {
                new Blood(0x122D).MoveToWorld(Location, Map);
                from.AddToBackpack(new MedusaDarkScales(Utility.Random(3) + 1));
                from.SendLocalizedMessage(1114098); // You cut away some scales and put them in your backpack.
                this.Combatant = from;
                --m_Scales;
            }
        }

        private DateTime m_GazeDelay;
        public static List<Mobile> AffectedMobiles = new List<Mobile>();

        public override void OnThink()
        {
            base.OnThink();

            if (DateTime.Now > m_GazeDelay)
            {
                Mobile target = Ability.FindRandomTarget(this);
               
                if (target != null)
                {
                    BaseCreature clone = new MedusaClone(target);

                    Effects.SendLocationEffect(target.Location, target.Map, 0x37B9, 10, 5);
                    clone.Frozen = clone.Blessed = true;
                    target.Frozen = target.Hidden = target.Blessed = true;
                    clone.MoveToWorld(target.Location, target.Map);
                    target.SendLocalizedMessage(1112768); // You have been turned to stone!!!
                    new GazeTimer(target, clone).Start();
                    m_GazeDelay = DateTime.Now + TimeSpan.FromSeconds(Utility.RandomMinMax(60, 120));

                    // List is for removing the Blessed status on world load in case of accidental crashing.
                    // Honesitly it's a thousand times better to remove the Blessed state on login for nonstaffers.
                    AffectedMobiles.Add(target);
                }
            }
        }

        public override void GenerateLoot()
        {
            AddLoot(LootPack.UltraRich, 5);
        }

        public override void OnDeath(Container c)
        {
            base.OnDeath(c);

            Mobile mobile = DemonKnight.FindRandomPlayer(this);

            if (Paragon.CheckArtifactChance(mobile, this))
            {
                switch (Utility.Random(4))
                {
                    case 0: DemonKnight.DistributeArtifact(mobile, new Slither()); break;
                    case 1: DemonKnight.DistributeArtifact(mobile, new IronwoodCompositeBow()); break;
                    case 2: DemonKnight.DistributeArtifact(mobile, new MedusaStatue()); break;
                    case 3: DemonKnight.DistributeArtifact(mobile, new MedusaBlood()); break;
                }
            }
        }

        public override WeaponAbility GetWeaponAbility() { return WeaponAbility.MortalStrike; }
        public override bool IgnoreYoungProtection { get { return true; } }
        public override int Scales { get { return (Utility.Random(5) + 1); } }
        public override ScaleType ScaleType { get { return ScaleType.MedusaLight; } }
        public override bool AlwaysMurderer { get { return true; } }
        public override bool GivesSAArtifact { get { return true; } }
        public override bool AutoDispel { get { return true; } }
        public override bool BardImmune { get { return true; } }
        public override bool Unprovokable { get { return true; } }
        public override bool AreaPeaceImmune { get { return true; } }
        public override Poison PoisonImmune { get { return Poison.Lethal; } }
        public override Poison HitPoison { get { return (0.8 >= Utility.RandomDouble() ? Poison.Deadly : Poison.Lethal); } }

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

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0);
            writer.Write((int)m_Scales);
            writer.Write(AffectedMobiles);
        }

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

            for (int i = 0; i < AffectedMobiles.Count; i++)
                if (AffectedMobiles[i] != null)
                    AffectedMobiles[i].Blessed = false;
        }

        public class GazeTimer : Timer
        {
            private Mobile target;
            private Mobile clone;
            private int m_Count;

            public GazeTimer(Mobile m, Mobile mc) : base(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(20))
            {
                target = m;
                clone = mc;
                m_Count = 0;
            }

            protected override void OnTick()
            {
                ++m_Count;

                if (m_Count == 1 && target != null)
                {
                    target.Frozen = target.Hidden = target.Blessed = false;

                    if (Medusa.AffectedMobiles.Contains(target))
                        Medusa.AffectedMobiles.Remove(target);
                }
                else if (m_Count == 2 && clone != null)
                {   
                    clone.SolidHueOverride = -1;
                    clone.Frozen = clone.Blessed = false;

                    foreach (Mobile m in clone.GetMobilesInRange(12))
                    {
                        if (m != null && m.Player)
                        {
                            m.SendLocalizedMessage(1112767); // Medusa releases one of the petrified creatures!!
                            m.Send(new RemoveMobile(clone));
                            m.Send(new MobileIncoming(m, clone));
                        }
                    }
                }
                else
                    Stop();
            }
        }

        /*private Mobile FindRandomMedusaTarget()
        {
            List<Mobile> list = new List<Mobile>();
            int charges;

            foreach (Mobile m in from.GetMobilesInRange(8))
            {
                if (m == null || m == from || !from.InLOS(m) || !CanBeHarmful(m))
                    continue;
                if (AffectedMobiles.Contains(m) || m is MedusaClone)
                    continue;

                charges = -1;

                foreach (Item i in m.Items)
                {
                    if ((!i is IGorgonLens))
                        continue;

                    charges = ((IGorgonLens)i).Charges;

                    if (charges > 0)
                    {
                        --charges.Charges;
                        break;
                    }
                }

                if (charges > -1)
                    list.Add(m);
            }

            if (list.Count == 0)
                return null;
            if (list.Count == 1)
                return list[0];

            return list[Utility.Random(list.Count)];
        }*/

    }
}