context: using System; 
  using System.Collections; 
  using Server.Items; 
  using Server.Gumps;
  using Server.Network;
  using Server.Targeting; 
  using Server.Spells; 
  using Server.Mobiles; 
  using Server.Engines.Craft;
  
  namespace Server.Items 
  { 
  	public class MC
  	{
  		private Mobile m_CompletedBy;
  		private bool m_Completed;
  		private Type m_type;
  		private int m_amount;
  		private int m_killed;
  		private AosAttribute m_AA = (AosAttribute)(0);
  		private AosWeaponAttribute m_AWA = (AosWeaponAttribute)(0);
  		private AosArmorAttribute m_AAA = (AosArmorAttribute)(0);
  
  		public bool Completed
  		{
  			get{ return m_Completed; }
  			set{ m_Completed = value; }
  		}
  		public Mobile CompletedBy
  		{
  			get{ return m_CompletedBy; }
  			set{ m_CompletedBy = value; }
  		}
  		public AosAttribute AA
  		{
  			get{ return m_AA; }
  			set{ m_AA = value; }
  		}
  		public AosWeaponAttribute AWA
  		{
  			get{ return m_AWA; }
  			set{ m_AWA = value; }
  		}
  		public AosArmorAttribute AAA
  		{
  			get{ return m_AAA; }
  			set{ m_AAA = value; }
  		}
  		public Type Monster
  		{
  			get{ return m_type; }
  			set{ m_type = value; }
  		}
  		public int AmountToKill
  		{
  			get{ return m_amount; }
  			set{ m_amount = value; }
  		}
  		public int AmountKilled
  		{
  			get{ return m_killed; }
  			set
  			{
  				m_killed = value;
  
  				if ( m_killed >= AmountToKill )
  				{
  					m_killed = AmountToKill;
  					Completed = true;
  				}
  			}
  		}
  
  		public MC()
  		{
  		}
  
  		public string GetAttr()
  		{
  			string name = "";
  			string str = "";
  
  			if ( AA >= (AosAttribute)1 )
  				str = AA.ToString();
  			else if ( AWA >= (AosWeaponAttribute)1 )
  				str = AWA.ToString();
  			else if ( AAA >= (AosArmorAttribute)1 )
  				str = AAA.ToString();
  
  			int capsbreak = str.IndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),1);
  
  			if( capsbreak > -1 )
  			{
  				string secondhalf = str.Substring( capsbreak );
   				string firsthalf = str.Substring(0, capsbreak );
  
  				capsbreak = secondhalf.IndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),1);
  				if( capsbreak > -1 )
  				{
  					string secondhalf2 = secondhalf.Substring( capsbreak );
   					string firsthalf2 = secondhalf.Substring(0, capsbreak );
  
  					name = firsthalf+" "+firsthalf2+" "+secondhalf2;
  				}
  				else
  					name = firsthalf+" "+secondhalf;
  			}
  			else
  				name = str;
  
  			return name;
  		}
  
  		public bool CheckAttribute( Item item, AosAttribute attr )
  		{
  			if ( item is BaseWeapon )
  			{
  				BaseWeapon b = (BaseWeapon)item;
  
  				if ( attr == AosAttribute.WeaponDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.DefendChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusDex && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.EnhancePotions && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.CastRecovery && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.CastSpeed && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.AttackChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusHits && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusInt && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.LowerManaCost && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.LowerRegCost && b.Attributes[attr] < 20 )
  					return true;
  				else if ( attr == AosAttribute.Luck && b.GetLuckBonus()+b.Attributes[attr] < 100 )
  					return true;
  				else if ( attr == AosAttribute.BonusMana && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.RegenMana && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.ReflectPhysical && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.RegenStam && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.RegenHits && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.SpellDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusStam && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusStr && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.WeaponSpeed && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.SpellChanneling && b.Attributes[attr] < 1 )
  					return true;
  			}
  			else if ( item is BaseArmor )
  			{
  				BaseArmor b = (BaseArmor)item;
  
  				if ( attr == AosAttribute.WeaponDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.DefendChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusDex && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.EnhancePotions && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.CastRecovery && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.CastSpeed && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.AttackChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusHits && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusInt && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.LowerManaCost && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.LowerRegCost && b.Attributes[attr] < 20 )
  					return true;
  				else if ( attr == AosAttribute.Luck && b.GetLuckBonus()+b.Attributes[attr] < 100 )
  					return true;
  				else if ( attr == AosAttribute.BonusMana && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.RegenMana && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.ReflectPhysical && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.RegenStam && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.RegenHits && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.SpellDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusStam && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusStr && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.WeaponSpeed && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.SpellChanneling && b.Attributes[attr] < 1 )
  					return true;
  			}
  			else if ( item is BaseJewel )
  			{
  				BaseJewel b = (BaseJewel)item;
  
  				if ( attr == AosAttribute.WeaponDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.DefendChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusDex && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.EnhancePotions && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.CastRecovery && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.CastSpeed && b.Attributes[attr] < 1 )
  					return true;
  				else if ( attr == AosAttribute.AttackChance && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusHits && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusInt && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.LowerManaCost && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.LowerRegCost && b.Attributes[attr] < 20 )
  					return true;
  				else if ( attr == AosAttribute.Luck && b.Attributes[attr] < 100 )
  					return true;
  				else if ( attr == AosAttribute.BonusMana && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.RegenMana && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.ReflectPhysical && b.Attributes[attr] < 30 )
  					return true;
  				else if ( attr == AosAttribute.RegenStam && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.RegenHits && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.SpellDamage && b.Attributes[attr] < 40 )
  					return true;
  				else if ( attr == AosAttribute.BonusStam && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.BonusStr && b.Attributes[attr] < 10 )
  					return true;
  				else if ( attr == AosAttribute.WeaponSpeed && b.Attributes[attr] < 15 )
  					return true;
  				else if ( attr == AosAttribute.SpellChanneling && b.Attributes[attr] < 1 )
  					return true;
  			}
  
  			return false;
  		}
  		public bool CheckAttribute( BaseWeapon b, AosWeaponAttribute attr )
  		{
  			if ( attr == AosWeaponAttribute.LowerStatReq && b.GetLowerStatReq() < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.SelfRepair && b.WeaponAttributes[attr] < 10 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitColdArea && b.WeaponAttributes[attr] < 60 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitDispel && b.WeaponAttributes[attr] < 100 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitEnergyArea && b.WeaponAttributes[attr] < 60 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitFireArea && b.WeaponAttributes[attr] < 60 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitFireball && b.WeaponAttributes[attr] < 50 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitHarm && b.WeaponAttributes[attr] < 50 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLeechHits && b.WeaponAttributes[attr] < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLightning && b.WeaponAttributes[attr] < 50 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLowerAttack && b.WeaponAttributes[attr] < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLowerDefend && b.WeaponAttributes[attr] < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitMagicArrow && b.WeaponAttributes[attr] < 50 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLeechMana && b.WeaponAttributes[attr] < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitPhysicalArea && b.WeaponAttributes[attr] < 60 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitPoisonArea && b.WeaponAttributes[attr] < 60 )
  				return true;
  			else if ( attr == AosWeaponAttribute.HitLeechStam && b.WeaponAttributes[attr] < 40 )
  				return true;
  			else if ( attr == AosWeaponAttribute.DurabilityBonus && b.WeaponAttributes[attr] < 255 )
  				return true;
  
  
  			return false;
  		}
  		public bool CheckAttribute( BaseArmor b, AosArmorAttribute attr )
  		{
  			if ( attr == AosArmorAttribute.LowerStatReq && b.GetLowerStatReq() < 40 )
  				return true;
  			else if ( attr == AosArmorAttribute.SelfRepair && b.ArmorAttributes[attr] < 10 )
  				return true;
  			else if ( attr == AosArmorAttribute.MageArmor && b.ArmorAttributes[attr] < 1 )
  				return true;
  			else if ( attr == AosArmorAttribute.DurabilityBonus && b.ArmorAttributes[attr] < 255 )
  				return true;
  
  			return false;
  		}
  
  		public bool ApplyAttribute( Mobile from, Item item )
  		{
  			if ( item is BaseWeapon )
  			{
  				BaseWeapon b = (BaseWeapon)item;
  
  		/*		if ( b.ArtifactRarity > 0 && !(b.CanGainLevels) )
  				{
  					from.SendMessage( "You cannot apply attributes to artifacts that cannot level." );
  					return false;
  				}
  				else*/ if ( AA > 0 && CheckAttribute( b, AA ) )
  				{
  					b.Attributes[AA] += 1;
  					return true;
  				}
  				else if ( AWA > 0 && CheckAttribute( b, AWA ) )
  				{
  					b.WeaponAttributes[AWA] += 1;
  					return true;
  				}
  				else if ( AAA == AosArmorAttribute.LowerStatReq && CheckAttribute( b, AosWeaponAttribute.LowerStatReq ) )
  				{
  					b.WeaponAttributes.LowerStatReq += 1;
  					return true;
  				}
  				else if ( AAA == AosArmorAttribute.SelfRepair && CheckAttribute( b, AosWeaponAttribute.SelfRepair ) )
  				{
  					b.WeaponAttributes.SelfRepair += 1;
  					return true;
  				}
  				else if ( AAA == AosArmorAttribute.DurabilityBonus && CheckAttribute( b, AosWeaponAttribute.DurabilityBonus ) )
  				{
  					b.WeaponAttributes.DurabilityBonus += 1;
  					return true;
  				}
  				else
  					from.SendMessage( "You cannot apply this attribute to that item." );
  			}
  			else if ( item is BaseArmor )
  			{
  				BaseArmor b = (BaseArmor)item;
  
  			/*	if ( b.ArtifactRarity > 0 && !(b.CanGainLevels))
  				{
  					from.SendMessage( "You cannot apply attributes to artifacts that cannot level." );
  					return false;
  				}
  				else*/ if ( AA > 0 && AA != AosAttribute.SpellChanneling )
  				{
  					b.Attributes[AA] += 1;
  					return true;
  				}
  				else if ( AAA > 0 && CheckAttribute( b, AAA ) )
  				{
  					b.ArmorAttributes[AAA] += 1;
  					return true;
  				}
  				else if ( AWA == AosWeaponAttribute.LowerStatReq && CheckAttribute( b, AosArmorAttribute.LowerStatReq ) )
  				{
  					b.ArmorAttributes.LowerStatReq += 1;
  					return true;
  				}
  				else if ( AWA == AosWeaponAttribute.SelfRepair && CheckAttribute( b, AosArmorAttribute.SelfRepair ) )
  				{
  					b.ArmorAttributes.SelfRepair += 1;
  					return true;
  				}
  				else if ( AWA == AosWeaponAttribute.DurabilityBonus && CheckAttribute( b, AosArmorAttribute.DurabilityBonus ) )
  				{
  					b.ArmorAttributes.DurabilityBonus += 1;
  					return true;
  				}
  				else
  					from.SendMessage( "You cannot apply this attribute to that item." );
  			}
  			else if ( item is BaseJewel )
  			{
  				BaseJewel b = (BaseJewel)item;
  
  			/*	if ( b.ArtifactRarity > 0 && !(b.CanGainLevels)  )
  				{
  					from.SendMessage( "You cannot apply attributes to artifacts that cannot level." );
  					return false;
  				}
  				else */ if ( AA > 0 && CheckAttribute( b, AA ) && AA != AosAttribute.SpellChanneling )
  				{
  					b.Attributes[AA] += 1;
  					return true;
  				}
  				else
  					from.SendMessage( "You cannot apply this attribute to that item." );
  			}
  			else
  				from.SendMessage( "That does not have attributes." );
  			return false;
  		}
  
  		public MC( GenericReader reader )
  		{
  			int version = reader.ReadInt();
  
  			switch ( version )
  			{
  				case 0:
  				{
  					m_CompletedBy = reader.ReadMobile();
  					m_Completed = reader.ReadBool();
  					if ( reader.ReadBool() )
  						m_type = ScriptCompiler.FindTypeByName( reader.ReadString() );
  
  					m_amount = reader.ReadInt();
  					m_killed = reader.ReadInt();
  					AA = (AosAttribute)reader.ReadInt();
  					AWA = (AosWeaponAttribute)reader.ReadInt();
  					AAA = (AosArmorAttribute)reader.ReadInt();
  
  					if ( m_amount == m_killed )
  						m_Completed = true;
  
  					break;
  				}
  			}
  		}
  
  		public void Serialize( GenericWriter writer )
  		{
  			writer.Write( (int) 0 ); // version
  
  			writer.Write( (Mobile) m_CompletedBy );
  			writer.Write( (bool) m_Completed );
  			if ( m_type != null )
  			{
  				writer.Write( true );
  				if ( m_type.DeclaringType == null )
  					writer.Write( m_type.Name );
  				else
  					writer.Write( m_type.FullName );
  			}
  			else
  				writer.Write( false );
  			writer.Write( m_amount );
  			writer.Write( m_killed );
  			writer.Write( (int)m_AA );
  			writer.Write( (int)m_AWA );
  			writer.Write( (int)m_AAA );
  		}
  	}
  
     	public class MCBook: Item, ICraftable
     	{ 
  		private ArrayList m_Entries;
  
  		private Mobile m_LastUser;
  		private Mobile m_Crafter;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile Crafter
  		{
  			get
  			{
  				return m_Crafter;
  			}
  			set
  			{
  				m_Crafter = value;
  				InvalidateProperties();
  			}
  		}
  
  		//oncraft 
  		    public  int OnCraft(int quality, bool makersMark, Mobile from, Server.Engines.Craft.CraftSystem craftSystem, Type typeRes, ITool tool, Server.Engines.Craft.CraftItem craftItem, int resHue)
          {
              if (makersMark)
                  Crafter = from;
  
              //Quality = (BookQuality)(quality - 1);
  
        //      MaxCharges = 100;
  
              return quality;
          }
  
  		
  		
  		
  		public ArrayList Entries{ get{ return m_Entries; } }
  
  		[Constructable]
  		public MCBook() : base( Core.AOS ? 0x22C5 : 0xEFA )
  		{
  			Weight = 1.0;
  			LootType = LootType.Blessed;
  			Name = "Monster Contract Book";
  			Hue = 18;
  
  			Layer = Layer.OneHanded;
  
  			m_Entries = new ArrayList();
  		}
  
  		public int CountEntryType( string m )
  		{
  			Type t = ScriptCompiler.FindTypeByName( m );
  			return CountEntryType( t );
  		}
  
  		public int CountEntryType( Type m )
  		{
  			int count = 0;
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				MC mc = (MC)Entries[i];
  				if ( mc.Monster == m )
  					count++;
  			}
  
  			return count;
  		}
  
  		public int CountEntryType( AosAttribute a )
  		{
  			int count = 0;
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				MC mc = (MC)Entries[i];
  				if ( mc.AA == a )
  					count++;
  			}
  
  			return count;
  		}
  
  		public int CountEntryType( AosWeaponAttribute a )
  		{
  			int count = 0;
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				MC mc = (MC)Entries[i];
  				if ( mc.AWA == a )
  					count++;
  				else if ( a == AosWeaponAttribute.SelfRepair && mc.AAA == AosArmorAttribute.SelfRepair )
  					count++;
  				else if ( a == AosWeaponAttribute.LowerStatReq && mc.AAA == AosArmorAttribute.LowerStatReq )
  					count++;
  				else if ( a == AosWeaponAttribute.DurabilityBonus && mc.AAA == AosArmorAttribute.DurabilityBonus )
  					count++;
  			}
  
  			return count;
  		}
  
  		public int CountEntryType( AosArmorAttribute a )
  		{
  			int count = 0;
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				MC mc = (MC)Entries[i];
  				if ( mc.AAA == a )
  					count++;
  				else if ( a == AosArmorAttribute.SelfRepair && mc.AWA == AosWeaponAttribute.SelfRepair )
  					count++;
  				else if ( a == AosArmorAttribute.LowerStatReq && mc.AWA == AosWeaponAttribute.LowerStatReq )
  					count++;
  				else if ( a == AosArmorAttribute.DurabilityBonus && mc.AWA == AosWeaponAttribute.DurabilityBonus )
  					count++;
  			}
  
  			return count;
  		}
  
  		public int CountEntryType( MC mc, bool showcompleted )
  		{
  			int count = 0;
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				MC smc = (MC)Entries[i];
  				if ( smc.Completed == showcompleted && mc.AA == smc.AA && mc.AAA == smc.AAA && mc.AWA == smc.AWA )
  					count++;
  				else if ( smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.SelfRepair && smc.AWA == AosWeaponAttribute.SelfRepair) || (smc.AAA == AosArmorAttribute.SelfRepair && mc.AWA == AosWeaponAttribute.SelfRepair)) )
  					count++;
  				else if ( smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.LowerStatReq && smc.AWA == AosWeaponAttribute.LowerStatReq) || (smc.AAA == AosArmorAttribute.LowerStatReq && mc.AWA == AosWeaponAttribute.LowerStatReq)) )
  					count++;
  				else if ( smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.DurabilityBonus && smc.AWA == AosWeaponAttribute.DurabilityBonus) || (smc.AAA == AosArmorAttribute.DurabilityBonus && mc.AWA == AosWeaponAttribute.DurabilityBonus)) )
  					count++;
  			}
  
  			return count;
  		}
  
  		public static bool HasListed( ArrayList list, bool showcompleted, MC mc, int count )
  		{
  			bool hasit = false;
  			for( int i = 0; i < list.Count; i++ )
  			{
  				MC smc = (MC)list[i];
  				if ( i < count && smc.Completed == showcompleted && mc.AA == smc.AA && mc.AAA == smc.AAA && mc.AWA == smc.AWA )
  					hasit = true;
  				else if ( i < count && smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.SelfRepair && smc.AWA == AosWeaponAttribute.SelfRepair) || (smc.AAA == AosArmorAttribute.SelfRepair && mc.AWA == AosWeaponAttribute.SelfRepair)) )
  					count++;
  				else if ( i < count && smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.LowerStatReq && smc.AWA == AosWeaponAttribute.LowerStatReq) || (smc.AAA == AosArmorAttribute.LowerStatReq && mc.AWA == AosWeaponAttribute.LowerStatReq)) )
  					count++;
  				else if ( i < count && smc.Completed == showcompleted && ((mc.AAA == AosArmorAttribute.DurabilityBonus && smc.AWA == AosWeaponAttribute.DurabilityBonus) || (smc.AAA == AosArmorAttribute.DurabilityBonus && mc.AWA == AosWeaponAttribute.DurabilityBonus)) )
  					count++;
  			}
  
  			return hasit;
  		}
  
  		public static void SortLevel( ArrayList list, bool showcompleted, ref ArrayList entries )
  		{
  			ArrayList e = new ArrayList();
  
  			for( int i = 0; i < list.Count; i++ )
  			{
  				MC mc = (MC)list[i];
  				if ( mc.Completed == showcompleted )
  					e.Add( mc );
  			}
  			entries = new ArrayList( e );
  		}
  
  		public void DropMC( Mobile from, MC mc )
  		{
  			if ( m_Entries.Contains( mc ) )
  			{
  				m_Entries.Remove( mc );
  				InvalidateProperties();
  
  				MonsterContract newMC = new MonsterContract();
  
  				newMC.Monster = mc.Monster;
  				newMC.AmountToKill = mc.AmountToKill;
  				newMC.AmountKilled = mc.AmountKilled;
  				newMC.AA = mc.AA;
  				newMC.AAA = mc.AAA;
  				newMC.AWA = mc.AWA;
  				newMC.Completed = mc.Completed;
  				newMC.CompletedBy = mc.CompletedBy;
  
  				string s;
  				if ( newMC.Monster.DeclaringType == null )
  					s = newMC.Monster.Name;
  				else
  					s = newMC.Monster.FullName;
  
  				int capsbreak = s.IndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),1);
  
  				if( capsbreak > -1 )
  				{
  					string secondhalf = s.Substring( capsbreak );
   					string firsthalf = s.Substring(0, capsbreak );
  
  					capsbreak = secondhalf.IndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),1);
  					if( capsbreak > -1 )
  					{
  						string secondhalf2 = secondhalf.Substring( capsbreak );
   						string firsthalf2 = secondhalf.Substring(0, capsbreak );
  
  						newMC.Name = "a Contract: "+newMC.AmountToKill+" "+firsthalf+" "+firsthalf2+" "+secondhalf2+"s";
  					}
  					else
  						newMC.Name = "a Contract: "+newMC.AmountToKill+" "+firsthalf+" "+secondhalf+"s";
  				}
  				else
  				newMC.Name = "a Contract: "+newMC.AmountToKill+" "+s+"s";
  
  				from.AddToBackpack( newMC );
  			}
  			else
  			{
  				from.SendMessage("That contract is no longer in the book.");
  			}
  		}
  
  		public override void GetProperties( ObjectPropertyList list )
  		{
  			base.GetProperties( list );
  
  			if ( Crafter != null )
  				list.Add( 1050043, Crafter.Name ); // crafted by ~1_NAME~
  
  			list.Add( 1060663, "Contracts\t{0}", Entries.Count );
  
  			int com = 0;
  			int inc = 0;
  
  			for( int i = 0; i < Entries.Count; i++ )
  			{
  				if ( ((MC)Entries[i]).Completed )
  					com++;
  				else
  					inc++;
  			}
  
  			list.Add( 1060660, "Completed Contracts\t{0}", com );
  			list.Add( 1060659, "Incompleted Contracts\t{0}", inc );
  		}
  
  		public override void OnDoubleClick( Mobile from )
  		{
  			if ( from.InRange( GetWorldLocation(), 1 ) )
  			{
  				if ( m_LastUser != from && m_LastUser != null )
  				{
  					m_LastUser.CloseGump( typeof( MCBookGump ) );
  					m_LastUser.CloseGump( typeof( MCGump ) );
  					m_LastUser.CloseGump( typeof( MCIndGump ) );
  					m_LastUser.CloseGump( typeof( MCSearchGump ) );
  					m_LastUser.CloseGump( typeof( MCSearchedForGump ) );
  					m_LastUser.CloseGump( typeof( MonsterContractGump ) );
  				}
  				m_LastUser = from;
  				from.CloseGump( typeof( MCBookGump ) );
  				from.CloseGump( typeof( MCGump ) );
  				from.CloseGump( typeof( MCIndGump ) );
  				from.CloseGump( typeof( MCSearchGump ) );
  				from.CloseGump( typeof( MCSearchedForGump ) );
  				from.CloseGump( typeof( MonsterContractGump ) );
  				from.SendGump( new MCBookGump( from, this, false ) );
  			}
  		}
  
  		public override bool OnDragDrop( Mobile from, Item dropped )
  		{
  			if ( dropped is MonsterContract )
  			{
  				MonsterContract mc = (MonsterContract)dropped;
  
  				if ( mc.LastUser != from && mc.LastUser != null )
  				{
  					mc.LastUser.CloseGump( typeof( MCBookGump ) );
  					mc.LastUser.CloseGump( typeof( MCGump ) );
  					mc.LastUser.CloseGump( typeof( MCIndGump ) );
  					mc.LastUser.CloseGump( typeof( MCSearchGump ) );
  					mc.LastUser.CloseGump( typeof( MCSearchedForGump ) );
  					mc.LastUser.CloseGump( typeof( MonsterContractGump ) );
  				}
  				from.CloseGump( typeof( MCBookGump ) );
  				from.CloseGump( typeof( MCGump ) );
  				from.CloseGump( typeof( MCIndGump ) );
  				from.CloseGump( typeof( MCSearchGump ) );
  				from.CloseGump( typeof( MCSearchedForGump ) );
  				from.CloseGump( typeof( MonsterContractGump ) );
  
  				MC m = new MC();
  
  				m.Monster = mc.Monster;
  				m.AmountToKill = mc.AmountToKill;
  				m.AmountKilled = mc.AmountKilled;
  				m.AA = mc.AA;
  				m.AAA = mc.AAA;
  				m.AWA = mc.AWA;
  				m.Completed = mc.Completed;
  				m.CompletedBy = mc.CompletedBy;
  
  				m_Entries.Add( m );
  				InvalidateProperties();
  
  				dropped.Delete();
  
  				//from.Send( new PlaySound( 0x42, GetWorldLocation() ) );
  
  				from.SendMessage( "You drop the contract into the book." );
  
  				return true;
  			}
  
  			return false;
  		}
  
  		#region ICraftable Members
  
  		public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
  		{
  			if ( quality == 2 )
  				Crafter = from;
  
  			return quality;
  		}
  
  		#endregion
  
              	public MCBook( Serial serial ) : base ( serial ) 
              	{             
             	} 
  
             	public override void Serialize( GenericWriter writer ) 
             	{ 
                		base.Serialize( writer ); 
  
  			writer.Write( (int) 0 );
  
  			writer.Write( m_Entries.Count );
  
  			for ( int i = 0; i < m_Entries.Count; ++i )
  				((MC)m_Entries[i]).Serialize( writer );
  
  			writer.Write( m_Crafter );
             	} 
              
             	public override void Deserialize( GenericReader reader ) 
             	{ 
                		base.Deserialize( reader ); 
                		int version = reader.ReadInt(); 
  
  			switch ( version )
  			{
  				case 0:
  				{
  					int count = reader.ReadInt();
  
  					m_Entries = new ArrayList( count );
  
  					for ( int i = 0; i < count; ++i )
  						m_Entries.Add( new MC( reader ) );
  
  					m_Crafter = reader.ReadMobile();
  
  					break;
  				}
  			}
             	} 
          }
  	public class MCBookGump : Gump
  	{
  		private Mobile m_Mobile;
  		private MCBook m_Book;
  		private bool m_ShowCompleted;
  
  		public MCBookGump( Mobile mobile, MCBook book, bool showcompleted ) : base( 25, 50 )
  		{
  			m_Mobile = mobile;
  			m_Book = book;
  			m_ShowCompleted = showcompleted;
  
  			AddPage( 0 );
  
  			AddBackground( 0, 0, 230, 180, 0x2436 );
  
  			if ( showcompleted )
  				AddLabel( 30, 20, 1152, "Completed Monster Contracts" );
  			else
  				AddLabel( 30, 20, 1152, "Incomplete Monster Contracts" );
  
  			AddButton( 10, 40, 2103, 2104, 1, GumpButtonType.Reply, 0 );
  			AddLabel( 25, 37, 1152, "Monster Contracts: "+book.Entries.Count );
  
  			AddButton( 20, 65, 2103, 2104, 2, GumpButtonType.Reply, 0 );
  			if ( showcompleted )
  				AddLabel( 35, 62, 1152, "Incomplete Contracts" );
  			else
  				AddLabel( 35, 62, 1152, "Completed Contracts" );
  
  			AddButton( 20, 85, 2061, 2062, 3, GumpButtonType.Reply, 0 );
  			AddLabel( 34, 83, 1152, @"Claim Corpse" );
  
  			AddButton( 20, 105, 2103, 2104, 4, GumpButtonType.Reply, 0 );
  			AddLabel( 35, 102, 1152, "Collect All Contracts" );
  
  			AddButton( 20, 125, 2103, 2104, 5, GumpButtonType.Reply, 0 );
  			AddLabel( 35, 122, 1152, "Search" );
  
  			AddButton( 20, 150, 2103, 2104, 0, GumpButtonType.Reply, 0 );
  			AddLabel( 35, 147, 1152, "Close" );
  		}
  
  		public override void OnResponse( NetState state, RelayInfo info )
  		{
  			Mobile from = state.Mobile; 
  
  			if ( from == null || m_Book == null )
  				return;
  
  			if ( info.ButtonID == 0 )
  			{
  				from.SendMessage( "Closed." );
  			}
  			if ( info.ButtonID == 1 )
  			{
  				from.SendGump( new MCGump( from, m_Book, m_ShowCompleted ) );
  			}
  			if ( info.ButtonID == 2 )
  			{
  				from.SendGump( new MCBookGump( from, m_Book, !m_ShowCompleted ) );
  			}
  			if ( info.ButtonID == 3 )
  			{
  				from.SendMessage( "Please choose the corpse to add." );
  				from.Target = new MonsterCorpseTarget( m_Book );
  			}
  			if ( info.ButtonID == 4 )
  			{
  				int collected = 0;
  
  				Item[] list = from.Backpack.FindItemsByType( typeof( MonsterContract ) );
  
  				for( int i = 0; i < list.Length; i++ )
  				{
  					Item item = list[i];
  
  					if ( item is MonsterContract )
  					{
  						MonsterContract mc = (MonsterContract)item;
  
  						MC m = new MC();
  
  						m.Monster = mc.Monster;
  						m.AmountToKill = mc.AmountToKill;
  						m.AmountKilled = mc.AmountKilled;
  						m.AA = mc.AA;
  						m.AAA = mc.AAA;
  						m.AWA = mc.AWA;
  						m.Completed = mc.Completed;
  						m.CompletedBy = mc.CompletedBy;
  
  						m_Book.Entries.Add( m );
  						collected++;
  
  						mc.Delete();
  					}
  				}
  				m_Book.InvalidateProperties();
  
  				from.SendMessage( "{0} contracts were collected in the book.", collected );
  			}
  			if ( info.ButtonID == 5 )
  			{
  				from.SendGump( new MCSearchGump( m_Book ) );
  			}
  		}
  
  		private class MonsterCorpseTarget : Target
  		{
  			private MCBook book;
  			
  			public MonsterCorpseTarget( MCBook mbook ) : base( -1, true, TargetFlags.None )
  			{
  				book = mbook;
  			}
  			
  			protected override void OnTarget( Mobile from, object o )
  			{
  				if ( o is Corpse )
  				{
  					Corpse MCcorpse = (Corpse)o;
  					
  					if ( MCcorpse.Channeled )
  					{
  						from.SendMessage("This corpse has already been claimed!");
  						return;
  					}
  					if ( MCcorpse.Killer == from || (MCcorpse.Killer is BaseCreature && ((BaseCreature)MCcorpse.Killer).ControlMaster == from) )
  					{
  						bool done = false;
  						for( int i = 0; i < book.Entries.Count; i++ )
  						{
  							if ( done )
  								continue;
  
  							MC mc = (MC)book.Entries[i];
  
  							if ( mc.Monster == MCcorpse.Owner.GetType() )
  							{
  								done = true;
  								mc.AmountKilled += 1;
  								MCcorpse.Channeled = true;
  								MCcorpse.Hue = 15;
  
  								if ( mc.AmountKilled >= mc.AmountToKill )
  									mc.CompletedBy = from;
  							}
  						}
  						if ( !done )
  							from.SendMessage("There are no contracts in this book that need this mosnter's corpse.");
  					}
  					else
  						from.SendMessage("You cannot claim someone elses work!");
  				}
  				else
  					from.SendMessage("That is not a corpse.");
  			}
  		}
  	}
  	public class MCGump : Gump
  	{
  		private Mobile m_Mobile;
  		private MCBook m_Book;
  		private bool m_ShowCompleted;
  		private int m_Page;
  
  		public MCGump( Mobile mobile, MCBook book, bool showcompleted ) : this( mobile, book, showcompleted, 1 )
  		{
  		}
  		public MCGump( Mobile mobile, MCBook book, bool showcompleted, int page ) : base( 25, 50 )
  		{
  			m_Mobile = mobile;
  			m_Book = book;
  			m_ShowCompleted = showcompleted;
  			m_Page = page;
  
  			if ( m_Book == null )
  				return;
  
  			AddPage( 0 );
  
  			AddBackground( 0, 0, 700, 560, 0x2436 );
  
  			if ( showcompleted )
  				AddLabel( 30, 20, 1152, "Completed Contracts" );
  			else
  				AddLabel( 30, 20, 1152, "Incomplete Contracts" );
  
  			AddButton( 20, 465, 2103, 2104, 0, GumpButtonType.Reply, 0 );
  			AddLabel( 35, 462, 1152, "Close" );
  
  			ArrayList list = null;
  
  			MCBook.SortLevel( book.Entries, showcompleted, ref list );
  
  			int totalpages = (int)((list.Count/20)+( (list.Count % 20 == 0) ? 0 : 1 ));
  
gt: 			AddLabel( 450, 20, 1152, "Page "+page+"/"+totalpages );