using System;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Engines.PartySystem;
using Server.Gumps;
using Server.Network;

namespace Server.Items
{
    public class JewelryTestChest : LockableContainer
    {
        private static readonly Type[] m_Artifacts = new Type[]
        {
            typeof(CandelabraOfSouls), typeof(GoldBricks), typeof(PhillipsWoodenSteed),
            typeof(ArcticDeathDealer), typeof(BlazeOfDeath), typeof(BurglarsBandana),
            typeof(CavortingClub), typeof(DreadPirateHat),
            typeof(EnchantedTitanLegBone), typeof(GwennosHarp), typeof(IolosLute),
            typeof(LunaLance), typeof(NightsKiss), typeof(NoxRangersHeavyCrossbow),
            typeof(PolarBearMask), typeof(VioletCourage), typeof(HeartOfTheLion),
            typeof(ColdBlood), typeof(AlchemistsBauble), typeof(CaptainQuacklebushsCutlass),
			typeof(ForgedPardon), typeof(ShieldOfInvulnerability), typeof(AncientShipModelOfTheHMSCape),
			typeof(AdmiralHeartyRum)
        };
        private int m_Level;
        private DateTime m_DeleteTime;
        private Timer m_Timer;
        private Mobile m_Owner;
        private bool m_Temporary;
        private List<Mobile> m_Guardians;
        private List<Item> m_Lifted = new List<Item>();
        [Constructable]
        public JewelryTestChest(int level)
            : this(null, level, false)
        {
        }

        public JewelryTestChest(Mobile owner, int level, bool temporary)
            : base(0xE40)
        {
            this.m_Owner = owner;
            this.m_Level = level;
            this.m_DeleteTime = DateTime.UtcNow + TimeSpan.FromHours(3.0);

            this.m_Temporary = temporary;
            this.m_Guardians = new List<Mobile>();

            this.m_Timer = new DeleteTimer(this, this.m_DeleteTime);
            this.m_Timer.Start();

            Fill(this, level);
        }

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

        public static Type[] Artifacts
        {
            get
            {
                return m_Artifacts;
            }
        }
        public override int LabelNumber
        {
            get
            {
                return 3000541;
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public int Level
        {
            get
            {
                return this.m_Level;
            }
            set
            {
                this.m_Level = value;
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Owner
        {
            get
            {
                return this.m_Owner;
            }
            set
            {
                this.m_Owner = value;
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public DateTime DeleteTime
        {
            get
            {
                return this.m_DeleteTime;
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public bool Temporary
        {
            get
            {
                return this.m_Temporary;
            }
            set
            {
                this.m_Temporary = value;
            }
        }
        public List<Mobile> Guardians
        {
            get
            {
                return this.m_Guardians;
            }
        }
        public override bool IsDecoContainer
        {
            get
            {
                return false;
            }
        }
        public static void Fill(LockableContainer cont, int level)
        {
            cont.Movable = false;
            cont.Locked = true;
            int numberItems;
			
            if (level == 0)
            {
                cont.LockLevel = 0; // Can't be unlocked

                cont.DropItem(new Gold(Utility.RandomMinMax(50, 100)));

                if (Utility.RandomDouble() < 0.75)
                    cont.DropItem(new TreasureMap(0, Map.Trammel));
            }
            else
            {
                //cont.TrapType = TrapType.ExplosionTrap;
                //cont.TrapPower = level * 25;
                //cont.TrapLevel = level;

                //switch ( level )
                //{
                //    case 1:
                //        cont.RequiredSkill = 36;
                //        break;
                //    case 2:
                //        cont.RequiredSkill = 76;
                //        break;
                //    case 3:
                //        cont.RequiredSkill = 84;
                //        break;
                //    case 4:
                //        cont.RequiredSkill = 92;
                //        break;
                //    case 5:
                //        cont.RequiredSkill = 100;
                //        break;
                //    case 6:
                //        cont.RequiredSkill = 100;
                //        break;
                //}

                //cont.LockLevel = cont.RequiredSkill - 10;
                //cont.MaxLockLevel = cont.RequiredSkill + 40;
				
                //Publish 67 gold change
                //if ( Core.SA )
                //	cont.DropItem( new Gold( level * 5000 ) );
                //else					
                cont.DropItem(new Gold(level * 1000));

                //for (int i = 0; i < level * 5; ++i)
                //    cont.DropItem(Loot.RandomScroll(0, 63, SpellbookType.Regular));

                if (Core.SE)
                {
                    switch ( level )
                    {
                        case 1:
                            numberItems = 5;
                            break;
                        case 2:
                            numberItems = 10;
                            break;
                        case 3:
                            numberItems = 15;
                            break;
                        case 4:
                            numberItems = 38;
                            break;
                        case 5:
                            numberItems = 50;
                            break;
                        case 6:
                            numberItems = 60;
                            break;
                        default:
                            numberItems = 0;
                            break;
                    }
                }
                else
                    numberItems = level * 6;

                numberItems = 15;
				
                for (int i = 0; i < numberItems; ++i)
                {
                    Item item;

                    item = Loot.RandomJewelry();
                    item.Unidentified = false;
                    item = LootPackEntry.Mutate(null, 0, item, level + 2);
                    
                    cont.DropItem(LootPackEntry.Mutate(null, 0, item, level));
                }
            }

            int reagents;
            if (level == 0)
                reagents = 12;
            else
                reagents = level * 3;
            reagents = 0;
            for (int i = 0; i < reagents; i++)
            {
                Item item = Loot.RandomPossibleReagent();
                item.Amount = Utility.RandomMinMax(40, 60);
                cont.DropItem(item);
            }

            int gems;
            if (level == 0)
                gems = 2;
            else
                gems = level * 3;
            gems = 0;
            for (int i = 0; i < gems; i++)
            {
                Item item = Loot.RandomGem();
                cont.DropItem(item);
            }

            if (level >= 6 && Core.AOS)
                cont.DropItem((Item)Activator.CreateInstance(m_Artifacts[Utility.Random(m_Artifacts.Length)]));
        }

        public override bool CheckLocked(Mobile from)
        {
            if (!this.Locked)
                return false;

            if (this.Level == 0 && from.AccessLevel < AccessLevel.GameMaster)
            {
                foreach (Mobile m in this.Guardians)
                {
                    if (m.Alive)
                    {
                        from.SendLocalizedMessage(1046448); // You must first kill the guardians before you may open this chest.
                        return true;
                    }
                }

                this.LockPick(from);
                return false;
            }
            else
            {
                return base.CheckLocked(from);
            }
        }

        public override bool CheckItemUse(Mobile from, Item item)
        {
            return this.CheckLoot(from, item != this) && base.CheckItemUse(from, item);
        }

        public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
        {
            return this.CheckLoot(from, true) && base.CheckLift(from, item, ref reject);
        }

        public override void OnItemLifted(Mobile from, Item item)
        {
            //bool notYetLifted = !this.m_Lifted.Contains(item);

            //from.RevealingAction();

            //if (notYetLifted)
            //{
            //    this.m_Lifted.Add(item);

            //    if (0.1 >= Utility.RandomDouble()) // 10% chance to spawn a new monster
            //        TreasureMap.Spawn(this.m_Level, this.GetWorldLocation(), this.Map, from, false);
            //}

            base.OnItemLifted(from, item);
        }

        public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
        {
            if (m.AccessLevel < AccessLevel.GameMaster)
            {
                m.SendLocalizedMessage(1048122, "", 0x8A5); // The chest refuses to be filled with treasure again.
                return false;
            }

            return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight);
        }

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

            writer.Write((int)2); // version

            writer.Write(this.m_Guardians, true);
            writer.Write((bool)this.m_Temporary);

            writer.Write(this.m_Owner);

            writer.Write((int)this.m_Level);
            writer.WriteDeltaTime(this.m_DeleteTime);
            writer.Write(this.m_Lifted, true);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch ( version )
            {
                case 2:
                    {
                        this.m_Guardians = reader.ReadStrongMobileList();
                        this.m_Temporary = reader.ReadBool();

                        goto case 1;
                    }
                case 1:
                    {
                        this.m_Owner = reader.ReadMobile();

                        goto case 0;
                    }
                case 0:
                    {
                        this.m_Level = reader.ReadInt();
                        this.m_DeleteTime = reader.ReadDeltaTime();
                        this.m_Lifted = reader.ReadStrongItemList();

                        if (version < 2)
                            this.m_Guardians = new List<Mobile>();

                        break;
                    }
            }

            if (!this.m_Temporary)
            {
                this.m_Timer = new DeleteTimer(this, this.m_DeleteTime);
                this.m_Timer.Start();
            }
            else
            {
                this.Delete();
            }
        }

        public override void OnAfterDelete()
        {
            if (this.m_Timer != null)
                this.m_Timer.Stop();

            this.m_Timer = null;

            base.OnAfterDelete();
        }

        public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
        {
            base.GetContextMenuEntries(from, list);

            if (from.Alive)
                list.Add(new RemoveEntry(from, this));
        }

        public void BeginRemove(Mobile from)
        {
            if (!from.Alive)
                return;

            from.CloseGump(typeof(RemoveGump));
            from.SendGump(new RemoveGump(from, this));
        }

        public void EndRemove(Mobile from)
        {
            if (this.Deleted || from != this.m_Owner || !from.InRange(this.GetWorldLocation(), 3))
                return;

            from.SendLocalizedMessage(1048124, "", 0x8A5); // The old, rusted chest crumbles when you hit it.
            this.Delete();
        }

        private static void GetRandomAOSStats(out int attributeCount, out int min, out int max)
        {
            int rnd = Utility.Random(15);
			
            if (Core.SE)
            {
                if (rnd < 1)
                {
                    attributeCount = Utility.RandomMinMax(3, 5);
                    min = 50;
                    max = 100;
                }
                else if (rnd < 3)
                {
                    attributeCount = Utility.RandomMinMax(2, 5);
                    min = 40;
                    max = 80;
                }
                else if (rnd < 6)
                {
                    attributeCount = Utility.RandomMinMax(2, 4);
                    min = 30;
                    max = 60;
                }
                else if (rnd < 10)
                {
                    attributeCount = Utility.RandomMinMax(1, 3);
                    min = 20;
                    max = 40;
                }
                else
                {
                    attributeCount = 1;
                    min = 10;
                    max = 20;
                }
            }
            else
            {
                if (rnd < 1)
                {
                    attributeCount = Utility.RandomMinMax(2, 5);
                    min = 20;
                    max = 70;
                }
                else if (rnd < 3)
                {
                    attributeCount = Utility.RandomMinMax(2, 4);
                    min = 20;
                    max = 50;
                }
                else if (rnd < 6)
                {
                    attributeCount = Utility.RandomMinMax(2, 3);
                    min = 20;
                    max = 40;
                }
                else if (rnd < 10)
                {
                    attributeCount = Utility.RandomMinMax(1, 2);
                    min = 10;
                    max = 30;
                }
                else
                {
                    attributeCount = 1;
                    min = 10;
                    max = 20;
                }
            }
        }

        private bool CheckLoot(Mobile m, bool criminalAction)
        {
            if (this.m_Temporary)
                return false;

            if (m.AccessLevel >= AccessLevel.GameMaster || this.m_Owner == null || m == this.m_Owner)
                return true;

            Party p = Party.Get(this.m_Owner);

            if (p != null && p.Contains(m))
                return true;

            Map map = this.Map;

            //if (map != null && (map.Rules & MapRules.HarmfulRestrictions) == 0)
            //{
            //    if (criminalAction)
            //        m.CriminalAction(true);
            //    else
            //        m.SendLocalizedMessage(1010630); // Taking someone else's treasure is a criminal offense!

            //    return true;
            //}

            m.SendLocalizedMessage(1010631); // You did not discover this chest!
            return false;
        }

        private class RemoveGump : Gump
        {
            private readonly Mobile m_From;
            private readonly JewelryTestChest m_Chest;
            public RemoveGump(Mobile from, JewelryTestChest chest)
                : base(15, 15)
            {
                this.m_From = from;
                this.m_Chest = chest;

                this.Closable = false;
                this.Disposable = false;

                this.AddPage(0);

                this.AddBackground(30, 0, 240, 240, 2620);

                this.AddHtmlLocalized(45, 15, 200, 80, 1048125, 0xFFFFFF, false, false); // When this treasure chest is removed, any items still inside of it will be lost.
                this.AddHtmlLocalized(45, 95, 200, 60, 1048126, 0xFFFFFF, false, false); // Are you certain you're ready to remove this chest?

                this.AddButton(40, 153, 4005, 4007, 1, GumpButtonType.Reply, 0);
                this.AddHtmlLocalized(75, 155, 180, 40, 1048127, 0xFFFFFF, false, false); // Remove the Treasure Chest

                this.AddButton(40, 195, 4005, 4007, 2, GumpButtonType.Reply, 0);
                this.AddHtmlLocalized(75, 197, 180, 35, 1006045, 0xFFFFFF, false, false); // Cancel
            }

            public override void OnResponse(NetState sender, RelayInfo info)
            {
                if (info.ButtonID == 1)
                    this.m_Chest.EndRemove(this.m_From);
            }
        }

        private class RemoveEntry : ContextMenuEntry
        {
            private readonly Mobile m_From;
            private readonly JewelryTestChest m_Chest;
            public RemoveEntry(Mobile from, JewelryTestChest chest)
                : base(6149, 3)
            {
                this.m_From = from;
                this.m_Chest = chest;

                this.Enabled = (from == chest.Owner);
            }

            public override void OnClick()
            {
                if (this.m_Chest.Deleted || this.m_From != this.m_Chest.Owner || !this.m_From.CheckAlive())
                    return;

                this.m_Chest.BeginRemove(this.m_From);
            }
        }

        private class DeleteTimer : Timer
        {
            private readonly Item m_Item;
            public DeleteTimer(Item item, DateTime time)
                : base(time - DateTime.UtcNow)
            {
                this.m_Item = item;
                this.Priority = TimerPriority.OneMinute;
            }

            protected override void OnTick()
            {
                this.m_Item.Delete();
            }
        }
    }
}