using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Collector;
using System.Collections;
using System.Collections.Generic;

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

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

				return m_System;
			}
		}

		private HarvestDefinition m_Definition;

		public HarvestDefinition Definition
		{
			get { return m_Definition; }
		}

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

			#region Fishing
			HarvestDefinition fish = new HarvestDefinition();

			// Resource banks are every 8x8 tiles
			fish.BankWidth = 5;
			fish.BankHeight = 5;

			// Every bank holds from 5 to 15 fish
			fish.MinTotal = 10;
			fish.MaxTotal = 20;

			// A resource bank will respawn its content every 10 to 20 minutes
			fish.MinRespawn = TimeSpan.FromMinutes(10.0);
			fish.MaxRespawn = TimeSpan.FromMinutes(20.0);

			// Skill checking is done on the Fishing skill
			fish.Skill = SkillName.Fishing;

			// Set the list of harvestable tiles
			fish.Tiles = m_WaterTiles;
			fish.RangedTiles = true;

			// Players must be within 4 tiles to harvest
			fish.MaxRange = 5;

			// One fish per harvest action
			fish.ConsumedPerHarvest = 1;
			fish.ConsumedPerFeluccaHarvest = 1;

			// The fishing
			fish.EffectActions = new int[] { 12 };
			fish.EffectSounds = new int[0];
			fish.EffectCounts = new int[] { 1 };
			fish.EffectDelay = TimeSpan.Zero;
			fish.EffectSoundDelay = TimeSpan.FromSeconds(8.0);

			fish.NoResourcesMessage = 503172; // The fish don't seem to be biting here.
			fish.FailMessage = 503171; // You fish a while, but fail to catch anything.
			fish.TimedOutOfRangeMessage = 500976; // You need to be closer to the water to fish!
			fish.OutOfRangeMessage = 500976; // You need to be closer to the water to fish!
			fish.PackFullMessage = 503176; // You do not have room in your backpack for a fish.
			fish.ToolBrokeMessage = 503174; // You broke your fishing pole.

			res = new HarvestResource[]
			{
				//(ctor) HarvestResource( double reqSkill, double minSkill, double maxSkill, object message, Type[] types )
				new HarvestResource(00.0, 00.0, 120.0, 1043297, typeof(Fish)),
					new HarvestResource(70.0, 65.0, 300.0, 1032694, typeof(WhitePearl))
			};

			veins = new HarvestVein[]
			{
				//(ctor) HarvestVein( double veinChance, double chanceToFallback, HarvestResource primaryResource, HarvestResource fallbackResource )
				new HarvestVein(99.0, 0.0, res[0], null),
					new HarvestVein(1.0, 0.5, res[1], res[0])	// WhitePearl
			};

			fish.Resources = res;
			fish.Veins = veins;

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

		public override void OnConcurrentHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
		{
			from.SendLocalizedMessage(500972); // You are already fishing.
		}

		private class MutateEntry
		{
			public double m_ReqSkill, m_MinSkill, m_MaxSkill;
			public bool m_DeepWater;
			public Type[] m_Types;

			public MutateEntry(double reqSkill, double minSkill, double maxSkill, bool deepWater, params Type[] types)
			{
				m_ReqSkill = reqSkill;
				m_MinSkill = minSkill;
				m_MaxSkill = maxSkill;
				m_DeepWater = deepWater;
				m_Types = types;
			}
		}

		private static MutateEntry[] m_MutateTable = new MutateEntry[]
		{
			//MutateEntry( double reqSkill, double minSkill, double maxSkill, bool deepWater, Type[] types )
			new MutateEntry(90.0, 90.0, 3000.0, true, typeof(FishAlbinoAngelfish), typeof(FishBladePlant), typeof(FishAngelfish), typeof(FishBlueCory), typeof(FishBrineShrimp)),
            new MutateEntry(90.0, 90.0, 3000.0, true, typeof(WhitePearl), typeof(FishShrimp), typeof(FishSmallmouthSuckerfish), typeof(FishSpeckledCrab), typeof(FishSpottedBucaneer)),
            new MutateEntry(90.0, 90.0, 3000.0, true, typeof(FishSpottedPuffer), typeof(FishStripedSosarianSwill), typeof(FishVesperReefTiger)),
            new MutateEntry(90.0, 90.0, 3000.0, true, typeof(FishMinocBlue), typeof(FishNujelmHoney), typeof(FishFishies), typeof(FishRainbowMolly), typeof(NetPiece), typeof(FishClownfish), typeof(FishGoldenBroadtail)),
				new MutateEntry(90.0, 90.0, 3000.0, true, typeof(FishFandancer), typeof(FishBritainiaCrownFish), typeof(FishJellyfish)),
				new MutateEntry(90.0, 90.0, 7000.0, true, typeof(WhitePearl), typeof(FishBladePlant), typeof(BigFish), typeof(SOSPiece)),
				new MutateEntry(80.0, 80.0, 4500.0, true, typeof(WhitePearl), typeof(MessageInABottle), typeof(SpecialFishingNet), typeof(TreasureMap)),
				new MutateEntry(0.0, 105.0, -420.0, false, typeof(Boots), typeof(Shoes), typeof(Sandals), typeof(ThighBoots)),
				new MutateEntry(0.0, 200.0, -200.0, false, new Type[1] { null })
		};

		public override bool SpecialHarvest(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc)
		{
			PlayerMobile player = from as PlayerMobile;

			if (player != null)
			{
				QuestSystem qs = player.Quest;

				if (qs is CollectorQuest)
				{
					QuestObjective obj = qs.FindObjective(typeof(FishPearlsObjective));

					if (obj != null && !obj.Completed)
					{
						if (Utility.RandomDouble() < 0.5)
						{
							player.SendLocalizedMessage(1055086, "", 0x59); // You pull a shellfish out of the water, and find a rainbow pearl inside of it.

							obj.CurProgress++;
						}
						else
						{
							player.SendLocalizedMessage(1055087, "", 0x2C); // You pull a shellfish out of the water, but it doesn't have a rainbow pearl.
						}

						return true;
					}
				}
			}

			return false;
		}

		public override Type MutateType(Type type, Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource)
		{
			bool deepWater = SpecialFishingNet.FullValidation(map, loc.X, loc.Y);

			if (from.Map == Map.Underworld)
			{
				//             return deepWater ? type : typeof( Fish );
				return (0.075 >= Utility.RandomDouble()) ? typeof(WhitePearl): type;
			}

			double skillBase = from.Skills[SkillName.Fishing].Base;
			double skillValue = from.Skills[SkillName.Fishing].Value;

			for (int i = 0; i < m_MutateTable.Length; ++i)
			{
				MutateEntry entry = m_MutateTable[i];

				if (!deepWater && entry.m_DeepWater)
					continue;

				if (skillBase >= entry.m_ReqSkill)
				{
					double chance = (skillValue - entry.m_MinSkill) / (entry.m_MaxSkill - entry.m_MinSkill);

					if (chance > Utility.RandomDouble())
						return entry.m_Types[Utility.Random(entry.m_Types.Length)];
				}
			}

			return type;
		}

		private static Map SafeMap(Map map)
		{
			if (map == null || map == Map.Internal)
				return Map.Trammel;

			return map;
		}

		public override bool CheckResources(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed)
		{
			Container pack = from.Backpack;

			if (pack != null)
			{
				Item[] messages = pack.FindItemsByType(typeof(SOS));

				for (int i = 0; i < messages.Length; ++i)
				{
					SOS sos = (SOS)messages[i];

					if (from.Map == sos.TargetMap && from.InRange(sos.TargetLocation, 40))
						return true;
				}
			}

			return base.CheckResources(from, tool, def, map, loc, timed);
		}

		public override Item Construct(Type type, Mobile from)
		{
			if (type == typeof(TreasureMap))
			{
				int level;
				if (from is PlayerMobile && ((PlayerMobile)from).Young && from.Map == Map.Trammel && TreasureMap.IsInHavenIsland(from))
					level = 0;
				else
					level = 1;

				return new TreasureMap(level, from.Map == Map.Felucca ? Map.Felucca : Map.Trammel);
			}
			else if (type == typeof(MessageInABottle))
			{
				return new MessageInABottle(SafeMap(from.Map));
			}
			else if (type == typeof(Fish) && FishingLog.LastWinner == from && from.Map != Map.Underworld && Utility.RandomDouble() < 0.025)
			{
				if (Utility.RandomDouble() < 0.2)
					return Activator.CreateInstance(Mobiles.Teragon.Artifacts[Utility.Random(Mobiles.Teragon.Artifacts.Length)]) as Item;
				else
					return Activator.CreateInstance(ASoullessBlade.ExtraLoot[Utility.Random(ASoullessBlade.ExtraLoot.Length)]) as Item;
			}

			Container pack = from.Backpack;

			if (pack != null)
			{
				Item[] messages = pack.FindItemsByType(typeof(SOS));

				for (int i = 0; i < messages.Length; ++i)
				{
					SOS sos = (SOS)messages[i];

					if (from.Map == sos.TargetMap && from.InRange(sos.TargetLocation, 60))
					{
						bool dolphin = false;

						foreach (Mobile m in from.GetMobilesInRange(6))
						{
							if (m is Xanthos.Evo.EvoDolphin)
							{
								if (((BaseCreature)m).Controlled && ((BaseCreature)m).ControlMaster == from && ((Xanthos.Interfaces.IEvoCreature)m).Stage > 2)
								{
									dolphin = true;
									m.PlaySound(139);
									break;
								}
							}
						}

						Item preLoot = null;

						if (!dolphin)
						{
							switch (Utility.Random(6))
							{
								case 0: // Bone parts
								{
									int[] list = new int[]
									{
										0x1AE0, 0x1AE1, 0x1AE2, 0x1AE3, 0x1AE4, // skulls
    										0x1B09, 0x1B0A, 0x1B0B, 0x1B0C, 0x1B0D, 0x1B0E, 0x1B0F, 0x1B10, // bone piles
    										0x1B15, 0x1B16, // pelvis bones
    										0xECA, 0xECB, 0xECC, 0xECD, 0xECE, 0xECF, 0xED0, 0xED1, 0xED2 // skeletons
									};

									preLoot = new ShipwreckedItem(Utility.RandomList(list));
									break;
								}

								case 2: // Paintings and portraits
								{
									preLoot = new ShipwreckedItem(Utility.Random(0xE9F, 10));
									break;
								}

								case 3: // Pillows
								{
									preLoot = new ShipwreckedItem(Utility.Random(0x13A4, 11));
									break;
								}

								case 4: // Shells
								{
									preLoot = new ShipwreckedItem(Utility.Random(0xFC4, 9));
									break;
								}

								case 5: // Misc
								{
									int[] list = new int[]
									{
										0xE9F, 0xEA0, 0xEA1, 0xEA2, 0xEA3, 0xEA4, 0xEA5, 0xEA6, 0xEA7, 0xEA8, // paintings
    										0x13A4, 0x13A5, 0x13A6, 0x13A7, 0x13A8, 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, 0x13AE, // pillows
    										0x1EB5, // unfinished barrel
    										0xA2A, // stool
    										0xC1F, // broken clock
    										0x1047, 0x1048, // globe
    										0x1EB1, 0x1EB2, 0x1EB3, 0x1EB4, // barrel staves
    										0xE25, 0xE26, 0xE27, 0xE28, 0xE29, 0xE2A, 0xE2B, 0xE2C, // bottles
    										0xC19, 0xC1A, 0xC1B, 0xC1C, 0xC1D, 0xC1E, // broken chairs
    										0xC2C, 0xC2D, 0xC2E, 0xC2F, 0xC30, // ruined painting, debris
    										0x1087, 0x1088, 0x1089, //jewelry0x1420
    										0x13E5, 0x13E6, 0x13E7, 0x13E8, 0x13E9, 0x13EA // hanging armor
									};

									preLoot = new ShipwreckedItem(Utility.RandomList(list));
									break;
								}

								case 6: // Ship Items
								{
									int[] list = new int[]
									{
										0x14F8, 0x14FA, // ropes
    										0x14F7, 0x14F9, // anchors
    										0x14EB, 0x14EC, // maps
    										0x1057, 0x1058, // sextants
    										0x171A // feathered hat
									};

									preLoot = new ShipwreckedItem(Utility.RandomList(list));
									break;
								}

								/* YET TO BE TESTED FOR VHAERUN'S CRL FISHING SYSTEM
    
    							case 4: // Treasure Box
    							{
    								new TreasureBox();
    							}
    							case 5: // Ruined Clothes
    							{
    								preLoot = newShipwreckedItem( Utility.Random( 0xXXX, X ) );
    							}
    						*/
							}
						}
						else
							from.SendMessage("Tvuj delfin ti pomohl rychleji vylovit truhlu");

						if (preLoot != null)
							return preLoot;

						LockableContainer chest;

						if (Utility.RandomBool())
							chest = new MetalGoldenChest();
						else
							chest = new WoodenChest();

						TreasureMapChest.Fill(chest, Math.Max(1, sos.Level), null);

						//bagliky
                  List<Item> items = chest.Items;
						ArrayList toDelete = new ArrayList();

						for (int a = 0; a < items.Count; ++a)
						{
							Item obj = items[a];

							if (obj is TreasureMapChestBag)
							{
								BaseContainer baglik = (BaseContainer)obj;

								if (baglik != null)
								{
									List<Item> baglikItems = baglik.Items;

									for (int x = 0; x < baglikItems.Count; ++x)
									{
										if (!chest.TryDropItem(from, baglikItems[x], false))	// Attempt to stack it
                                 chest.DropItem(baglikItems[x]);
									}

									toDelete.Add(baglik);
								}
							}
						}

						foreach (Item item in toDelete)
							item.Delete();

						if (sos.IsAncient)
						{
							if (sos.Level > 6)
								chest.Hue = 1298;
							else
								chest.Hue = 0x481;

							chest.DropItem(new FabledFishingNet());
						}
						else
							chest.DropItem(new SpecialFishingNet());

						double piecechance = 0.05;

						switch (sos.Level)
						{
							case 2: piecechance = 0.05; break;
							case 3: piecechance = 0.07; break;
							case 4: piecechance = 0.1; break;
							case 5: piecechance = 0.2; break;
							case 6: piecechance = 0.3; break;
							case 7: piecechance = 0.5; break;
							case 8: piecechance = 0.7; break;
							case 9: piecechance = 1.00; break;
						}

						//SOS piece
                   if (Utility.RandomDouble() < piecechance + 0.2)
							chest.DropItem(new SOSPiece());

						if (sos.Level > 6 && Utility.RandomDouble() < piecechance)
							chest.DropItem(new SpendingPointsScroll());

						if (sos.Level > 5 && Utility.RandomDouble() < piecechance)
							chest.DropItem((Item)Activator.CreateInstance(ASoullessBlade.ExtraLoot[Utility.Random(ASoullessBlade.ExtraLoot.Length)]));

						if (sos.Level > 6 && Utility.RandomDouble() < piecechance)
							chest.DropItem((Item)Activator.CreateInstance(Mobiles.Teragon.Artifacts[Utility.Random(Mobiles.Teragon.Artifacts.Length)]));

						chest.Movable = true;
						chest.Locked = false;
						chest.TrapType = TrapType.None;
						chest.TrapPower = 0;
						chest.TrapLevel = 0;

						if (from is PlayerMobile && sos.Level > 6)
						{
							World.Broadcast(37, true, "{0} prave vylovil{1} z more truhlu s pokladem level {2}!", from.RawName, (from.Female) ? "a":"", sos.Level);
							Server.Commands.LogIt.WriteLine("Poklady", from, "{0} vylovil truhlu level {1}", from.RawName, sos.Level);

							PlayerTitles.TitleProgress(from, "fishing", sos.Level - 6); //Sailor, Sea-Dog
                     Guilds.Guild.GiveXp(from, (sos.Level - 6) * 100);

							if (Utility.RandomDouble() < 0.06)
								chest.DropItem((Item)Activator.CreateInstance(ASoullessBlade.ExtraLoot[Utility.Random(ASoullessBlade.ExtraLoot.Length)]));

							if (Utility.RandomDouble() < 0.05)
								chest.DropItem((Item)Activator.CreateInstance(Mobiles.Teragon.Artifacts[Utility.Random(Mobiles.Teragon.Artifacts.Length)]));

							piecechance = 0.001;

							switch (sos.Level)
							{
								case 8: piecechance = 0.05; break;
								case 9: piecechance = 0.25; break;
							}

							if (Utility.RandomDouble() < piecechance)
								chest.DropItem(new Xanthos.Evo.EvoDolphinDeed());

								/*
                     //SOUTEZ
                     PlayerMobile pm = ( PlayerMobile ) from;
                     pm.Expy += sos.Level;
                     
                     from.SendMessage( "Ziskavas {0} bodu.", sos.Level );
                     from.SendMessage( "Celkem mas {0} bodu.", pm.Expy );
                     */
						}

						sos.Delete();

						return chest;
					}
				}
			}

			return base.Construct(type, from);
		}

		public override bool Give(Mobile m, Item item, bool placeAtFeet)
		{
			if (m.Map != Map.Underworld && (item is TreasureMap || item is MessageInABottle || item is SpecialFishingNet))
			{
				BaseCreature serp;
				MagicalFishingPole pole = null;

				if (m.FindItemOnLayer(Layer.OneHanded) is MagicalFishingPole)
					pole = (MagicalFishingPole) m.FindItemOnLayer(Layer.OneHanded);

				double bonus = 0.0;

				if (pole != null && pole.Bait > 0)
				{
					bonus = 0.2;
					pole.Bait--;
				}

				if ((0.3 + bonus) > Utility.RandomDouble())
				{
					if ((0.1 + bonus) > Utility.RandomDouble())
					{
						if (m.Map == Map.Felucca && m.Skills[SkillName.Fishing].Value > 199.9 && Utility.RandomDouble() < (0.15 + bonus))
							serp = new SaltwaterElemental(m, true);
						else
							serp = new DeepwaterSlime();
					}
					else if ((0.2 + bonus) > Utility.RandomDouble())
						serp = new Kraken();
					else
						serp = new DeepSeaSerpent();
				}
				else
					serp = new SeaSerpent();

				int x = m.X, y = m.Y;

				Map map = m.Map;

				for (int i = 0; map != null && i < 20; ++i)
				{
					int tx = m.X - 10 + Utility.Random(21);
					int ty = m.Y - 10 + Utility.Random(21);

					Tile t = map.Tiles.GetLandTile(tx, ty);

					if (t.Z == -5 && ((t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137)) && !Spells.SpellHelper.CheckMulti(new Point3D(tx, ty, -5), map))
					{
						x = tx;
						y = ty;
						break;
					}
				}

				serp.MoveToWorld(new Point3D(x, y, -5), map);

				if (Teragon.CheckConvert(serp, serp.Location, map))
					serp.IsTeragon = true;

				serp.Home = serp.Location;
				serp.RangeHome = 10;

				serp.PackItem(item);

				m.SendLocalizedMessage(503170); // Uh oh! That doesn't look like a fish!

				return true; // we don't want to give the item to the player, it's on the serpent
			}

			if (item is BigFish || item is WoodenChest || item is MetalGoldenChest)
				placeAtFeet = true;

			if (item is BigFish)
			{
				((BigFish)item).Fisher = m;

				if (FishingLog.LastWinner != m)
				{
					FishingLog.Record((int) item.Weight, m, true);
					m.SendMessage("Ziskavas {0} bodu do souteze rybaru.", (int) item.Weight);
				}

				// 			   if ( Utility.RandomDouble() < 0.3 )
				// 			   {
				//                item.Name = "Soutezni ryba";
				// 			      item.Hue = 1772;
				//             }
			}

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

		public override void SendSuccessTo(Mobile from, Item item, HarvestResource resource)
		{
			if (item is BigFish)
			{
				from.SendLocalizedMessage(1042635); // Your fishing pole bends as you pull a big fish from the depths!

				((BigFish)item).Fisher = from;
			}
			else if (item is WoodenChest || item is MetalGoldenChest)
			{
				from.SendLocalizedMessage(503175); // You pull up a heavy chest from the depths of the ocean!
			}
			else
			{
				int number;
				string name;

				if (item is BaseMagicFish)
				{
					number = 1008124;
					name = "a mess of small fish";
				}
				else if (item is Fish)
				{
					number = 1008124;
					name = "a fish";
				}
				else if (item is BaseShoes)
				{
					number = 1008124;
					name = item.ItemData.Name;
				}
				else if (item is TreasureMap)
				{
					number = 1008125;
					name = "a sodden piece of parchment";
				}
				else if (item is MessageInABottle)
				{
					number = 1008125;
					name = "a bottle, with a message in it";
				}
				else if (item is SpecialFishingNet)
				{
					number = 1008125;
					name = "a special fishing net"; // TODO: this is just a guess--what should it really be named?
				}
				else if (item is FishMinocBlue)
				{
					number = 1008124;
					name = "a Minoc Blue fish";
				}
				else if (item is FishAlbinoAngelfish)
				{
					number = 1008124;
					name = "a albino angel fish";
				}
				else if (item is FishAngelfish)
				{
					number = 1008124;
					name = "a angel fish";
				}
				else if (item is FishBlueCory)
				{
					number = 1008124;
					name = "a Blue Cory fish";
				}
				else if (item is FishBrineShrimp)
				{
					number = 1008124;
					name = "a Brine Shrimp";
				}
				else if (item is FishShrimp)
				{
					number = 1008124;
					name = "a shrimp";
				}
				else if (item is FishSmallmouthSuckerfish)
				{
					number = 1008124;
					name = "a Smallmouth Suckerfish";
				}
				else if (item is FishSpeckledCrab)
				{
					number = 1008124;
					name = "a Speckled Crab";
				}
				else if (item is FishSpottedBucaneer)
				{
					number = 1008124;
					name = "a Spotted Bucaneer fish";
				}
				else if (item is FishSpottedPuffer)
				{
					number = 1008124;
					name = "a Spotted Puffer fish";
				}
				else if (item is FishStripedSosarianSwill)
				{
					number = 1008124;
					name = "a Striped Sosarian Swill fish";
				}
				else if (item is FishVesperReefTiger)
				{
					number = 1008124;
					name = "a Vesper Reef Tiger fish";
				}
				else if (item is FishNujelmHoney)
				{
					number = 1008124;
					name = "a Nujelm Honey fish";
				}
				else if (item is FishRainbowMolly)
				{
					number = 1008124;
					name = "a Rainbow Molly fish";
				}
				else if (item is NetPiece)
				{
					number = 1008124;
					name = "a piece of net";
				}
				else if (item is FishClownfish)
				{
					number = 1008124;
					name = "a Clown fish";
				}
				else if (item is FishGoldenBroadtail)
				{
					number = 1008124;
					name = "a Golden Broadtail fish";
				}
				else if (item is FishFandancer)
				{
					number = 1008124;
					name = "a Fan dancer fish";
				}
				else if (item is FishBritainiaCrownFish)
				{
					number = 1008124;
					name = "a Britainia Crown fish";
				}
				else if (item is FishJellyfish)
				{
					number = 1008124;
					name = "a Jelly fish";
				}
				else if (item is FishBladePlant)
				{
					number = 1008124;
					name = "a Blade Plant";
				}
				else if (item is FishFishies)
				{
					number = 1008124;
					name = "a mess of Fishies";
				}
				else if (item is WhitePearl)
				{
					number = 1008124;
					name = "a white pearl";
				}
				else
				{
					number = 1043297;

					if (item.Name != null)
					{
						name = item.Name;
					}
					else
					{
						if ((item.ItemData.Flags & TileFlag.ArticleA) != 0)
							name = "a " + item.ItemData.Name;
						else if ((item.ItemData.Flags & TileFlag.ArticleAn) != 0)
							name = "an " + item.ItemData.Name;
						else
							name = item.ItemData.Name;
					}
				}

				if (number == 1043297)
					from.SendLocalizedMessage(number, name);
				else
					from.SendLocalizedMessage(number, true, name);
			}
		}

		public override void OnHarvestStarted(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
		{
			base.OnHarvestStarted(from, tool, def, toHarvest);

			int tileID;
			Map map;
			Point3D loc;

			if (GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
				Timer.DelayCall(TimeSpan.FromSeconds(1.5), new TimerStateCallback(Splash_Callback), new object[] { loc, map });
			}

		private void Splash_Callback(object state)
		{
			object[] args = (object[])state;
			Point3D loc = (Point3D)args[0];
			Map map = (Map)args[1];

			Effects.SendLocationEffect(loc, map, 0x352D, 16, 4);
			Effects.PlaySound(loc, map, 0x364);
		}

		public override object GetLock(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
		{
			return this;
		}

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

			from.SendLocalizedMessage(500974); // What water do you want to fish in?
			return true;
		}

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

			if (from.Mounted)
			{
				from.SendLocalizedMessage(500971); // You can't fish while riding!
				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 (from.Mounted)
			{
				from.SendLocalizedMessage(500971); // You can't fish while riding!
				return false;
			}

			return true;
		}

		private static int[] m_WaterTiles = new int[]
		{
			0x00A8, 0x00AB,
				0x0136, 0x0137,
				0x5797, 0x579C,
				0x746E, 0x7485,
				0x7490, 0x74AB,
				0x74B5, 0x75D5
		};
	}
}