using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Gumps;
using Server.Items;
using Server.Network;
using Server.Targeting;
using Xanthos.ShrinkSystem;
using Server.Engines.XmlSpawner2;

namespace Server.Mobiles
{
	public class AnimalTrainer : BaseVendor
	{
		private ArrayList m_SBInfos = new ArrayList();
		protected override ArrayList 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 );
			}
		}
		
		//sell pet
		private class PetBuyEntry : ContextMenuEntry
		{
			private AnimalTrainer m_Trainer;
			private Mobile m_From;

			public PetBuyEntry( AnimalTrainer trainer, Mobile from ) : base( 6113, 12 )
			{
				m_Trainer = trainer;
				m_From = from;
			}

			public override void OnClick()
			{
				m_Trainer.SayTo( m_From, "Za ochocene monstrum dostanes body, za zvire zlataky" );
				m_From.Target = new BuyPetTarget( m_Trainer );
			}
		}
		
		private class BuyPetTarget : Target
		{
			private AnimalTrainer m_Trainer;

			public BuyPetTarget( AnimalTrainer trainer ) : base( 12, false, TargetFlags.None )
			{
				m_Trainer = trainer;
			}

			protected override void OnTarget( Mobile from, object targeted )
			{
				if ( from == null || m_Trainer == null || m_Trainer.Deleted )
					return;
            
            if ( targeted is BaseCreature )
					m_Trainer.SayTo( from, "Prosim, napred zvire shrinkni." );
				else if ( targeted == from )
					m_Trainer.SayTo( from, 502672 ); // HA HA HA! Sorry, I am not an inn.
				else if ( targeted is ShrinkItem )
				{
               ShrinkItem shr = ( ShrinkItem ) targeted;
               
               if ( shr.Owner != from )
                  m_Trainer.SayTo( from, "Toto neni tve zvire." );
               else if ( !( shr.ShrunkenPet is BaseCreature ) || shr.ShrunkenPet is Golem )
                  m_Trainer.SayTo( from, "Toto neni zvire." );
               if ( shr.ShrunkenPet is Xanthos.Interfaces.IEvoCreature )
                  m_Trainer.SayTo( from, "Nevykupuji evolution pety." );
               else
               {
                  BaseCreature bc = (BaseCreature) shr.ShrunkenPet;
                  int body = (int) ( bc.MinTameSkill + BaseInstrument.GetBaseDifficulty( (Mobile) bc ) );
                  
                  if ( bc.MinTameSkill < 95.2 )
                     body /= 2;
                  else
                     body += Utility.RandomMinMax( 30, 70 );
                     
                  if ( body < 6 ) body = 6;
                  
                  if ( bc.AI == AIType.AI_Melee || bc.AI == AIType.AI_Mage ) //utocici monstra
                  {
						   if (XmlAttach.FindAttachment(from, typeof(AnimalTrainerAttachment)) == null)
							  XmlAttach.AttachTo(from, new AnimalTrainerAttachment());
						
						   AnimalTrainerAttachment qatt = (AnimalTrainerAttachment)XmlAttach.FindAttachment(from,typeof(AnimalTrainerAttachment));
						   
						   if ( qatt == null )
						      return;
                        
                     qatt.Count += body;						   
						   m_Trainer.SayTo( from, "Do knihy clena cechu tameru ti bylo pripocteno {0} bodu.", body );
						   m_Trainer.SayTo( from, "Celkem jiz mas {0}.", qatt.Count );
						   shr.Delete();
                  }
                  else
                  {
                     from.AddToBackpack( new Gold( body ) );
                     m_Trainer.SayTo( from, "Zde je tva odmena, rovnych {0} zlatych.", body );
                     shr.Delete();
                     
						   //SOUTEZ START
                     /*if ( from is PlayerMobile )
                     {
                        PlayerMobile pm = ( PlayerMobile ) from;
                        if ( body > 30 ) body = 30;
                        
                        if ( pm != null && pm.NpcGuild == NpcGuild.RangersGuild )
                        {
                           if ( bc is Horse || bc is PackHorse || bc is PackLlama )
                           {
                              from.SendMessage( "Za toto zvire nejsou body do souteze" );
                           }
                           else
                           {
                              from.SendMessage( 0x35, "Do souteze lovcu zvere ziskavas {0} bodu!", body );
                              pm.Expy += body;
                           }
                        }
                     }	*/					   
						   //SOUTEZ END
                  }
               }
            }
				else
					m_Trainer.SayTo( from, 502672 ); // HA HA HA! Sorry, I am not an inn.
					
				from.Target = new BuyPetTarget( m_Trainer );
			}
		}
		//end sell pet
		
		//Plant Buy
		private class PlantBuyEntry : ContextMenuEntry
		{
			private AnimalTrainer m_Trainer;
			private Mobile m_From;

			public PlantBuyEntry( AnimalTrainer trainer, Mobile from ) : base( 6121, 12 )
			{
				m_Trainer = trainer;
				m_From = from;
			}

			public override void OnClick()
			{
				AnimalTrainerAttachment qatt = (AnimalTrainerAttachment)XmlAttach.FindAttachment(m_From,typeof(AnimalTrainerAttachment));
            
            if ( qatt == null )
               m_Trainer.SayTo( m_From, "Nemas zadne body v knize cechu tameru, nejdriv zkus prodat nekomu z nas nejake ochocene monstrum." );
//             else if ( qatt.Count < 2000 )
//                m_Trainer.SayTo( m_From, "Nemas dostatek bodu v knize cechu tameru, nejdriv zkus prodat nekomu z nas nejake ochocene monstrum." );
            else
               m_From.SendGump( new PlantBuyGump( m_From, m_Trainer ) );
			}
		}
		
		private class PlantBuyGump : Gump
		{
			private AnimalTrainer m_Trainer;
			private Mobile m_From;
			private AnimalTrainerAttachment m_Qatt;
			
			public PlantBuyGump( Mobile from, AnimalTrainer trainer ) : base( 100, 150 )
			{
				m_Trainer = trainer;
				m_From = from;				
				m_Qatt = (AnimalTrainerAttachment)XmlAttach.FindAttachment(from,typeof(AnimalTrainerAttachment));
				
				if ( m_Qatt == null )
				  return;
				
				this.Closable=true;
				this.Disposable=true;
				this.Dragable=true;
				this.Resizable=false;

    			AddPage(0);
    			AddBackground(0, 0, 325, 291, 5170);
    			AddItem(58, 62, 6365);
    			AddLabel(108, 57, 1152, @"Mandrake Plant - 1500 bodu");
    			AddLabel(108, 75, 0, @"+5str +5dex +5int +20hits");
    			AddItem(58, 111, 6380);
    			AddLabel(108, 114, 1152, @"Ginseng Plant - 2000 bodu");
    			AddLabel(108, 132, 0, @"+1 to all resistances");
    			AddItem(58, 180, 6373);
    			AddLabel(108, 174, 1152, @"Nightshade Plant - 4000 bodu");
    			AddLabel(108, 195, 0, @"+1 to base damage");
    			AddLabel(50, 26, 241, @"Nakup rostlin za body v cechu tameru");
    			AddButton(248, 235, 2074, 2075, (int)Buttons.Okay, GumpButtonType.Reply, 0);
    			AddButton(184, 235, 2071, 2072, (int)Buttons.Cancel, GumpButtonType.Reply, 0);
    			AddRadio(25, 65, 2151, 2153, false, (int)Buttons.Mandrake);
    			AddRadio(25, 121, 2151, 2153, false, (int)Buttons.Ginseng);
    			AddRadio(25, 180, 2151, 2153, false, (int)Buttons.Nightshade);
    			AddLabel(29, 236, 241, string.Format("Pocet bodu: {0}", m_Qatt.Count));
			}

			public enum Buttons
			{
    			Okay,
    			Cancel,
    			Mandrake,
    			Ginseng,
    			Nightshade,
			}

			public override void OnResponse(NetState sender, RelayInfo info)
			{
				Mobile from = sender.Mobile;
				
				if ( from == null || m_Trainer == null || m_Trainer.Deleted || m_Qatt == null )
					return;
					
				switch( info.ButtonID )
				{
					case (int)Buttons.Okay:
						{
							if (info.IsSwitched( (int)Buttons.Mandrake) )
							{
								if( info.Switches.Length == 1 )
								{
									if ( m_Qatt.Count >= 1500 )
									{
                              from.AddToBackpack( new MandrakePlant() );
                              m_Qatt.Count -= 1500;
                           }
                           else
                              m_Trainer.SayTo( from, "Na tento nakup nemas dost bodu." );
                        }
							}
							else if (info.IsSwitched( (int)Buttons.Ginseng) )
							{
								if( info.Switches.Length == 1 )
								{
									if ( m_Qatt.Count >= 2000 )
									{
                              from.AddToBackpack( new GinsengPlant() );
                              m_Qatt.Count -= 2000;
                           }
                           else
                              m_Trainer.SayTo( from, "Na tento nakup nemas dost bodu." );
                        }
							}
							else if (info.IsSwitched( (int)Buttons.Nightshade) )
							{
								if( info.Switches.Length == 1 )
								{
									if ( m_Qatt.Count >= 4000 )
									{
                              from.AddToBackpack( new NightshadePlant() );
                              m_Qatt.Count -= 4000;
                           }
                           else
                              m_Trainer.SayTo( from, "Na tento nakup nemas dost bodu." );
                        }
							}
						}
						break;
				}
				
				if ( m_Qatt.Count < 0 )
				  m_Qatt.Count = 0;
			}
		}		
		//End Plant buy

		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 ) );
					
				list.Add( new PetBuyEntry( this, from ) );
				list.Add( new PlantBuyEntry( 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 sklsum = taming + anlore + vetern;

			int max;

			if ( sklsum >= 240.0 )
				max = 5;
			else if ( sklsum >= 200.0 )
				max = 4;
			else if ( sklsum >= 160.0 )
				max = 3;
			else
				max = 2;

			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);

			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!
			}
		}

		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;
					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.InRange( this, 14 ) || !from.Stabled.Contains( pet ) || !from.CheckAlive() )
				return;

			if ( (from.Followers + pet.ControlSlots) <= from.FollowersMax )
			{
				pet.SetControlMaster( from );

				if ( pet.Summoned )
					pet.SummonMaster = from;

				pet.ControlTarget = from;
				pet.ControlOrder = OrderType.Follow;

				pet.MoveToWorld( from.Location, from.Map );

				pet.IsStabled = false;
				from.Stabled.Remove( pet );

				SayTo( from, 1042559 ); // Here you go... and good day to you!
			}
			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;

			if ( from.Stabled.Count >= GetMaxStabled( from ) )
			{
				SayTo( from, 1042565 ); // You have too many pets in the stables!
			}
			else
			{
				SayTo( from, 1042558 ); /* 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.Target = new StableTarget( this );
			}
		}

		public void EndStable( Mobile from, BaseCreature pet )
		{
			if ( Deleted || !from.CheckAlive() )
				return;

			if ( !pet.Controlled || 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 || pet is BaseTalismanSummon || pet is TalkingBaseCreature || pet is BaseEscortable )
			{
				SayTo( from, 502673 ); // I can not stable summoned creatures.
			}
			else if ( pet.Body.IsHuman )
			{
				SayTo( from, 502672 ); // HA HA HA! Sorry, I am not an inn.
			}
			else if ( (pet is PackLlama || pet is PackHorse || pet is Beetle) && (pet.Backpack != null && pet.Backpack.Items.Count > 0) )
			{
				SayTo( from, 1042563 ); // You need to unload your pet.
			}
			else if ( pet.Combatant != null && pet.InRange( pet.Combatant, 12 ) && pet.Map == pet.Combatant.Map )
			{
				SayTo( from, 1042564 ); // I'm sorry.  Your pet seems to be busy.
			}
			else if ( from.Stabled.Count >= GetMaxStabled( from ) )
			{
				SayTo( from, 1042565 ); // You have too many pets in the stables!
			}
			else
			{
				Container bank = from.BankBox;

				if ( bank != null && bank.ConsumeTotal( typeof( Gold ), 30 ) )
				{
					pet.ControlTarget = null;
					pet.ControlOrder = OrderType.Stay;
					pet.Internalize();

					pet.SetControlMaster( null );
					pet.SummonMaster = null;

					pet.IsStabled = true;

					if ( Core.SE )	
						pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy

					from.Stabled.Add( pet );

					SayTo( from, 502679 ); // Very well, thy pet is stabled. Thou mayst recover it by saying 'claim' to me. In one real world week, I shall sell it off if it is not claimed!
				}
				else
				{
					SayTo( from, 502677 ); // But thou hast not the funds in thy bank account!
				}
			}
		}

		public void Claim( Mobile from )
		{
			if ( Deleted || !from.CheckAlive() )
				return;

			bool claimed = false;
			int stabled = 0;

			for ( int i = 0; i < from.Stabled.Count; ++i )
			{
				BaseCreature pet = from.Stabled[i] as BaseCreature;

				if ( pet == null || pet.Deleted )
				{
					pet.IsStabled = false;
					from.Stabled.RemoveAt( i );
					--i;
					continue;
				}

				++stabled;

				if ( (from.Followers + pet.ControlSlots) <= from.FollowersMax )
				{
					pet.SetControlMaster( from );

					if ( pet.Summoned )
						pet.SummonMaster = from;

					pet.ControlTarget = from;
					pet.ControlOrder = OrderType.Follow;

					pet.MoveToWorld( from.Location, from.Map );

					pet.IsStabled = false;

					if ( Core.SE )
						pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy

					from.Stabled.RemoveAt( i );
					--i;

					claimed = true;
				}
				else
				{
					SayTo( from, 1049612, pet.Name ); // ~1_NAME~ remained in the stables because you have too many followers.
				}
			}

			if ( claimed )
				SayTo( from, 1042559 ); // Here you go... and good day to you!
			else if ( stabled == 0 )
				SayTo( from, 502671 ); // But I have no animals stabled with me at the moment!
		}

		public override bool HandlesOnSpeech( Mobile from )
		{
			return true;
		}

		public override void OnSpeech( SpeechEventArgs e )
		{
			if ( !e.Handled && e.HasKeyword( 0x0008 ) )
			{
				e.Handled = true;
				BeginStable( e.Mobile );
			}
			else if ( !e.Handled && e.HasKeyword( 0x0009 ) )
			{
				e.Handled = true;

				if ( !Insensitive.Equals( e.Speech, "claim" ) )
					BeginClaimList( e.Mobile );
				else
					Claim( e.Mobile );
			}
			else
			{
				base.OnSpeech( e );
			}
		}

		public AnimalTrainer( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();
		}
	}
}