using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
using System;
using System.Collections.Generic;

namespace Server.Items
{
    public class CollectorXML3 : Container
    {
        public override int DefaultMaxWeight { get { return 0; } } // A value of 0 signals unlimited weight
        public override bool Decays { get { return false; } }
        public override bool DisplayWeight { get { return false; } }
        public override bool DisplaysContent { get { return false; } }
        public override bool IsPublicContainer { get { return true; } }
        public override bool IsDecoContainer { get { return false; } }
        // 		public override string DefaultName { get { return "Collector"; } }

        private XmlSpawner m_LinkedXMLSpawner;
        private double i_Delay;
        private string m_Key1;
        private string m_Label1;
        private string m_Key1Name;
        private int m_Key1_cur;
        private int m_Key1_max;
        private string m_Key2;
        private string m_Label2;
        private string m_Key2Name;
        private int m_Key2_cur;
        private int m_Key2_max;
        private string m_Key3;
        private string m_Label3;
        private int m_Key3_cur;
        private int m_Key3_max;
        private string m_Key4;
        private string m_Label4;
        private int m_Key4_cur;
        private int m_Key4_max;
        private string m_Key5;
        private string m_Label5;
        private int m_Key5_cur;
        private int m_Key5_max;

        private bool m_AllKeys;

        public XmlSpawner LinkedXMLSpawner { get { return m_LinkedXMLSpawner; } set { m_LinkedXMLSpawner = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public double DeleteDelay
        {
            get { return i_Delay; }
            set { i_Delay = value; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key1
        {
            get { return m_Key1; }
            set
            {
                string str = value;

                if (!String.IsNullOrEmpty(str))
                {
                    str = str.ToLower();
                    str = str.Trim();

                    Type type = SpawnerType.GetType(str);

                    if (type != null)
                        m_Key1 = str;
                    else
                        m_Key1 = "-invalid-";
                }
                else
                    m_Key1 = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Label1
        {
            get { return m_Label1; }
            set
            {
                if (value.Length <= 1)
                    m_Label1 = m_Key1;
                else
                    m_Label1 = value;
                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key1Name
        {
            get { return m_Key1Name; }
            set
            {
                if (String.IsNullOrEmpty(value))
                    m_Key1Name = null;
                else
                    m_Key1Name = value;
                InvalidateProperties();
            }
        }

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

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

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key2
        {
            get { return m_Key2; }
            set
            {
                string str = value;

                if (!String.IsNullOrEmpty(str))
                {
                    str = str.ToLower();
                    str = str.Trim();

                    Type type = SpawnerType.GetType(str);

                    if (type != null)
                        m_Key2 = str;
                    else
                        m_Key2 = "-invalid-";
                }
                else
                    m_Key2 = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Label2
        {
            get { return m_Label2; }
            set
            {
                if (value.Length <= 1)
                    m_Label2 = m_Key2;
                else
                    m_Label2 = value;
                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key2Name
        {
            get { return m_Key2Name; }
            set
            {
                if (String.IsNullOrEmpty(value))
                    m_Key2Name = null;
                else
                    m_Key2Name = value;
                InvalidateProperties();
            }
        }

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

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

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key3
        {
            get { return m_Key3; }
            set
            {
                string str = value;

                if (!String.IsNullOrEmpty(str))
                {
                    str = str.ToLower();
                    str = str.Trim();

                    Type type = SpawnerType.GetType(str);

                    if (type != null)
                        m_Key3 = str;
                    else
                        m_Key3 = "-invalid-";
                }
                else
                    m_Key3 = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Label3
        {
            get { return m_Label3; }
            set
            {
                if (value.Length <= 1)
                    m_Label3 = m_Key3;
                else
                    m_Label3 = value;
                InvalidateProperties();
            }
        }

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

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

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key4
        {
            get { return m_Key4; }
            set
            {
                string str = value;

                if (!String.IsNullOrEmpty(str))
                {
                    str = str.ToLower();
                    str = str.Trim();

                    Type type = SpawnerType.GetType(str);

                    if (type != null)
                        m_Key4 = str;
                    else
                        m_Key4 = "-invalid-";
                }
                else
                    m_Key4 = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Label4
        {
            get { return m_Label4; }
            set
            {
                if (value.Length <= 1)
                    m_Label4 = m_Key4;
                else
                    m_Label4 = value;
                InvalidateProperties();
            }
        }

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

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

        [CommandProperty(AccessLevel.GameMaster)]
        public String Key5
        {
            get { return m_Key5; }
            set
            {
                string str = value;

                if (!String.IsNullOrEmpty(str))
                {
                    str = str.ToLower();
                    str = str.Trim();

                    Type type = SpawnerType.GetType(str);

                    if (type != null)
                        m_Key5 = str;
                    else
                        m_Key5 = "-invalid-";
                }
                else
                    m_Key5 = null;

                InvalidateProperties();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public String Label5
        {
            get { return m_Label5; }
            set
            {
                if (value.Length <= 1)
                    m_Label5 = m_Key5;
                else
                    m_Label5 = value;
                InvalidateProperties();
            }
        }

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

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

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

        [Constructable]
        public CollectorXML3() : this(1.0) { }

        [Constructable]
        public CollectorXML3(double DelayTime) : base(0x9A8)
        {
            Movable = false;
            LiftOverride = false;
            Name = "Kouzelna skrinka";
            i_Delay = DelayTime;
            m_Key1_cur = 0;
            m_Key2_cur = 0;
            m_Key3_cur = 0;
            m_Key4_cur = 0;
            m_Key5_cur = 0;
            m_Key1_max = 1;
            m_Key2_max = 1;
            m_Key3_max = 1;
            m_Key4_max = 1;
            m_Key5_max = 1;
        }

        public override void AddNameProperties(ObjectPropertyList list)
        {
            base.AddNameProperties(list);
            list.Add("Seznam predmetu:");
            if (m_Label1 != null)
                list.Add(1060658, "{0}\t{1}", m_Label1.ToString(), String.Format("{0}/{1}", m_Key1_cur, m_Key1_max));
            if (m_Label2 != null)
                list.Add(1060659, "{0}\t{1}", m_Label2.ToString(), String.Format("{0}/{1}", m_Key2_cur, m_Key2_max));
            if (m_Label3 != null)
                list.Add(1060660, "{0}\t{1}", m_Label3.ToString(), String.Format("{0}/{1}", m_Key3_cur, m_Key3_max));
            if (m_Label4 != null)
                list.Add(1060661, "{0}\t{1}", m_Label4.ToString(), String.Format("{0}/{1}", m_Key4_cur, m_Key4_max));
            if (m_Label5 != null)
                list.Add(1060662, "{0}\t{1}", m_Label5.ToString(), String.Format("{0}/{1}", m_Key5_cur, m_Key5_max));
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);
            Server.Engines.XmlSpawner2.XmlAttach.AddAttachmentProperties(this, list);
        }

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

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

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

            writer.Write(m_Key1Name);
            writer.Write(m_Key2Name);

            writer.Write(m_LinkedXMLSpawner);
            writer.Write((double)i_Delay);
            writer.Write(m_Key1);
            writer.Write(m_Label1);
            writer.Write((int)m_Key1_cur);
            writer.Write((int)m_Key1_max);
            writer.Write(m_Key2);
            writer.Write(m_Label2);
            writer.Write((int)m_Key2_cur);
            writer.Write((int)m_Key2_max);
            writer.Write(m_Key3);
            writer.Write(m_Label3);
            writer.Write((int)m_Key3_cur);
            writer.Write((int)m_Key3_max);
            writer.Write(m_Key4);
            writer.Write(m_Label4);
            writer.Write((int)m_Key4_cur);
            writer.Write((int)m_Key4_max);
            writer.Write(m_Key5);
            writer.Write(m_Label5);
            writer.Write((int)m_Key5_cur);
            writer.Write((int)m_Key5_max);
            writer.Write((bool)m_AllKeys);
        }

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

            int version = reader.ReadInt();
            switch (version)
            {
                case 1:
                    {
                        m_Key1Name = reader.ReadString();
                        m_Key2Name = reader.ReadString();
                        goto case 0;
                    }
                case 0:
                    {
                        m_LinkedXMLSpawner = reader.ReadItem() as XmlSpawner;
                        i_Delay = reader.ReadDouble();
                        m_Key1 = reader.ReadString();
                        m_Label1 = reader.ReadString();
                        m_Key1_cur = reader.ReadInt();
                        m_Key1_max = reader.ReadInt();
                        m_Key2 = reader.ReadString();
                        m_Label2 = reader.ReadString();
                        m_Key2_cur = reader.ReadInt();
                        m_Key2_max = reader.ReadInt();
                        m_Key3 = reader.ReadString();
                        m_Label3 = reader.ReadString();
                        m_Key3_cur = reader.ReadInt();
                        m_Key3_max = reader.ReadInt();
                        m_Key4 = reader.ReadString();
                        m_Label4 = reader.ReadString();
                        m_Key4_cur = reader.ReadInt();
                        m_Key4_max = reader.ReadInt();
                        m_Key5 = reader.ReadString();
                        m_Label5 = reader.ReadString();
                        m_Key5_cur = reader.ReadInt();
                        m_Key5_max = reader.ReadInt();
                        m_AllKeys = reader.ReadBool();
                        break;
                    }
            }

            if (Items.Count > 0)
            {
                m_Timer = new EmptyTimer(this, i_Delay);
                m_Timer.Start();
            }
        }

        public override bool OnDragDrop(Mobile from, Item dropped)
        {
            if (m_Key1 == "-invalid-" || m_Key1 == null || m_Key2 == "-invalid-" || m_Key2 == null || m_Key3 == "-invalid-" || m_Key3 == null || m_Key4 == "-invalid-" || m_Key4 == null || m_Key5 == "-invalid-" || m_Key5 == null
          || m_LinkedXMLSpawner == null || m_LinkedXMLSpawner.Deleted || from == null || dropped == null)
            {
                from.SendMessage("Collector je spatne nastaven. Kontaktuj prosim Game mastera.");
                return false;
            }

            if (m_AllKeys)
            {
                from.SendMessage("V {0} je plny, chvili pockej az se vyprazdni.", this.Name);
                return false;
            }

            Type droppedType = (dropped is Xanthos.Interfaces.IShrinkItem) ? ((Xanthos.Interfaces.IShrinkItem)dropped).ShrunkenPet.GetType() : dropped.GetType();

            Type typeKey1 = SpawnerType.GetType(m_Key1);
            Type typeKey2 = SpawnerType.GetType(m_Key2);
            Type typeKey3 = SpawnerType.GetType(m_Key3);
            Type typeKey4 = SpawnerType.GetType(m_Key4);
            Type typeKey5 = SpawnerType.GetType(m_Key5);

            if (droppedType == typeKey1 || droppedType == typeKey2 || droppedType == typeKey3 || droppedType == typeKey4 || droppedType == typeKey5)
            {
                int droppedAmount = dropped.Amount;

                if ((droppedType == typeKey1 && m_Key1Name != null && (dropped.Name == null || !m_Key1Name.Equals(dropped.Name, StringComparison.OrdinalIgnoreCase)))
                  || (droppedType == typeKey2 && m_Key2Name != null && (dropped.Name == null || !m_Key2Name.Equals(dropped.Name, StringComparison.OrdinalIgnoreCase))))
                {
                    from.SendMessage("Tento predmet nelze do {0} umistit.", this.Name);
                    return false;
                }
                else if ((droppedType == typeKey1 && (m_Key1_cur == m_Key1_max || m_Key1_cur + droppedAmount > m_Key1_max)) ||
                    (droppedType == typeKey2 && (m_Key2_cur == m_Key2_max || m_Key2_cur + droppedAmount > m_Key2_max)) ||
                    (droppedType == typeKey3 && (m_Key3_cur == m_Key3_max || m_Key3_cur + droppedAmount > m_Key3_max)) ||
                    (droppedType == typeKey4 && (m_Key4_cur == m_Key4_max || m_Key4_cur + droppedAmount > m_Key4_max)) ||
                    (droppedType == typeKey5 && (m_Key5_cur == m_Key5_max || m_Key5_cur + droppedAmount > m_Key5_max)))
                {
                    from.SendMessage("Pozadovane mnozstvi tohoto predmetu je jiz v {0} umisteno, nebo vhazujes prilis mnoho.", this.Name);
                    return false;
                }
                else //ok
                {
                    if (droppedType == typeKey1)
                        m_Key1_cur += droppedAmount;
                    else if (droppedType == typeKey2)
                        m_Key2_cur += droppedAmount;
                    else if (droppedType == typeKey3)
                        m_Key3_cur += droppedAmount;
                    else if (droppedType == typeKey4)
                        m_Key4_cur += droppedAmount;
                    else if (droppedType == typeKey5)
                        m_Key5_cur += droppedAmount;

                    InvalidateProperties();

                    if ((m_Key1_cur == m_Key1_max) && (m_Key2_cur == m_Key2_max) && (m_Key3_cur == m_Key3_max) && (m_Key4_cur == m_Key4_max) && (m_Key5_cur == m_Key5_max))
                    {
                        m_AllKeys = true;
                        m_LinkedXMLSpawner.DoReset = true;
                        m_LinkedXMLSpawner.TriggerMob = from;
                        m_LinkedXMLSpawner.DoRespawn = true;
                        m_LinkedXMLSpawner.Running = false;
                        Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5024);
                        Effects.PlaySound(Location, Map, 0x1FF);
                        from.SendMessage("V {0} jsou nyni umisteny vsechny pozadovane predmety.", this.Name);
                    }
                    else
                        from.SendMessage("Predmet byl umisten do {0}.", this.Name);

                    from.SendMessage("{0} bude vyprazdnen za {1} minuty.", this.Name, i_Delay);

                    if (m_Timer != null)
                        m_Timer.Stop();

                    m_Timer = null;
                    m_Timer = new EmptyTimer(this, i_Delay);

                    m_Timer.Start();
                    return base.OnDragDrop(from, dropped);
                }
            }
            else
            {
                from.SendMessage("Tento predmet nelze do {0} umistit.", this.Name);
                return false;
            }
        }

        // 		public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
        // 		{
        // 			from.SendMessage( "Predmet byl umisten do colectoru." );
        // 
        // 			if ( m_Timer != null )
        // 				m_Timer.Stop();
        // 			else
        // 				m_Timer = new EmptyTimer( this, i_Delay );
        // 
        // 			m_Timer.Start();
        // 			return base.OnDragDropInto( from, item, p );
        // 		}

        public override void OnDoubleClick(Mobile from)
        {
            if ((int)from.AccessLevel > (int)AccessLevel.Counselor && (LinkedXMLSpawner == null || LinkedXMLSpawner.Deleted))
            {
                from.BeginTarget(-1, false, TargetFlags.Beneficial, new TargetCallback(ConnectTarget_Callback));
                from.SendMessage("Zamer XMLSpawner se kterym chces collector spojit.");
            }
            else if ((int)from.AccessLevel > (int)AccessLevel.Player)
                base.OnDoubleClick(from);
            else if (m_AllKeys)
            {
                if (from.HasGump(typeof(ConfirmEmpty)))
                    from.CloseGump(typeof(ConfirmEmpty));

                from.SendGump(new ConfirmEmpty(this));
            }
        }

        private class ConfirmEmpty : BaseConfirmGump
        {
            public override int TitleNumber { get { return 1053045; } } // Empty the bowl? --- 1075083 <center>Warning!</center>
            public override int LabelNumber { get { return 1074975; } } // Are you sure you wish to select this?

            private CollectorXML3 m_Item;

            public ConfirmEmpty(CollectorXML3 item) : base()
            {
                m_Item = item;
            }

            public override void Confirm(Mobile from)
            {
                if (m_Item == null || m_Item.Deleted || !m_Item.AllKeys)
                    return;

                m_Item.Empty();
            }
        }

        private void ConnectTarget_Callback(Mobile from, object obj)
        {
            if (obj is Item && obj is XmlSpawner)
            {
                XmlSpawner ps = (XmlSpawner)obj;

                LinkedXMLSpawner = ps;
                from.SendMessage("Spojil jsi uspesne collector se spawnerem.");
            }
            else
            {
                from.SendMessage("Musis zamerit XMLSpawner!");
            }
        }

        public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
        {
            if ((int)from.AccessLevel > (int)AccessLevel.Player)
                return base.CheckLift(from, item, ref reject);
            else
                reject = LRReason.CannotLift;

            return false;
        }

        public override void DisplayTo(Mobile m)
        {
            if ((int)m.AccessLevel > (int)AccessLevel.Player)
                base.DisplayTo(m);
        }

        public override void OnItemUsed(Mobile from, Item item)
        {
            if ((int)from.AccessLevel > (int)AccessLevel.Player)
                base.OnItemUsed(from, item);
        }

        public void Empty()
        {
            List<Item> items = this.Items;

            if (items.Count > 0)
            {
                PublicOverheadMessage(MessageType.Regular, 0x3B2, false, String.Format("*{0} byla vyprazdnena*", this.Name));
                Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
                Effects.PlaySound(Location, Map, 0x201);

                for (int i = items.Count - 1; i >= 0; --i)
                {
                    if (i >= items.Count)
                        continue;

                    items[i].Delete();
                }
            }

            if (m_Timer != null)
                m_Timer.Stop();

            m_Timer = null;

            m_Key1_cur = 0;
            m_Key2_cur = 0;
            m_Key3_cur = 0;
            m_Key4_cur = 0;
            m_Key5_cur = 0;
            InvalidateProperties();
            m_AllKeys = false;
        }

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

            m_Timer = null;
            base.OnAfterDelete();
        }

        private Timer m_Timer;

        private class EmptyTimer : Timer
        {
            private CollectorXML3 m_Barrel;

            public EmptyTimer(CollectorXML3 barrel, double i_Delay) : base(TimeSpan.FromMinutes(i_Delay))
            {
                m_Barrel = barrel;
                Priority = TimerPriority.FiveSeconds;
            }

            protected override void OnTick()
            {
                m_Barrel.Empty();
            }
        }
    }
}
