context: using System;
  using System.Collections.Generic;
  using Server.Items;
  
  namespace Server.Engines.Craft
  {
  	public enum CraftECA
  	{
  		ChanceMinusSixty,
  		FiftyPercentChanceMinusTenPercent,
  		ChanceMinusSixtyToFourtyFive
  	}
  
  	public abstract class CraftSystem
  	{
  		private int m_MinCraftEffect;
  		private int m_MaxCraftEffect;
  		private double m_Delay;
  		private bool m_Resmelt;
  		private bool m_Repair;
  		private bool m_MarkOption;
  		private bool m_CanEnhance;
  
  		private CraftItemCol m_CraftItems;
  		private CraftGroupCol m_CraftGroups;
  		private CraftSubResCol m_CraftSubRes;
  		private CraftSubResCol m_CraftSubRes2;
  
  		private List<int> m_Recipes;
  		private List<int> m_RareRecipes;
  
  		public int MinCraftEffect { get { return m_MinCraftEffect; } }
  		public int MaxCraftEffect { get { return m_MaxCraftEffect; } }
  		public double Delay { get { return m_Delay; } }
  
  		public CraftItemCol CraftItems{ get { return m_CraftItems; } }
  		public CraftGroupCol CraftGroups{ get { return m_CraftGroups; } }
  		public CraftSubResCol CraftSubRes{ get { return m_CraftSubRes; } }
  		public CraftSubResCol CraftSubRes2{ get { return m_CraftSubRes2; } }
  
  		public abstract SkillName MainSkill{ get; }
  
  		public virtual int GumpTitleNumber{ get{ return 0; } }
  		public virtual string GumpTitleString{ get{ return ""; } }
  
  		public virtual CraftECA ECA{ get{ return CraftECA.ChanceMinusSixty; } }
  
  		private Dictionary<Mobile, CraftContext> m_ContextTable = new Dictionary<Mobile, CraftContext>();
  
  		public abstract double GetChanceAtMin( CraftItem item );
  
  		public virtual bool RetainsColorFrom( CraftItem item, Type type )
  		{
  			return false;
  		}
  
  		public CraftContext GetContext( Mobile m )
  		{
  			if ( m == null )
  				return null;
  
  			if ( m.Deleted )
  			{
  				m_ContextTable.Remove( m );
  				return null;
  			}
  
  			CraftContext c = null;
  			m_ContextTable.TryGetValue( m, out c );
  
  			if ( c == null )
  				m_ContextTable[m] = c = new CraftContext();
  
  			return c;
  		}
  
  		public void OnMade( Mobile m, CraftItem item )
  		{
  			CraftContext c = GetContext( m );
  
  			if ( c != null )
  				c.OnMade( item );
  		}
  
  		public bool Resmelt
  		{
  			get { return m_Resmelt; }
  			set { m_Resmelt = value; }
  		}
  
  		public bool Repair
  		{
  			get{ return m_Repair; }
  			set{ m_Repair = value; }
  		}
  
  		public bool MarkOption
  		{
  			get{ return m_MarkOption; }
  			set{ m_MarkOption = value; }
  		}
  
  		public bool CanEnhance
  		{
  			get{ return m_CanEnhance; }
  			set{ m_CanEnhance = value; }
  		}
  
  		public CraftSystem( int minCraftEffect, int maxCraftEffect, double delay )
  		{
  			m_MinCraftEffect = minCraftEffect;
  			m_MaxCraftEffect = maxCraftEffect;
  			m_Delay = delay;
  
  			m_CraftItems = new CraftItemCol();
  			m_CraftGroups = new CraftGroupCol();
  			m_CraftSubRes = new CraftSubResCol();
  			m_CraftSubRes2 = new CraftSubResCol();
  
  			m_Recipes = new List<int>();
  			m_RareRecipes = new List<int>();
  
  			InitCraftList();
  		}
  
  		public virtual bool ConsumeOnFailure( Mobile from, Type resourceType, CraftItem craftItem )
  		{
  			return true;
  		}
  
  		public void CreateItem( Mobile from, Type type, Type typeRes, Type typeRes2, BaseTool tool, CraftItem realCraftItem )
  		{	
  			// Verify if the type is in the list of the craftable item
  			CraftItem craftItem = m_CraftItems.SearchFor( type );
  			if ( craftItem != null )
  			{
  				// The item is in the list, try to create it
  				// Test code: items like sextant parts can be crafted either directly from ingots, or from different parts
  				realCraftItem.Craft( from, this, typeRes, typeRes2, tool );
  				//craftItem.Craft( from, this, typeRes, tool );
  			}
  		}
  
  		public int RandomRecipe()
  		{
  			if ( m_Recipes.Count == 0 )
  				return -1;
  
  			return m_Recipes[Utility.Random( m_Recipes.Count )];
  		}
  
  		public int RandomRareRecipe()
  		{
  			if ( m_RareRecipes.Count == 0 )
  				return -1;
  
  			return m_RareRecipes[Utility.Random( m_RareRecipes.Count )];
  		}
  
  
  		public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount )
  		{
  			return AddCraft( typeItem, group, name, MainSkill, minSkill, maxSkill, typeRes, nameRes, amount, "" );
  		}
  
  		public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount, TextDefinition message )
  		{
  			return AddCraft( typeItem, group, name, MainSkill, minSkill, maxSkill, typeRes, nameRes, amount, message );
  		}
  
  		public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, SkillName skillToMake, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount )
  		{
  			return AddCraft( typeItem, group, name, skillToMake, minSkill, maxSkill, typeRes, nameRes, amount, "" );
  		}
  
  		public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, SkillName skillToMake, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount, TextDefinition message )
  		{
  			CraftItem craftItem = new CraftItem( typeItem, group, name );
  			craftItem.AddRes( typeRes, nameRes, amount, message );
  			craftItem.AddSkill( skillToMake, minSkill, maxSkill );
  
  			DoGroup( group, craftItem );
  			return m_CraftItems.Add( craftItem );
  		}
  
  
  		private void DoGroup( TextDefinition groupName, CraftItem craftItem )
  		{
  			int index = m_CraftGroups.SearchFor( groupName );
  
  			if ( index == -1)
  			{
  				CraftGroup craftGroup = new CraftGroup( groupName );
  				craftGroup.AddCraftItem( craftItem );
  				m_CraftGroups.Add( craftGroup );
  			}
  			else
  			{
  				m_CraftGroups.GetAt( index ).AddCraftItem( craftItem );
  			}
  		}
  
  
  		public void SetItemHue( int index, int hue )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.ItemHue = hue;
  		}
  
  		public void SetManaReq( int index, int mana )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.Mana = mana;
  		}
  
  		public void SetStamReq( int index, int stam )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.Stam = stam;
  		}
  
  		public void SetHitsReq( int index, int hits )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.Hits = hits;
  		}
  		
  		public void SetUseAllRes( int index, bool useAll )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.UseAllRes = useAll;
  		}
  
  		public void SetNeedHeat( int index, bool needHeat )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.NeedHeat = needHeat;
  		}
  
  		public void SetNeedOven( int index, bool needOven )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.NeedOven = needOven;
  		}
  
  		public void SetBeverageType( int index, BeverageType requiredBeverage )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.RequiredBeverage = requiredBeverage;
  		}
  
  		public void SetNeedMill( int index, bool needMill )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.NeedMill = needMill;
  		}
  
  		public void SetNeededExpansion( int index, Expansion expansion )
  		{
  			CraftItem craftItem = m_CraftItems.GetAt( index );
  			craftItem.RequiredExpansion = expansion;
  		}
  
  		public void AddRes( int index, Type type, TextDefinition name, int amount )
  		{
  			AddRes( index, type, name, amount, "" );
  		}
  
  		public void AddRes( int index, Type type, TextDefinition name, int amount, TextDefinition message )
  		{
  
gt: 			CraftItem craftItem = m_CraftItems.GetAt( index );