context: using System;
  using System.Collections;
  using Server;
  using Server.Gumps;
  using Server.Items;
  using Server.Mobiles;
  using Server.Prompts;
  
  namespace Server.Engines.BulkOrders
  {
  	public class BOBGump : Gump
  	{
  		private PlayerMobile m_From;
  		private BulkOrderBook m_Book;
  		private ArrayList m_List;
  
  		private int m_Page;
  
  		private const int LabelColor = 0x7FFF;
  
  		public Item Reconstruct( object obj )
  		{
  			Item item = null;
  
  			if ( obj is BOBLargeEntry )
  				item = ((BOBLargeEntry)obj).Reconstruct();
  			else if ( obj is BOBSmallEntry )
  				item = ((BOBSmallEntry)obj).Reconstruct();
  
  			return item;
  		}
  
  		public bool CheckFilter( object obj )
  		{
  			if ( obj is BOBLargeEntry )
  			{
  				BOBLargeEntry e = (BOBLargeEntry)obj;
  
  				return CheckFilter( e.Material, e.AmountMax, true, e.RequireExceptional, e.DeedType, ( e.Entries.Length > 0 ? e.Entries[0].ItemType : null ) );
  			}
  			else if ( obj is BOBSmallEntry )
  			{
  				BOBSmallEntry e = (BOBSmallEntry)obj;
  
  				return CheckFilter( e.Material, e.AmountMax, false, e.RequireExceptional, e.DeedType, e.ItemType );
  			}
  
  			return false;
  		}
  
  		public bool CheckFilter( BulkMaterialType mat, int amountMax, bool isLarge, bool reqExc, BODType deedType, Type itemType )
  		{
  			BOBFilter f = ( m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter );
  
  			if ( f.IsDefault )
  				return true;
  
  			if ( f.Quality == 1 && reqExc )
  				return false;
  			else if ( f.Quality == 2 && !reqExc )
  				return false;
  
  			if ( f.Quantity == 1 && amountMax != 10 )
  				return false;
  			else if ( f.Quantity == 2 && amountMax != 15 )
  				return false;
  			else if ( f.Quantity == 3 && amountMax != 20 )
  				return false;
  
  			if ( f.Type == 1 && isLarge )
  				return false;
  			else if ( f.Type == 2 && !isLarge )
  				return false;
  
  			switch ( f.Material )
  			{
  				default:
  				case  0: return true;
  				case  1: return ( deedType == BODType.Smith );
  				case  2: return ( deedType == BODType.Tailor );
  
  				case  3: return ( mat == BulkMaterialType.None && BGTClassifier.Classify( deedType, itemType ) == BulkGenericType.Iron );
  				case  4: return ( mat == BulkMaterialType.DullCopper );
  				case  5: return ( mat == BulkMaterialType.ShadowIron );
  				case  6: return ( mat == BulkMaterialType.Copper );
  				case  7: return ( mat == BulkMaterialType.Bronze );
  				case  8: return ( mat == BulkMaterialType.Gold );
  				case  9: return ( mat == BulkMaterialType.Agapite );
  				case 10: return ( mat == BulkMaterialType.Verite );
  				case 11: return ( mat == BulkMaterialType.Valorite );
  
  				case 12: return ( mat == BulkMaterialType.None && BGTClassifier.Classify( deedType, itemType ) == BulkGenericType.Cloth );
  				case 13: return ( mat == BulkMaterialType.None && BGTClassifier.Classify( deedType, itemType ) == BulkGenericType.Leather );
  				case 14: return ( mat == BulkMaterialType.Spined );
  				case 15: return ( mat == BulkMaterialType.Horned );
  				case 16: return ( mat == BulkMaterialType.Barbed );
  			}
  		}
  
  		public int GetIndexForPage( int page )
  		{
  			int index = 0;
  
  			while ( page-- > 0 )
  				index += GetCountForIndex( index );
  
  			return index;
  		}
  
  		public int GetCountForIndex( int index )
  		{
  			int slots = 0;
  			int count = 0;
  
  			ArrayList list = m_List;
  
  			for ( int i = index; i >= 0 && i < list.Count; ++i )
  			{
  				object obj = list[i];
  
  				if ( CheckFilter( obj ) )
  				{
  					int add;
  
  					if ( obj is BOBLargeEntry )
  						add = ((BOBLargeEntry)obj).Entries.Length;
  					else
  						add = 1;
  
  					if ( (slots + add) > 10 )
  						break;
  
  					slots += add;
  				}
  
  				++count;
  			}
  
  			return count;
  		}
  
  		public int GetPageForIndex(int index, int sizeDropped)
  		{
  			if (index <= 0)
  				return 0;
  
  			int count = 0;
  			int add = 0;
  			int page = 0;
  			ArrayList list = m_List;
  			int i;
  			object obj;
  
  			for (i=0; (i < index) && (i < list.Count); i++)
  			{
  				obj = list[i];
  				if (CheckFilter(obj))
  				{
  					if (obj is BOBLargeEntry)
  						add = ((BOBLargeEntry)obj).Entries.Length;
  					else
  						add = 1;
  					count += add;
  					if (count > 10)
  					{
  						page++;
  						count = add;
  					}
  				}
  			}
  			/* now we are on the page of the bod preceeding the dropped one.
  			 * next step: checking whether we have to remain where we are.
  			 * The counter i needs to be incremented as the bod to this very moment
  			 * has not yet been removed from m_List */
  			i++;
  
  			/* if, for instance, a big bod of size 6 has been removed, smaller bods
  			 * might fall back into this page. Depending on their sizes, the page eeds
  			 * to be adjusted accordingly. This is done now.
  			 */
  			if (count + sizeDropped > 10)
  			{
  				while ((i < list.Count) && (count <= 10))
  				{
  					obj = list[i];
  					if (CheckFilter(obj))
  					{
  						if (obj is BOBLargeEntry)
  							count += ((BOBLargeEntry)obj).Entries.Length;
  						else
  							count += 1;
  					}
  					i++;
  				}
  				if (count > 10)
  					page++;
  			}
  			return page;
  		}
  
  
  		public object GetMaterialName( BulkMaterialType mat, BODType type, Type itemType )
  		{
  			switch ( type )
  			{
  				case BODType.Smith:
  				{
  					switch ( mat )
  					{
  						case BulkMaterialType.None: return 1062226;
  						case BulkMaterialType.DullCopper: return 1018332;
  						case BulkMaterialType.ShadowIron: return 1018333;
  						case BulkMaterialType.Copper: return 1018334;
  						case BulkMaterialType.Bronze: return 1018335;
  						case BulkMaterialType.Gold: return 1018336;
  						case BulkMaterialType.Agapite: return 1018337;
  						case BulkMaterialType.Verite: return 1018338;
  						case BulkMaterialType.Valorite: return 1018339;
  					}
  
  					break;
  				}
  				case BODType.Tailor:
  				{
  					switch ( mat )
  					{
  						case BulkMaterialType.None:
  						{
  							if ( itemType.IsSubclassOf( typeof( BaseArmor ) ) || itemType.IsSubclassOf( typeof( BaseShoes ) ) )
  								return 1062235;
  
  							return 1044286;
  						}
  						case BulkMaterialType.Spined: return 1062236;
  						case BulkMaterialType.Horned: return 1062237;
  						case BulkMaterialType.Barbed: return 1062238;
  					}
  
  					break;
  				}
  			}
  
  			return "Invalid";
  		}
  
  		public BOBGump( PlayerMobile from, BulkOrderBook book ) : this( from, book, 0, null )
  		{
  		}
  
  		public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
  		{
  			int index = info.ButtonID;
  
  			switch ( index )
  			{
  				case 0: // EXIT
  				{
  					break;
  				}
  				case 1: // Set Filter
  				{
  					m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
  
  					break;
  				}
  				case 2: // Previous page
  				{
  					if ( m_Page > 0 )
  						m_From.SendGump( new BOBGump( m_From, m_Book, m_Page - 1, m_List ) );
  
  					return;
  				}
  				case 3: // Next page
  				{
  					if ( GetIndexForPage( m_Page + 1 ) < m_List.Count )
  						m_From.SendGump( new BOBGump( m_From, m_Book, m_Page + 1, m_List ) );
  
  					break;
  				}
  				case 4: // Price all
  				{
  					if ( m_Book.IsChildOf( m_From.Backpack ) )
  					{
  						m_From.Prompt = new SetPricePrompt( m_Book, null, m_Page, m_List );
  						m_From.SendMessage( "Type in a price for all deeds in the book:" );
  					}
  
  					break;
  				}
  				default:
  				{
  					bool canDrop = m_Book.IsChildOf( m_From.Backpack );
  					bool canPrice = canDrop || (m_Book.RootParent is PlayerVendor);
  
  					index -= 5;
  
  					int type = index % 2;
  
gt: 					index /= 2;