using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;

namespace Server.Engines.Harvest
{
	public class Lumberjacking : HarvestSystem
	{
		private static Lumberjacking m_System;

		public static Lumberjacking System
		{
			get
			{
				if (m_System == null)
					m_System = new Lumberjacking();

				return m_System;
			}
		}

		private HarvestDefinition m_Definition;

		public HarvestDefinition Definition
		{
			get { return m_Definition; }
		}

		private Lumberjacking()
		{
			HarvestResource[] res;
			HarvestVein[] veins;

			#region Lumberjacking
			HarvestDefinition lumber = new HarvestDefinition();

			// Resource banks are every 4x3 tiles
			lumber.BankWidth = 4;
			lumber.BankHeight = 4;

			// Every bank holds from 20 to 45 logs
			lumber.MinTotal = 20;
			lumber.MaxTotal = 45;

			// A resource bank will respawn its content every 20 to 30 minutes
			lumber.MinRespawn = TimeSpan.FromMinutes(20.0);
			lumber.MaxRespawn = TimeSpan.FromMinutes(30.0);

			// Skill checking is done on the Lumberjacking skill
			lumber.Skill = SkillName.Lumberjacking;

			// Set the list of harvestable tiles
			lumber.Tiles = m_TreeTiles;

			// Players must be within 2 tiles to harvest
			lumber.MaxRange = 2;

			// Ten logs per harvest action
			lumber.ConsumedPerHarvest = 10;
			lumber.ConsumedPerFeluccaHarvest = 10;

			// The chopping effect
			lumber.EffectActions = new int[] { 13 };
			lumber.EffectSounds = new int[] { 0x13E };
			lumber.EffectCounts = new int[] { 1, 2, 2, 2, 3 };
			lumber.EffectDelay = TimeSpan.FromSeconds(1.6);
			lumber.EffectSoundDelay = TimeSpan.FromSeconds(0.9);

			lumber.NoResourcesMessage = 500493; // There's not enough wood here to harvest.
			lumber.FailMessage = 500495; // You hack at the tree for a while, but fail to produce any useable wood.
			lumber.OutOfRangeMessage = 500446; // That is too far away.
			lumber.PackFullMessage = 500497; // You can't place any wood into your backpack!
			lumber.ToolBrokeMessage = 500499; // You broke your axe.

			res = new HarvestResource[]
			{
				new HarvestResource(00.0, 00.0, 120.0, 1072540, typeof(Log)),
					new HarvestResource(35.0, 35.0, 124.0, "You chop some pine logs and put them into your backpack.", typeof(PineLog), typeof(PineTreefellow)),
					new HarvestResource(45.0, 45.0, 126.0, "You chop some cedar logs and put them into your backpack.", typeof(CedarLog), typeof(CedarTreefellow)),
					new HarvestResource(75.0, 75.0, 128.0, "You chop some cherry logs and put them into your backpack.", typeof(CherryLog), typeof(CherryTreefellow)),
					new HarvestResource(85.0, 85.0, 130.0, "You chop some mahogany logs and put them into your backpack.", typeof(MahoganyLog), typeof(MahoganeyTreefellow)),
					new HarvestResource(90.0, 90.0, 132.0, 1072541, typeof(OakLog), typeof(OakTreefellow)),
					new HarvestResource(95.0, 95.0, 135.0, 1072542, typeof(AshLog), typeof(AshTreefellow)),
					new HarvestResource(100.0, 100.0, 140.0, 1072543, typeof(YewLog), typeof(YewTreefellow)),
					new HarvestResource(105.0, 105.0, 140.0, 1072544, typeof(HeartwoodLog), typeof(HeartwoodTreefellow)),
					new HarvestResource(110.0, 110.0, 150.0, 1072545, typeof(BloodwoodLog), typeof(BloodwoodTreefellow)),
					new HarvestResource(115.0, 115.0, 160.0, 1072546, typeof(FrostwoodLog), typeof(FrostwoodTreefellow))
			};

			veins = new HarvestVein[]
			{
				new HarvestVein(36.0, 0.0, res[0], null),
					new HarvestVein(13.0, 0.5, res[1], res[0]), // Pine
					new HarvestVein(10.0, 0.5, res[2], res[0]), // Cedar
					new HarvestVein(9.0, 0.5, res[3], res[0]), // Cherry
					new HarvestVein(8.5, 0.5, res[4], res[0]), // Mahogony
					new HarvestVein(7.0, 0.5, res[5], res[0]), // Oak
					new HarvestVein(5.5, 0.5, res[6], res[0]), // Ash
					new HarvestVein(4.0, 0.5, res[7], res[0]), // Yew
					new HarvestVein(3.5, 0.5, res[8], res[0]), // Heartwood
					new HarvestVein(2.0, 0.5, res[9], res[0]), // Bloodwood
					new HarvestVein(1.5, 0.5, res[10], res[0]), // Frostwood
			};

			lumber.Resources = res;
			lumber.Veins = veins;

			// 			lumber.RaceBonus = Core.ML;

			m_Definition = lumber;
			Definitions.Add(lumber);
			#endregion
		}

		public override bool CheckHarvest(Mobile from, Item tool)
		{
			if (!base.CheckHarvest(from, tool))
				return false;

			if (tool.Parent != from && !(tool is LegendaryHatchet))
			{
				from.SendLocalizedMessage(500487); // The axe must be equipped for any serious wood chopping.
				return false;
			}

			return true;
		}

		public override bool CheckHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
		{
			if (!base.CheckHarvest(from, tool, def, toHarvest))
				return false;

			if (tool.Parent != from && !(tool is LegendaryHatchet))
			{
				from.SendLocalizedMessage(500487); // The axe must be equipped for any serious wood chopping.
				return false;
			}

			return true;
		}

		public override void OnBadHarvestTarget(Mobile from, Item tool, object toHarvest)
		{
			if (tool is LegendaryHatchet)
			{
				if (((LegendaryHatchet)tool).HarvestCorpse(from, toHarvest) == false)
					from.SendLocalizedMessage(500489); // You can't use an axe on that.
			}
			else
				from.SendLocalizedMessage(500489); // You can't use an axe on that.
		}

		/*//START Quest
      public override void SendSuccessTo( Mobile from, Item item, HarvestResource resource )
		{
         if ( from is PlayerMobile )
         {
            PlayerMobile pm = ( PlayerMobile ) from;
            
            if ( pm != null && pm.NpcGuild == NpcGuild.MerchantsGuild )
            {
               int expy = 0;
               
                if (item is PineLog)
                  expy += (int) ( item.Amount / 2 );
                else if (item is CedarLog)
                  expy += item.Amount;
                else if (item is CherryLog)
                  expy += ( item.Amount * 2 );
                else if (item is MahoganyLog)
                  expy += ( item.Amount * 3 );
                else if (item is OakLog)
                  expy += ( item.Amount * 4 );
                else if (item is AshLog)
                  expy += ( item.Amount * 5 );
                else if (item is YewLog)
                  expy += ( item.Amount * 6 );
                else if (item is HeartwoodLog)
                  expy += ( item.Amount * 8 );
                else if (item is BloodwoodLog)
                  expy += ( item.Amount * 10 );
                else if (item is FrostwoodLog)
                  expy += ( item.Amount * 12 );
                      
               if ( expy > 0 )
               {
                  from.SendMessage( 0x35, "Do souteze drevorubcu ziskavas {0} bodu!", expy );
                  pm.Expy += expy;
                  
                  if ( Utility.RandomDouble() < 0.02 )
                  {
                     from.CloseGump(typeof(Gumps.AFKCheckGump));
                     from.SendGump(new Gumps.AFKCheckGump(from, 0, 5, 0, 90, null, true, new Point3D(1496, 1615, 20), Map.Trammel, null));
                  }
               }
            }
         }
        
         resource.SendSuccessTo( from );
		}
      //END Quest */
		#region Mondain's Legacy
		public override bool Give( Mobile m, Item item, bool placeAtFeet )
		{

			if ( m.Skills.Lumberjacking.Value >= 100 && m.Map != Map.Underworld )
			{

				if ( Utility.RandomDouble() < 0.07 )
				{

					Item sitem = null;
					int message = 0;
					double chance = Utility.RandomDouble();

					// 					if ( chance < 0.01 )
					// 					{
					// 						if ( Utility.RandomBool() )
					// 						{
					// 							sitem = new ParasiticPlant();
					// 							message = 1072549; // You found a parasitic plant!
					// 						}
					// 						else
					// 						{
					// 							sitem = new LuminescentFungi();
					// 							message = 1072550; // You found a luminescent fungi!
					// 						}
					// 					}
					if ( chance < 0.05 )
					{

                  sitem = new Switch();
						message = 1072547; // You found a switch!
					}
					else
					{

                  if ( Utility.RandomBool() )
						{

						   sitem = new BrilliantAmber();
						   message = 1072551; // You found a brilliant amber!
						}
                  else
						{

                     sitem = new BarkFragment();
						   message = 1072548; // You found a bark fragment!
						}
					}

					if ( item != null && !m.PlaceInBackpack( sitem ) && placeAtFeet )
					{

						ArrayList atFeet = new ArrayList();

						foreach ( Item obj in m.GetItemsInRange( 0 ) )
							atFeet.Add( obj );

						for ( int i = 0; i < atFeet.Count; ++i )
						{

							Item check = (Item)atFeet[i];

							if ( check.StackWith( m, sitem, false ) )
								return base.Give( m, item, placeAtFeet );
						}

						sitem.MoveToWorld( m.Location, m.Map );
					}

					m.SendLocalizedMessage( message );
				}
			}

			return base.Give( m, item, placeAtFeet );
		}

		#endregion

		public override HarvestVein MutateVein( Mobile from, Item tool, HarvestDefinition def, HarvestBank bank, object toHarvest, HarvestVein vein )
		{

			if ( from.Map == Map.Underworld )
			{

				int veinIndex = Array.IndexOf( def.Veins, vein );

				if ( veinIndex >= 0 && veinIndex < (def.Veins.Length) )
				{
					return def.Veins[0]; 
/* 					double chance = Utility.RandomDouble();

					if ( chance < 0.005 )
						{

						veinIndex = def.Veins.Length - 1;
						Guilds.Guild.GiveXp(from, 1000);
						}
					else if ( chance < 0.05 )
					  veinIndex = 7;
					else if ( chance < 0.1 )
					  veinIndex = 5;
					else if ( chance < 0.2 )
					  veinIndex = 2;
					else
					  veinIndex = 0;

					return def.Veins[veinIndex]; */
				}
			}

			if ( tool is TrollsHatchet || tool is LegendaryHatchet )
			{

				int veinIndex = Array.IndexOf( def.Veins, vein );

				if ( veinIndex >= 0 && veinIndex < (def.Veins.Length - 1) )
					return def.Veins[veinIndex + 1];
			}

			return base.MutateVein( from, tool, def, bank, toHarvest, vein );
		}

		private static int[] m_Offsets = new int[]
		{

				-1, -1,
				-1,  0,
				-1,  1,
				 0, -1,
				 0,  1,
				 1, -1,
				 1,  0,
				 1,  1
		};

      public override void OnHarvestFinished( Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested )
		{

			if ( tool is TrollsHatchet && 0.15 > Utility.RandomDouble() && from.Map != Map.Underworld )
			{

            HarvestResource res = vein.PrimaryResource;

				if ( res == resource && res.Types.Length > 1 )
				{

               try
					{

						Map map = from.Map;

						if ( map == null || map == Map.Internal )
							return;

						BaseCreature spawned = Activator.CreateInstance( res.Types[1] ) as BaseCreature;

						if ( spawned != null )
						{

                     int offset = Utility.Random( 8 ) * 2;

							for ( int i = 0; i < m_Offsets.Length; i += 2 )
							{

								int x = from.X + m_Offsets[(offset + i) % m_Offsets.Length];
								int y = from.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];

								if ( map.CanSpawnMobile( x, y, from.Z ) )
								{

									spawned.MoveToWorld( new Point3D( x, y, from.Z ), map );

									if ( spawned.Map == Map.Internal )
									{

                              spawned.Delete();
                              return;
									}

									spawned.Combatant = from;

									if( Utility.RandomDouble() < 0.6 )
										spawned.PackItem( new BarkFragment() );

									return;
								}
								else
								{

									int z = map.GetAverageZ( x, y );

									if ( map.CanSpawnMobile( x, y, z ) )
									{

										spawned.MoveToWorld( new Point3D( x, y, z ), map );

    									if ( spawned.Map == Map.Internal )
										{

                                  spawned.Delete();
                                  return;
										}

										spawned.Combatant = from;

										if( Utility.RandomDouble() < 0.6 )
										  spawned.PackItem( new BarkFragment() );

										return;
									}
								}
							}

							spawned.MoveToWorld( from.Location, from.Map );
							spawned.Combatant = from;

                     if( Utility.RandomDouble() < 0.6 )
							  spawned.PackItem( new BarkFragment() );
						}
					}

					catch
					{
					}
				}
			}
		}

		public static void Initialize()
		{

			Array.Sort( m_TreeTiles );
		}

		#region Tile lists
		private static int[] m_TreeTiles = new int[]
		{

				0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD, 0x4CD0, 0x4CD3, 0x4CD6, 0x4CD8,
				0x4CDA, 0x4CDD, 0x4CE0, 0x4CE3, 0x4CE6, 0x4CF8, 0x4CFB, 0x4CFE,
				0x4D01, 0x4D41, 0x4D42, 0x4D43, 0x4D44, 0x4D57, 0x4D58, 0x4D59,
				0x4D5A, 0x4D5B, 0x4D6E, 0x4D6F, 0x4D70, 0x4D71, 0x4D72, 0x4D84,
				0x4D85, 0x4D86, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9, 0x52BA,
				0x52BB, 0x52BC, 0x52BD,

				0x4CCE, 0x4CCF, 0x4CD1, 0x4CD2, 0x4CD4, 0x4CD5, 0x4CD7, 0x4CD9,
				0x4CDB, 0x4CDC, 0x4CDE, 0x4CDF, 0x4CE1, 0x4CE2, 0x4CE4, 0x4CE5,
				0x4CE7, 0x4CE8, 0x4CF9, 0x4CFA, 0x4CFC, 0x4CFD, 0x4CFF, 0x4D00,
				0x4D02, 0x4D03, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D4A,
				0x4D4B, 0x4D4C, 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51, 0x4D52,
				0x4D53, 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60, 0x4D61, 0x4D62,
				0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D73,
				0x4D74, 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D7A, 0x4D7B,
				0x4D7C, 0x4D7D, 0x4D7E, 0x4D7F, 0x4D87, 0x4D88, 0x4D89, 0x4D8A,
				0x4D8B, 0x4D8C, 0x4D8D, 0x4D8E, 0x4D8F, 0x4D90, 0x4D95, 0x4D96,
				0x4D97, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA1,
				0x4DA2, 0x4DA3, 0x4DA5, 0x4DA6, 0x4DA7, 0x4DA9, 0x4DAA, 0x4DAB,
				0x52BE, 0x52BF, 0x52C0, 0x52C1, 0x52C2, 0x52C3, 0x52C4, 0x52C5,
				0x52C6, 0x52C7
		};
		#endregion
	}
}