using System;
using Server.Network;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using Server.Gumps;
using Server.Targeting;
using Server.Multis;

namespace Server.Items
{
	[FlipableAttribute(0xE41, 0xE40, 0xE79, 0xE77, 0x9AA, 0xE7D, 0x9A9, 0xE7E, 0xE3F, 0xE3E, 0xE3D, 0xE3C,
	                   0x9A8, 0xE80, 0x9AB, 0xE7C, 0xe43, 0xe42, 0x280B, 0x280C, 0x280F, 0x2810, 0x2811, 0x2812,
	                   0x2857, 0x2858, 0x2859, 0x285A, 0x285B, 0x285C, 0x285D, 0x285E, 0x2DF1, 0x2DF2, 0x2DF3, 0x2DF4)]
	public class WireBox : BaseContainer
	{
		private SortedDictionary<int, int> m_AcquiredItems;
		private int m_WithdrawIncrement;

		public bool HasItem(int dyeID)
		{
			if(m_AcquiredItems != null && m_AcquiredItems.ContainsKey(dyeID))
				return true;

			return false;
		}

		public void AcquireDye(int dyeID, int uses)
		{
			if(m_AcquiredItems == null)
			m_AcquiredItems = new SortedDictionary<int, int>();

			if (HasItem(dyeID))
				m_AcquiredItems[dyeID] += uses;
			else
				m_AcquiredItems[dyeID] = uses;
		}

		// 		public void ResetDyes()
		// 		{
		// 			m_AcquiredItems = null;
		// 		}


		public int KnownItems
		{
			get
			{
				if(m_AcquiredItems == null)
				return 0;

				return m_AcquiredItems.Count;
			}
		}



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

		public SortedDictionary<int, int> AcquiredItems
		{
			get
			{
				if(m_AcquiredItems == null)
				return null;

				return m_AcquiredItems;
			}

			set { m_AcquiredItems = value; }
		}



		[Constructable]
		public WireBox() : base(0xE80)
		{
			Movable = true;
			Weight = 10.0;
			Hue = 1260;
			Name = "Magical wire & Magic scroll Box";
			WithdrawIncrement = 10;
		}



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



		public override bool DisplaysContent { get { return false; } }

		public override void GetProperties(ObjectPropertyList list)
		{
			base.GetProperties(list);
			list.Add(1060658, "Magical wire, Magic scroll, Clothing skill scroll\t{0}", KnownItems);
		}



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

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

			writer.Write((int) m_WithdrawIncrement);

			if(m_AcquiredItems == null)
			{
				writer.Write((int)0);
			}
			else
			{
				writer.Write(m_AcquiredItems.Count);

				foreach(KeyValuePair<int, int> kvp in m_AcquiredItems)
				{
					writer.Write(kvp.Key);
					writer.Write(kvp.Value);
				}
			}
		}



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

			int version = reader.ReadInt();

			m_WithdrawIncrement = reader.ReadInt();

			switch(version)
			{
				case 1:
				{
					int dyesCount = reader.ReadInt();

					if(dyesCount > 0)
					{
						m_AcquiredItems = new SortedDictionary<int, int>();

						for(int i = 0; i < dyesCount; i++)
						{
							int r = reader.ReadInt();
							int ri = reader.ReadInt();
							m_AcquiredItems.Add(r, ri);
						}
					}



					goto case 0;
				}


				case 0:
				{
					break;
				}
			}
		}



		public override void OnDoubleClick(Mobile from)
		{
			if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this))
				from.LocalOverheadMessage(Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
			else if (KnownItems > 0)
			{
				if (!IsSecure)
				{
					from.SendMessage("Box must be secured in house.");
				}
				else
				{
					if(from.HasGump(typeof(WireBoxGump)))
						from.CloseGump(typeof(WireBoxGump));

					from.SendGump(new WireBoxGump(this));
				}
			}
			else
				from.SendMessage("Truhla je prazdna");
		}



		public override bool OnDragDrop(Mobile from, Item o)
		{
			if(from.HasGump(typeof(WireBoxGump)))
				from.CloseGump(typeof(WireBoxGump));

			if (!IsSecure)
			{
				from.SendMessage("Box must be secured in house.");
				return false;
			}
			else
			{
				if (o is Item && ((Item)o).BlessedFor != null)
				{
					from.SendMessage("Blessed for predmety nelze do truhly vlozit");
					return false;
				}
				else if (o is MagicalWire)
				{
					MagicalWire wire = (MagicalWire) o;

					AcquireDye((int) wire.WeaponWireAttribute, wire.Bonus);
					wire.Delete();
					from.PlaySound(66);
					InvalidateProperties();
					return true;
				}
				else if (o is MagicScroll)
				{
					MagicScroll scroll = (MagicScroll) o;

					AcquireDye(((int) scroll.MagicScrollType) + 100, scroll.ScrollValue);
					scroll.Delete();
					InvalidateProperties();
					from.PlaySound(995);
					return true;
				}
				else if (o is ClothingSkillScroll)
				{
					ClothingSkillScroll scroll = (ClothingSkillScroll) o;

					AcquireDye(((int) scroll.Skill) + 1000, (int) scroll.Value);
					scroll.Delete();
					InvalidateProperties();
					from.PlaySound(995);
					return true;
				}
				else
					from.SendMessage("Do truhly lze vlozit pouze magicke draty a svitky, nebo clothing skill scrolly");

				return false;
			}
		}



		private class WireBoxGump : Gump
		{
			public static string[] WireName { get { return new string[]
					{


    			"lower stat req",
    			"leech hits",
    			"leech stam",
    			"leech mana",
    			"lower attack",
    			"lower defend",
    			"magic arrow",
    			"harm",
    			"fireball",
    			"lightning",
    			"dispel",
    			"cold area",
    			"fire area",
    			"poison area",
    			"energy area",
    			"physical area",
    			"resist physical",
    			"resist fire",
    			"resist cold",
    			"resist poison",
    			"resist energy",
    			"durability",
    			"weapon damage",
    			"defend chance",
    			"chance",
    			"luck",
    			"weapon speed"
					}; } }

			public static string[] ScrollName { get { return new string[]
					{


    			"luck",
    			"regen hits",
    			"regen mana",
    			"regen stam",
    			"bonus hits",
    			"bonus mana",
    			"bonus stam",
    			"spell damage",
    			"weapon damage",
    			"weapon speed",
    			"defend chance",
    			"hit chance",
    			"bonus str",
    			"bonus dex",
    			"bonus int",
    			"cast recovery",
    			"cast speed",
    			"crit chance", //spellbook
    			"crit damage",
    			"consecrate",
    			"leech chance"

					}; } }

			private static readonly int m_Fields = 20;
			private static readonly int m_HueTit = 0; //32767;
			private static readonly int m_HueEnt = 0; //32767;
			private static readonly int m_DeltaBut = 2;
			private static readonly int m_FieldsDist = 36;

			private WireBox m_Box;
			private List<int> m_Dyes;
			private int m_Page;

			public WireBoxGump(WireBox box): this(box, null, 1)
			{
			}



			public WireBoxGump(WireBox box, List<int> dyes, int page) : base(50, 50)
			{
				Closable = false;
				Disposable = true;
				Dragable = true;
				Resizable = false;

				m_Box = box;
				m_Dyes = dyes;
				m_Page = page;

				if(m_Dyes == null)
				m_Dyes = new List<int>(m_Box.AcquiredItems.Keys);

				Initialize();
			}



			public void Initialize()
			{
				if (m_Box.KnownItems < 1)
				return;

				AddPage(0);

				AddBackground(0, 0, 375, 455, 9200);

				AddImageTiled(10, 10, 355, 25, 9354);
				AddImageTiled(10, 45, 355, 370, 9354);
				AddImageTiled(40, 425, 325, 20, 9354);

				// 				AddAlphaRegion(10, 10, 355, 415);
				// 				AddAlphaRegion(70, 425, 295, 20);            

				AddLabelCropped(14, 12, 355, 25, m_HueEnt, String.Format("Magicke draty a svitky (Pocet: {0})", m_Box.KnownItems));
				// 	            AddHtmlLocalized( 14, 12, 355, 25, 1049753, m_HueTit, false, false ); // Dye Tubs

				AddButton(335, 11, 4017, 4018, 0, GumpButtonType.Reply, 0);

				AddButton(10, 425, 4005, 4007, 1, GumpButtonType.Reply, 0);
				AddHtmlLocalized(78, 425, 160, 20, 1062986, m_HueTit, false, false); // Withdraw request
			   AddTextEntry(45, 425, 40, 20, 0x480, 500, m_Box.WithdrawIncrement.ToString());

				if(m_Page > 1)
				AddButton(325, 427, 5603, 5607, 2, GumpButtonType.Reply, 0); // Previous page

				if(m_Page < Math.Ceiling(m_Dyes.Count/(double)m_Fields))
					AddButton(345, 427, 5601, 5605, 3, GumpButtonType.Reply, 0); // Next Page

				int IndMax = (m_Page * m_Fields) - 1;
				int IndMin = (m_Page * m_Fields) - m_Fields;
				int IndTemp = 0;
				int RightTemp = 0;

				for(int i = 0; i < m_Dyes.Count; i++)
				{
					if(i >= IndMin && i <= IndMax)
					{
						int id = m_Dyes[i];
						string name = "???";
						int img = 6263;
						int imgHue = 2123;

						if (id >= 1000)
						{
							name = ClothingSkillScroll.GetName(id - 1000);
							img = 5360;
							imgHue = 2607;
						}
						else if (id >= 100)
						{
							name = ScrollName[ id - 100 ];
							img = 5360;
							imgHue = 1573;
						}
						else
						{
							name = WireName[ id ];

							switch (id)
							{
								case (int) MagicalWire.WireAttribute.LowerStatReq: imgHue = 1477; break;
								case (int) MagicalWire.WireAttribute.HitLeechHits: imgHue = 1194; break;
								case (int) MagicalWire.WireAttribute.HitLeechStam: imgHue = 1099; break;
								case (int) MagicalWire.WireAttribute.HitLeechMana: imgHue = 1363; break;
								case (int) MagicalWire.WireAttribute.HitLowerAttack: imgHue = 1097; break;
								case (int) MagicalWire.WireAttribute.HitLowerDefend: imgHue = 1180; break;
								case (int) MagicalWire.WireAttribute.HitMagicArrow: imgHue = 1098; break;
								case (int) MagicalWire.WireAttribute.HitHarm: imgHue = 1182; break;
								case (int) MagicalWire.WireAttribute.HitFireball: imgHue = 1101; break;
								case (int) MagicalWire.WireAttribute.HitLightning: imgHue = 1100; break;
								case (int) MagicalWire.WireAttribute.HitDispel: imgHue = 1601; break;
								case (int) MagicalWire.WireAttribute.HitColdArea: imgHue = 1095; break;
								case (int) MagicalWire.WireAttribute.HitFireArea: imgHue = 1060; break;
								case (int) MagicalWire.WireAttribute.HitPoisonArea: imgHue = 1094; break;
								case (int) MagicalWire.WireAttribute.HitEnergyArea: imgHue = 2123; break;
								case (int) MagicalWire.WireAttribute.HitPhysicalArea: imgHue = 1093; break;
								case (int) MagicalWire.WireAttribute.ResistPhysicalBonus: imgHue = 2305; break;
								case (int) MagicalWire.WireAttribute.ResistFireBonus: imgHue = 1096; break;
								case (int) MagicalWire.WireAttribute.ResistColdBonus: imgHue = 1151; break;
								case (int) MagicalWire.WireAttribute.ResistPoisonBonus: imgHue = 565; break;
								case (int) MagicalWire.WireAttribute.ResistEnergyBonus: imgHue = 1361; break;
								case (int) MagicalWire.WireAttribute.DurabilityBonus: imgHue = 1179; break;
								case (int) MagicalWire.WireAttribute.WeaponDamage: imgHue = 1092; break;
								case (int) MagicalWire.WireAttribute.DefendChance: imgHue = 1192; break;
								case (int) MagicalWire.WireAttribute.AttackChance: imgHue = 1196; break;
								case (int) MagicalWire.WireAttribute.Luck: imgHue = 1150; break;
								case (int) MagicalWire.WireAttribute.WeaponSpeed: imgHue = 1195; break;
							}
						}



						AddItem(142 + RightTemp, 50 + (IndTemp * m_FieldsDist), img, imgHue);
						AddLabelCropped(35 + RightTemp, 52 + (IndTemp * m_FieldsDist), 225, 20, m_HueEnt, String.Format("{0} ({1})", name, (m_Box.HasItem(id)) ? m_Box.AcquiredItems[id] : 0));
						AddButton(15 + RightTemp, 52 + m_DeltaBut + (IndTemp * m_FieldsDist), 1209, 1210, i + 10, GumpButtonType.Reply, 0);
						IndTemp++;

						if ((m_Fields / 2) == IndTemp)
						{
							IndTemp = 0;
							RightTemp = 170;
						}
					}
				}
			}




			public override void OnResponse(NetState sender, RelayInfo info)
			{
				Mobile from = sender.Mobile;

				if (info.ButtonID == 0)
				return;
				else if(info.ButtonID == 1) // Withdraw
				{
					int i_Withdraw = BlackSmithBoxGump.CheckWithdraw(from, info);

					if (i_Withdraw > 0)
					{
						m_Box.WithdrawIncrement = i_Withdraw;
						from.SendMessage("Vyber nastaven na {0}", i_Withdraw);
					}
					else
						m_Box.WithdrawIncrement = 1;

					from.SendGump(new WireBoxGump(m_Box, m_Dyes, m_Page));
				}
				else if(info.ButtonID == 2) // Previous page
				{
					m_Page--;
					from.SendGump(new WireBoxGump(m_Box, m_Dyes, m_Page));
				}
				else if(info.ButtonID == 3) // Next Page
				{
					m_Page++;
					from.SendGump(new WireBoxGump(m_Box, m_Dyes, m_Page));
				}
				else
				{
					int id = m_Dyes[info.ButtonID - 10];

					if (m_Box == null)
					return;

					if (m_Box.AcquiredItems[id] > m_Box.WithdrawIncrement)
					{
						from.AddToBackpack(CreateItem(id, m_Box.WithdrawIncrement));
						m_Box.AcquiredItems[id] = m_Box.AcquiredItems[id] - m_Box.WithdrawIncrement;
					}
					else if (m_Box.AcquiredItems[id] > 0)
					{
						from.AddToBackpack(CreateItem(id, m_Box.AcquiredItems[id]));
						m_Box.AcquiredItems.Remove(id);
					}
					else
					{
						from.SendMessage("Tohle v truhle neni");
					}



					from.SendGump(new WireBoxGump(m_Box, new List<int>(m_Box.AcquiredItems.Keys), m_Page));
					m_Box.InvalidateProperties();
				}
			}



			private static Item CreateItem(int id, int amount)
			{
				if (id >= 1000)
				{
					return new ClothingSkillScroll((SkillName) (id - 1000), (double) amount);
				}
				else if (id >= 100)
				{
					MagicScroll scroll = new MagicScroll(amount);
					scroll.MagicScrollType = (MagicScroll.ScrollType) id - 100;

					return scroll;
				}
				else
				{
					return new MagicalWire((MagicalWire.WireAttribute) id, amount);
				}
			}
		}
	}
}