context: using System;
  using System.Collections.Generic;
  using Server;
  using Server.ContextMenus;
  using Server.Gumps;
  using Server.Items;
  using Server.Network;
  using Server.Targeting;
  
  namespace Server.Mobiles
  {
  	public class AnimalTrainer : BaseVendor
  	{
  		private List<SBInfo> m_SBInfos = new List<SBInfo>();
  		protected override List<SBInfo> SBInfos{ get { return m_SBInfos; } }
  
  		[Constructable]
  		public AnimalTrainer() : base( "the animal trainer" )
  		{
  			SetSkill( SkillName.AnimalLore, 64.0, 100.0 );
  			SetSkill( SkillName.AnimalTaming, 90.0, 100.0 );
  			SetSkill( SkillName.Veterinary, 65.0, 88.0 );
  		}
  
  		public override void InitSBInfo()
  		{
  			m_SBInfos.Add( new SBAnimalTrainer() );
  		}
  
  		public override VendorShoeType ShoeType
  		{
  			get{ return Female ? VendorShoeType.ThighBoots : VendorShoeType.Boots; }
  		}
  
  		public override int GetShoeHue()
  		{
  			return 0;
  		}
  
  		public override void InitOutfit()
  		{
  			base.InitOutfit();
  
  			AddItem( Utility.RandomBool() ? (Item)new QuarterStaff() : (Item)new ShepherdsCrook() );
  		}
  
  		private class StableEntry : ContextMenuEntry
  		{
  			private AnimalTrainer m_Trainer;
  			private Mobile m_From;
  
  			public StableEntry( AnimalTrainer trainer, Mobile from ) : base( 6126, 12 )
  			{
  				m_Trainer = trainer;
  				m_From = from;
  			}
  
  			public override void OnClick()
  			{
  				m_Trainer.BeginStable( m_From );
  			}
  		}
  
  		private class ClaimListGump : Gump
  		{
  			private AnimalTrainer m_Trainer;
  			private Mobile m_From;
  			private List<BaseCreature> m_List;
  
  			public ClaimListGump( AnimalTrainer trainer, Mobile from, List<BaseCreature> list ) : base( 50, 50 )
  			{
  				m_Trainer = trainer;
  				m_From = from;
  				m_List = list;
  
  				from.CloseGump( typeof( ClaimListGump ) );
  
  				AddPage( 0 );
  
  				AddBackground( 0, 0, 325, 50 + (list.Count * 20), 9250 );
  				AddAlphaRegion( 5, 5, 315, 40 + (list.Count * 20) );
  
  				AddHtml( 15, 15, 275, 20, "<BASEFONT COLOR=#FFFFFF>Select a pet to retrieve from the stables:</BASEFONT>", false, false );
  
  				for ( int i = 0; i < list.Count; ++i )
  				{
  					BaseCreature pet = list[i];
  
  					if ( pet == null || pet.Deleted )
  						continue;
  
  					AddButton( 15, 39 + (i * 20), 10006, 10006, i + 1, GumpButtonType.Reply, 0 );
  					AddHtml( 32, 35 + (i * 20), 275, 18, String.Format( "<BASEFONT COLOR=#C0C0EE>{0}</BASEFONT>", pet.Name ), false, false );
  				}
  			}
  
  			public override void OnResponse( NetState sender, RelayInfo info )
  			{
  				int index = info.ButtonID - 1;
  
  				if ( index >= 0 && index < m_List.Count )
  					m_Trainer.EndClaimList( m_From, m_List[index] );
  			}
  		}
  
  		private class ClaimAllEntry : ContextMenuEntry
  		{
  			private AnimalTrainer m_Trainer;
  			private Mobile m_From;
  
  			public ClaimAllEntry( AnimalTrainer trainer, Mobile from ) : base( 6127, 12 )
  			{
  				m_Trainer = trainer;
  				m_From = from;
  			}
  
  			public override void OnClick()
  			{
  				m_Trainer.Claim( m_From );
  			}
  		}
  
  		public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
  		{
  			if ( from.Alive )
  			{
  				list.Add( new StableEntry( this, from ) );
  
  				if ( from.Stabled.Count > 0 )
  					list.Add( new ClaimAllEntry( this, from ) );
  			}
  
  			base.AddCustomContextEntries( from, list );
  		}
  
  		public static int GetMaxStabled( Mobile from )
  		{
  			double taming = from.Skills[SkillName.AnimalTaming].Value;
  			double anlore = from.Skills[SkillName.AnimalLore].Value;
  			double vetern = from.Skills[SkillName.Veterinary].Value;
              double tinkering = from.Skills[SkillName.Tinkering].Value;
  			double sklsum = taming + anlore + vetern;
  
  			int max = 5;
  			if ( taming >= 100.0 )
  				max += (int)((taming - 90.0) / 10);
  
  			if ( anlore >= 100.0 )
  				max += (int)((anlore - 90.0) / 10);
  
  			if ( vetern >= 100.0 )
  				max += (int)((vetern - 90.0) / 10);
  
              if (tinkering >= 100.0)
              {
                  max += (int)((tinkering - 90.0) / 3);
              }
  
              return max;
  		}
  
  		private class StableTarget : Target
  		{
  			private AnimalTrainer m_Trainer;
  
  			public StableTarget( AnimalTrainer trainer ) : base( 12, false, TargetFlags.None )
  			{
  				m_Trainer = trainer;
  			}
  
  			protected override void OnTarget( Mobile from, object targeted )
  			{
  				if ( targeted is BaseCreature )
  					m_Trainer.EndStable( from, (BaseCreature)targeted );
  				else if ( targeted == from )
  					m_Trainer.SayTo( from, 502672 ); // HA HA HA! Sorry, I am not an inn.
  				else
  					m_Trainer.SayTo( from, 1048053 ); // You can't stable that!
  			}
  		}
  
  		private void CloseClaimList( Mobile from )
  		{
  			from.CloseGump( typeof( ClaimListGump ) );
  		}
  
  		public void BeginClaimList( Mobile from )
  		{
  			if ( Deleted || !from.CheckAlive() )
  				return;
  
  			List<BaseCreature> list = new List<BaseCreature>();
  
  			for ( int i = 0; i < from.Stabled.Count; ++i )
  			{
  				BaseCreature pet = from.Stabled[i] as BaseCreature;
  
  				if ( pet == null || pet.Deleted )
  				{
  					pet.IsStabled = false;
  					pet.StabledBy = null;
  					from.Stabled.RemoveAt( i );
  					--i;
  					continue;
  				}
  
  				list.Add( pet );
  			}
  
  			if ( list.Count > 0 )
  				from.SendGump( new ClaimListGump( this, from, list ) );
  			else
  				SayTo( from, 502671 ); // But I have no animals stabled with me at the moment!
  		}
  
  		public void EndClaimList( Mobile from, BaseCreature pet )
  		{
  			if ( pet == null || pet.Deleted || from.Map != this.Map || !from.Stabled.Contains( pet ) || !from.CheckAlive() )
  				return;
  
  			if ( !from.InRange( this, 14 ) )
  			{
  				from.SendLocalizedMessage( 500446 ); // That is too far away.
  				return;
  			}
  
  			if ( CanClaim( from, pet ) )
  			{
  				DoClaim( from, pet );
  
  				from.Stabled.Remove( pet );
  
  				if ( from is PlayerMobile )
  					((PlayerMobile)from).AutoStabled.Remove( pet );
  			}
  			else
  			{
  				SayTo( from, 1049612, pet.Name ); // ~1_NAME~ remained in the stables because you have too many followers.
  			}
  		}
  
  		public void BeginStable( Mobile from )
  		{
  			if ( Deleted || !from.CheckAlive() )
  				return;
  
  			/* I charge 30 gold per pet for a real week's stable time.
  				* I will withdraw it from thy bank account.
  				* Which animal wouldst thou like to stable here?
  				*/
  			from.SendLocalizedMessage(1042558);
  
  			from.Target = new StableTarget( this );
  		}
  
  		public void EndStable( Mobile from, BaseCreature pet )
  		{
  			if ( Deleted || !from.CheckAlive() )
  				return;
  
  			if ( pet.Body.IsHuman )
  			{
  				SayTo( from, 502672 ); // HA HA HA! Sorry, I am not an inn.
  			}
  			else if ( !pet.Controlled )
  			{
  				SayTo( from, 1048053 ); // You can't stable that!
  			}
  			else if ( pet.ControlMaster != from )
  			{
  				SayTo( from, 1042562 ); // You do not own that pet!
  			}
  			else if ( pet.IsDeadPet )
  			{
  				SayTo( from, 1049668 ); // Living pets only, please.
  			}
  			else if ( pet.Summoned )
  			{
  				SayTo( from, 502673 ); // I can not stable summoned creatures.
  			}
  /*
  			else if ( pet.Allured )
  			{
  				SayTo( from, 1048053 ); // You can't stable that!
  			}
  */
  			else if ( (pet is PackLlama || pet is PackHorse || pet is Beetle) && (pet.Backpack != null && pet.Backpack.Items.Count > 0) )
  			{
  
gt: 				SayTo( from, 1042563 ); // You need to unload your pet.