using System;
using Server;
using Server.Items;
using Server.Spells;
using Server.Network;
using System.Collections;

namespace Server.Mobiles
{
	//[CorpseName( "a water elemental corpse" )]
	public class SaltwaterElemental : BaseCreature
	{
		private Mobile m_Fisher;
		private bool m_FishingPole;

		public Mobile Fisher
		{
			get { return m_Fisher; }
			set { m_Fisher = value; }
		}

		public bool FishingPole
		{
			get { return m_FishingPole; }
			set { m_FishingPole = value; }
		}

		[Constructable]
		public SaltwaterElemental() : this(null, false)
		{
		}

		[Constructable]
		public SaltwaterElemental(Mobile fisher, bool fishingpole) : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
		{
			m_Fisher = fisher;
			m_FishingPole = fishingpole;

			Name = "a saltwater elemental";
			Body = 16;
			BaseSoundID = 278;
			Hue = Utility.RandomMinMax(1361, 1366);

			SetStr(696, 705);
			SetDex(146, 155);
			SetInt(666, 685);

			SetHits(1500, 2000);
			SetMana(2500);

			SetDamage(19, 26);

			SetDamageType(ResistanceType.Cold, 80);
			SetDamageType(ResistanceType.Energy, 20);

			SetResistance(ResistanceType.Physical, 100);
			SetResistance(ResistanceType.Fire, 100);
			SetResistance(ResistanceType.Cold, 30, 50);
			SetResistance(ResistanceType.Poison, 100);
			SetResistance(ResistanceType.Energy, 70, 85);

			SetSkill(SkillName.EvalInt, 107.6, 120.5);
			SetSkill(SkillName.Necromancy, 120.6, 150.5);
			SetSkill(SkillName.SpiritSpeak, 120.1, 150.5);
			SetSkill(SkillName.Magery, 120.1, 150.1);
			SetSkill(SkillName.Anatomy, 80.5);
			SetSkill(SkillName.Meditation, 110.0);
			SetSkill(SkillName.MagicResist, 80.1, 85.0);
			SetSkill(SkillName.Parry, 90.1, 95.1);
			SetSkill(SkillName.Tactics, 100.0);
			SetSkill(SkillName.Wrestling, 110.1, 120.0);

			Fame = 19000;
			Karma = -15000;

			VirtualArmor = 65;
			CanSwim = true;

			PackItem(new Rope(Utility.RandomMinMax(3, 10)));
			PackItem(new MessageInABottle(Map.Felucca));

			if(Utility.RandomDouble() < 0.75)
				PackItem(new MessageInABottle(Map.Felucca));

			PackItem((Utility.RandomDouble() < 0.85) ? new SpecialFishingNet() : new FabledFishingNet()); //Confirm?
			PackItem(Loot.RandomNewPotion());

			if (m_Fisher != null && m_Fisher.Talisman is TheBait)
				PackItem((Item)Activator.CreateInstance(ASoullessBlade.ExtraLoot[Utility.Random(ASoullessBlade.ExtraLoot.Length)]));

			if(Utility.RandomDouble() < 0.5)
			{
				SailorBones bones = new SailorBones();

				if (!m_FishingPole && m_Fisher != null)
				{
					Item farmor = Loot.RandomArmorOrHat();
					farmor.Hue = Utility.RandomMinMax(1361, 1366);

					int skillBonus = (int) Utility.RandomList(3, 3, 3, 5, 5, 10);

					if (skillBonus > 9)
						farmor.BlessedFor = m_Fisher;

					if (farmor is BaseClothing)
						((BaseClothing)farmor).SkillBonuses.SetValues(0, SkillName.Fishing, skillBonus);
					else if (farmor is BaseArmor)
						((BaseArmor)farmor).SkillBonuses.SetValues(0, SkillName.Fishing, skillBonus);

					bones.DropItem(farmor);
				}

				if(Utility.RandomDouble() < 0.75)
					bones.DropItem(new SOSPiece());

				if (m_FishingPole)
				{
					if (Utility.RandomDouble() < 0.9)
					{
						double random = Utility.RandomDouble();

						if (0.2 >= random)
						{
							bones.DropItem((Item)Activator.CreateInstance(Mobiles.Teragon.Artifacts[Utility.Random(Mobiles.Teragon.Artifacts.Length)]));
						}
						else if (0.4 >= random)
						{
							bones.DropItem((Item)Activator.CreateInstance(TreasureMessageChest.Artifacts[Utility.Random(TreasureMessageChest.Artifacts.Length)]));
						}
						else if (0.6 >= random)
						{
							random = Utility.RandomDouble();

							if (0.2 >= random)
							{
								bones.DropItem(new CechovniMince(Utility.RandomMinMax(10, 30)));
							}
							else if (0.4 >= random)
							{
								if (0.50 >= random)
									bones.DropItem(new TreasureMapPiece());
								else if (0.45 >= random)
									bones.DropItem(new TreasureMapPieceRare());
								else
									bones.DropItem(new TreasureMapPieceAncient());
							}
							else if (0.6 >= random)
							{
								bones.DropItem((Item)Activator.CreateInstance(Mobiles.Paragon.MLMiniArtifacts[Utility.Random(Mobiles.Paragon.MLMiniArtifacts.Length)]));
							}
							else
							{
								int theHue = Utility.RandomMinMax(2521, 2651);

								AllDyeTubsAll dt = new AllDyeTubsAll();
								dt.DyedHue = theHue;
								dt.Hue = theHue;
								dt.Charges = 1;
								bones.DropItem(dt);
							}
						}
						else
						{
							bones.DropItem(new PSToken(Utility.RandomMinMax(2, 5)));
						}
					}

					if (Utility.RandomDouble() < 0.3)
						bones.DropItem((Item)Activator.CreateInstance(ASoullessBlade.ExtraLoot[Utility.Random(ASoullessBlade.ExtraLoot.Length)]));
				}

				if (Utility.RandomDouble() < 0.05)
					bones.DropItem(new TheBait());

				if (Utility.RandomDouble() < 0.02)
					bones.DropItem(new Xanthos.Evo.EvoDolphinDeed());

				PackItem(bones);
			}
		}

		public override void GenerateLoot()
		{
			AddLoot(LootPack.UltraRich, 1);
			AddLoot(LootPack.HighScrolls, 4);
		}

		public override bool BleedImmune { get { return true; } }
		public override bool CanRummageCorpses { get { return true; } }
		public override bool BardImmune { get { return true; } }
		public override bool Unprovokable { get { return true; } }
		public override bool Uncalmable { get { return true; } }
		public override Poison PoisonImmune { get { return Poison.Lethal; } }
		public override int TreasureMapLevel { get { return 5; } }
		public override bool IsNotScaredOfDeath { get { return true; } } //neutika pri malem poctu hp
      public override bool IsScaryToPets { get { return true; } }

		public override bool HasBreath { get { return true; } }
		public override int BreathPhysicalDamage { get { return 20; } } // TODO: Verify damage type
		public override int BreathColdDamage { get { return 80; } }
		public override int BreathFireDamage { get { return 0; } }
		public override int BreathEffectHue { get { return 0x1ED; } }
		public override double BreathDamageScalar { get { return 0.05; } }
		public override double BreathMinDelay { get { return 5.0; } }
		public override double BreathMaxDelay { get { return 7.5; } }

		public void SpawnBlob(Mobile target)
		{
			Map map = this.Map;

			if (map == null || target == null)
				return;

			int newSums = Utility.RandomMinMax(1, 2);

			for (int i = 0; i < newSums; ++i)
			{
				SumPoisonElemental blob = new SumPoisonElemental();

				blob.Team = this.Team;
				blob.FightMode = FightMode.Closest;
				bool validLocation = false;
				Point3D loc = Utility.RandomBool() ? this.Location : target.Location;

				for (int j = 0; !validLocation && j < 10; ++j)
				{
					int x = X + Utility.Random(6) - 1;
					int y = Y + Utility.Random(6) - 1;
					int z = map.GetAverageZ(x, y);

					if (validLocation = map.CanFit(x, y, this.Z, 16, false, false))
						loc = new Point3D(x, y, Z);
					else if (validLocation = map.CanFit(x, y, z, 16, false, false))
						loc = new Point3D(x, y, z);
				}

				blob.Name = "a saltwater blob";
				blob.Hue = Utility.RandomMinMax(1361, 1366);
				blob.Body = 51;
				blob.BaseSoundID = 456;
				blob.CanSwim = true;

				blob.SetHits(556, 699);
				blob.SetDamage(16, 20);
				blob.SetDamageType(ResistanceType.Physical, 10);
				blob.SetDamageType(ResistanceType.Cold, 90);

				blob.SetResistance(ResistanceType.Physical, 100);
				blob.SetResistance(ResistanceType.Fire, 100);
				blob.SetResistance(ResistanceType.Cold, 20, 40);
				blob.SetResistance(ResistanceType.Poison, 100);
				blob.SetResistance(ResistanceType.Energy, 75);

				if (Teragon.CheckConvert(blob, loc, map))
					blob.IsTeragon = true;

				blob.MoveToWorld(loc, map);
				blob.Combatant = target;

				TimeSpan duration = TimeSpan.FromSeconds(45.0);

				new UnsummonTimer(this, blob, duration).Start();
				blob.SummonEnd = DateTime.Now + duration;
			}

			Effects.PlaySound(this.Location, map, 32);
		}

		public override void AlterMeleeDamageTo(Mobile to, ref int damage)
		{
			damage = DecreaseDamage(to, damage);

			if (to is Xanthos.Interfaces.IEvoCreature && !(to is Xanthos.Evo.EvoDolphin))
				damage *= 5;
		}

		public override void OnDamage(int amount, Mobile from, bool willKill, int typ)
		{
			if (from is Xanthos.Evo.EvoDolphin)
			{
				base.OnDamage(amount, from, willKill, typ);
				return;
			}

			if (from == null)
				return;

			if(0.055 > Utility.RandomDouble())
				SpawnBlob(from);

				// 			from.Damage( Utility.Random( 20, 10 ), this );
			from.Stam -= Utility.Random(5, 15);
			from.Mana -= Utility.Random(6, 15);

			IMount mount = from.Mount;

			if (mount != null)
			{
				from.PlaySound(0x140);
				from.FixedParticles(0x3728, 10, 15, 9955, EffectLayer.Waist);
				from.SendLocalizedMessage(1062315); // You fall off your mount!

			   mount.Rider = null;
				BaseMount.SetMountPrevention(from, BlockMountType.Dazed, TimeSpan.FromSeconds(20.0));
			}
			else
			{
				if(!(from.Talisman is TheBait) && Utility.RandomDouble() < 0.1)
				{
					ExpireTimer timer = (ExpireTimer)m_Table[from];

					if(timer == null)
					{
						this.PublicOverheadMessage(MessageType.Regular, 193, true, String.Format("Freezing cold on {0}!", from.RawName));
						this.PlaySound(33);
						from.SolidHueOverride = 2642;
						timer = new ExpireTimer(from, this);
						timer.Start();
						m_Table[from] = timer;
					}
				}
			}

			base.OnDamage(amount, from, willKill, typ);
		}

		private static Hashtable m_Table = new Hashtable();

		private class ExpireTimer : Timer
		{
			private Mobile m_Mobile;
			private Mobile m_From;
			private int m_Count;

			public ExpireTimer(Mobile m, Mobile from)
			: base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0))
			{
				m_Mobile = m;
				m_From = from;
				Priority = TimerPriority.TwoFiftyMS;
			}

			public void DoExpire()
			{
				Stop();
				m_Table.Remove(m_Mobile);
				m_Mobile.SendMessage("Freezing cold faded");
				m_Mobile.SolidHueOverride = -1;
			}

			public void DrainLife()
			{
				if(m_Mobile.Alive && !m_Mobile.Blessed && !m_Mobile.Deleted)
				{
					m_Mobile.PlaySound(0x10B);
					m_Mobile.FixedParticles(0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255);
					int damage = Engines.XmlSpawner2.XmlSpecial.PercentualDamage(Utility.RandomMinMax(10, 25), m_Mobile);

					m_Mobile.Hits -= damage;
					ISTile5.SendDmgPacket(m_Mobile, damage);

					if (m_Mobile.Hits < 2)
						m_Mobile.Kill();
				}
				else
					DoExpire();
			}

			protected override void OnTick()
			{
				DrainLife();

				if (Utility.RandomBool())
					m_Mobile.Paralyze(TimeSpan.FromSeconds(1.0));

				if(++m_Count >= 8)
				{
					DoExpire();
				}
			}
		}

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

		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write((int) 0);
		}

		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
}