context: /*
   created by:
       /\            888                   888     .d8888b.   .d8888b.  
  ____/_ \____       888                   888    d88P  Y88b d88P  Y88b 
  \  ___\ \  /       888                   888    888    888 888    888 
   \/ /  \/ /    .d88888  8888b.   8888b.  888888 Y88b. d888 Y88b. d888 
   / /\__/_/\   d88" 888     "88b     "88b 888     "Y888P888  "Y888P888 
  /__\ \_____\  888  888 .d888888 .d888888 888           888        888 
      \  /      Y88b 888 888  888 888  888 Y88b.  Y88b  d88P Y88b  d88P 
       \/        "Y88888 "Y888888 "Y888888  "Y888  "Y8888P"   "Y8888P"  
  */
  #define USE_TOKENS
  using System;
  using Server;
  using Server.Items;
  using Server.Gumps;
  using Server.Network;
  using Server.Mobiles;
  using System.Text;
  using System.Text.RegularExpressions;
  using System.Collections.Generic;
  
  namespace daat99
  {
  	public class MasterStorageStorageGump : Gump
  	{
  		private static readonly BaseStorage NoFilter = ItemStorage.Storage;
  		public class StoredItemGumpObject
  		{
  			public ulong Amount;
  			public Type ItemType;
  			public StoredItemGumpObject(Type type, ulong amount)
  			{
  				ItemType = type;
  				Amount = amount;
  			}
  
  			public string GetVisualName()
  			{
  				StringBuilder sb = new StringBuilder();
  				sb.Append(Amount.ToString());
  				sb.Append(":  ");
  				sb.Append(Regex.Replace(ItemType.Name, "([A-Z])", " $1").Trim());
  				return sb.ToString();
  			}
  		}
  		public static void SendGump(Mobile from, MasterStorage backpack) { SendGump(from, backpack, -1); }
  		public static void SendGump(Mobile from, MasterStorage backpack, int page)  { SendGump(from, backpack, page, null); }
  		public static void SendGump(Mobile from, MasterStorage backpack, int page, BaseStorage filter)
  		{
  			CloseGump(from);
  			if (from == null )
  				return;
  			if (backpack == null || backpack.Deleted || !backpack.IsOwner(from as PlayerMobile))
  			{
  				from.SendMessage(1173, "You don't have your Master Storage in your backpack.");
  				return;
  			}
  			from.SendGump(new MasterStorageStorageGump(from as PlayerMobile, backpack, page, filter));
  		}
  		public static void CloseGump(Mobile from)
  		{
  			if (from != null && from.HasGump(typeof(MasterStorageStorageGump)))
  				from.CloseGump(typeof(MasterStorageStorageGump));
  		}
  
  		enum BUTTONS_ENUM
  		{
  			OK = 0, WEBSITE, REFILL, AMOUNT_TEXT, RESET_FILTER, PREVIOUS_PAGE, NEXT_PAGE, FILTER_START = 100, WITHDRAW_ITEM_START = 200
  		};
  
  		PlayerMobile player;
  		MasterStorage backpack;
  		int page;
  		BaseStorage filter;
  		StoredItemGumpObject[] items;
  		public MasterStorageStorageGump(PlayerMobile player, MasterStorage backpack) : this(player, backpack, -1, null) { }
  		public MasterStorageStorageGump(PlayerMobile player, MasterStorage backpack, int page, BaseStorage filter) : base(20, 20)
  		{
  			this.backpack = backpack;
  			this.page = page;
  			this.player = player;
  			this.filter = filter;
  			items = null;
  			if (backpack != null)
  			{
  				if (page == -1)
  					page = backpack.StoragePage;
  				if (filter == null)
  					filter = backpack.StorageFilter;
  			}
  			init();
  			if (player == null || backpack == null)
  				return;
  			drawFilters();
  			drawItems();
  			addPageControls();
  		}
  
  
  		private void init()
  		{
  			AddPage(0);
  			AddBackground(0, 0, 660, 500, 3500); //white  500 was 480
  
  			if (filter == null)
  				filter = ItemStorage.Storage;
  			AddHtml(250, 15, 450, 20, "<basefont color=#ff0000>Daat99's Master Storage </basefont> Showing: " + filter.Name, false, false);
  
  			AddLabel(15, 15, 2, @"====================");
  			AddLabel(58, 30, 2, @" /\");
  			AddLabel(19, 40, 2, @" -----/---\-----");
  			AddLabel(23, 50, 2, @" \ /     \ /");
  			AddLabel(31, 60, 2, @" /       \");
  			AddLabel(33, 60, 2, @" \       /");
  			AddLabel(22, 70, 2, @" / \     / \");
  			AddLabel(20, 80, 2, @" -----\---/-----");
  			AddLabel(60, 90, 2, @" \/");
  			AddLabel(15, 100, 2, @"====================");
  			
  			AddLabel(15, 120, 20, "Extract Amount:");
  			AddTextEntry(25, 140, 85, 20, 32, (int)BUTTONS_ENUM.AMOUNT_TEXT, 100.ToString());
  		}
  		private void drawFilters()
  		{
  			int filterIndex = 0;
  			int filterHeight = 20;
  			int topBuffer = 190;
  
  			AddButton(15, topBuffer, 4033, 4033, (int)BUTTONS_ENUM.REFILL, GumpButtonType.Reply, 1);
  			AddLabel(35, topBuffer-2, 1263, "Refill");
  			topBuffer += (int)(filterHeight*1.5);
  
  			AddButton(15, topBuffer, 4033, 4033, (int)BUTTONS_ENUM.RESET_FILTER, GumpButtonType.Reply, 0);
  			AddLabel(35, topBuffer - 2, 70, @"Clear filter");
  			topBuffer += filterHeight;
  
  			foreach (BaseStorage storage in backpack.StorageList)
  			{
  				AddButton(15, topBuffer + filterIndex * filterHeight, 4033, 4033, (int)BUTTONS_ENUM.FILTER_START + filterIndex, GumpButtonType.Reply, 0);
  				AddLabel(35, topBuffer - 2 + filterIndex * filterHeight, 70, storage.Name);
  				++filterIndex;
  			}
  		}
  
  		private void drawItems()
  		{
  			int leftBuffer = 170;
  			int topBuffer = 40;
  			int itemsPerRow = 2;
  			int itemsPerColumn = 20;
  			int itemHeight = 20;
  			int itemWidth = 240;
  			items = backpack.GetStoredItemsForPage(itemsPerRow * itemsPerColumn, page, filter);
  
  			for (int itemIndex = 0; itemIndex < items.Length && items[itemIndex] != null; ++itemIndex)
  			{
  				if ((int)(itemIndex / itemsPerColumn) >= itemsPerRow)
  					break;
  				int x = (int)(itemIndex / itemsPerColumn)*itemWidth + leftBuffer;
  				int y = (itemIndex % itemsPerColumn)*itemHeight + topBuffer;
  				AddButton( x, y, 2511, 2510, (int)BUTTONS_ENUM.WITHDRAW_ITEM_START + itemIndex, GumpButtonType.Reply, 0 );
  				AddHtml(x + 20, y, itemWidth - 20, itemHeight, items[itemIndex].GetVisualName(), false, false);
  			}
  		}
  
  		private void addPageControls()
  		{
  			if (page > 0)
  				AddButton(15, 160, 4014, 4016, (int)BUTTONS_ENUM.PREVIOUS_PAGE, GumpButtonType.Reply, 0);
  
  			AddButton(45, 159, 5526, 5527, (int)BUTTONS_ENUM.WEBSITE, GumpButtonType.Reply, 0);
  
  			if (items[items.Length - 1] != null)
  				AddButton(110, 160, 4005, 4007, (int)BUTTONS_ENUM.NEXT_PAGE, GumpButtonType.Reply, 0);
  		}
  
  		public override void OnResponse(NetState sender, RelayInfo info)
  		{
  			if (player == null)
  				return;
  			if (info.ButtonID == (int)BUTTONS_ENUM.OK)
  				CloseGump(player);
  			else if (info.ButtonID == (int)BUTTONS_ENUM.WEBSITE)
  				player.LaunchBrowser("http://daat99.home.dyndns.org/index.html");
  			else if (info.ButtonID == (int)BUTTONS_ENUM.RESET_FILTER)
  				SendGump(player, backpack, page, NoFilter);
  			else if (info.ButtonID == (int)BUTTONS_ENUM.PREVIOUS_PAGE)
  				SendGump(player, backpack, page - 1, filter);
  			else if (info.ButtonID == (int)BUTTONS_ENUM.NEXT_PAGE)
  				SendGump(player, backpack, page + 1, filter);
  			//extracting items
  			else if (info.ButtonID >= (int)BUTTONS_ENUM.WITHDRAW_ITEM_START && info.ButtonID < (int)BUTTONS_ENUM.WITHDRAW_ITEM_START + items.Length)
  			{
  				//calculate extract amount
  				TextRelay trText = info.GetTextEntry((int)BUTTONS_ENUM.AMOUNT_TEXT);
  				int amount = 0;
  				if (trText != null)
  				{
  					try { amount = Convert.ToInt32(trText.Text, 10); }
  					catch { player.SendMessage(1173, "Unable to parse the extract amount into a number."); }
  				}
  				int itemIndex = info.ButtonID - (int)BUTTONS_ENUM.WITHDRAW_ITEM_START;
  				if (amount < 0)
  					player.SendMessage(1173, "You must enter a positive number to extract.");
  				else if (itemIndex < 0 || itemIndex > items.Length)
  					player.SendMessage(1173, "Unrecognized item.");
  				else
  				{
  					StoredItemGumpObject storedItem = items[itemIndex];
  					ulong available = storedItem.Amount;
  					if ( available <= 0 )
  					{
  						player.SendMessage(1173, "You don't have that items.");
  						return;
  					}
  					if (available < (ulong)amount)
  					{
  						amount = (int)available;
  						player.SendMessage(1173, "You don't have enough of that item, extracting only " + amount + " instead.");
  					}
  					List<Item> extractedItems = backpack.TryExtractType(storedItem.ItemType, amount);
  					if (extractedItems == null || extractedItems.Count <= 0)
  						player.SendMessage(1173, "Unable to extract the items.");
  					else
  					{
  						foreach (Item item in extractedItems)
  							MasterStorageUtils.DropItemInBagOrFeet(player, backpack, item);
  						player.SendMessage(1173, "You successfully extracted " + amount + " items.");
  						SendGump(player, backpack, page, filter);
  					}
  				}
  			}
  			//changing filter
  			else if (info.ButtonID >= (int)BUTTONS_ENUM.FILTER_START && info.ButtonID < (int)BUTTONS_ENUM.WITHDRAW_ITEM_START)
  			{
  				int filterIndex = info.ButtonID - (int)BUTTONS_ENUM.FILTER_START;
  				if (filterIndex < 0 || filterIndex > backpack.StorageList.Count)
  					player.SendMessage(1173, "Unrecognized filter.");
  				else
  					SendGump(player, backpack, page, backpack.StorageList[filterIndex]);
  			}
  			else if (info.ButtonID == (int)BUTTONS_ENUM.REFILL)
  			{
  				backpack.RefillStorage(player);
  				SendGump(player, backpack, page, filter);
  			}
  		}
  	}
  
      public class MasterStorageSetupGump : Gump
      {
  		public static void SendGump(Mobile from, MasterStorage backpack, int page)
  		{
  			CloseGump(from);
  			if (from == null ||  backpack == null || backpack.Deleted || !backpack.IsOwner(from as PlayerMobile))
  				return;
  
gt: 			from.SendGump(new MasterStorageSetupGump(backpack, page));