using System;
using Server.Misc;
using Server.Network;
using System.Collections;
using Server.Items;
using Server.Targeting;

namespace Server.Mobiles
{
	public class KhaldunSummoner : BaseCreature
	{
		public override bool ClickTitle { get { return false; } }
		public override bool ShowFameTitle { get { return false; } }

		[Constructable]
		public KhaldunSummoner(): base(AIType.AI_Necromage, FightMode.Closest, 10, 1, 0.2, 0.4)
		{
			Body = 0x190;
			Name = "Zealot of Khaldun";
			Title = "the Summoner";

			SetStr(516, 605);
			SetDex(106, 115);
			SetInt(300, 305);

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

			SetDamage(10, 25);

			SetDamageType(ResistanceType.Cold, 70);
			SetDamageType(ResistanceType.Physical, 30);

			SetResistance(ResistanceType.Physical, 50, 70);
			SetResistance(ResistanceType.Fire, 50, 70);
			SetResistance(ResistanceType.Cold, 60, 70);
			SetResistance(ResistanceType.Poison, 50, 60);
			SetResistance(ResistanceType.Energy, 60, 70);

			SetSkill(SkillName.EvalInt, 77.6, 110.5);
			SetSkill(SkillName.Necromancy, 120.6, 130.5);
			SetSkill(SkillName.SpiritSpeak, 120.1, 150.5);
			SetSkill(SkillName.Magery, 90.1, 120.1);
			SetSkill(SkillName.Poisoning, 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, 70.1, 150.0);
			SetSkill(SkillName.Swords, 120.1, 130.0);
			SetSkill(SkillName.Anatomy, 100.0);

			VirtualArmor = 36;
			Fame = 10000;
			Karma = -10000;

			LeatherGloves gloves = new LeatherGloves();
			gloves.Hue = 0x66D;
			AddItem(gloves);

			BoneHelm helm = new BoneHelm();
			helm.Hue = 0x835;
			AddItem(helm);

			Necklace necklace = new Necklace();
			necklace.Hue = 0x66D;
			AddItem(necklace);

			Cloak cloak = new Cloak();
			cloak.Hue = 0x66D;
			AddItem(cloak);

			Kilt kilt = new Kilt();
			kilt.Hue = 0x66D;
			AddItem(kilt);

			Sandals sandals = new Sandals();
			sandals.Hue = 0x66D;
			AddItem(sandals);
		}

		public override int GetIdleSound()
		{
			return 0x184;
		}

		public override int GetAngerSound()
		{
			return 0x286;
		}

		public override int GetDeathSound()
		{
			return 0x288;
		}

		public override int GetHurtSound()
		{
			return 0x19F;
		}

		public override bool AlwaysMurderer { get { return true; } }
		public override bool Unprovokable { get { return true; } }
		public override bool IsNotScaredOfDeath { get { return true; } } //neutika pri malem poctu hp

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

		public override bool OnBeforeDeath()
		{
			BoneWarriorMage rm = new BoneWarriorMage();
			rm.Team = this.Team;
			rm.Combatant = this.Combatant;
			rm.NoKillAwards = true;
			rm.Name = "a bone magi";
			rm.Body = 148;
			rm.Hue = 0;
			rm.BaseSoundID = 451;

			if (rm.Backpack == null)
			{
				Backpack pack = new Backpack();
				pack.Movable = false;
				rm.AddItem(pack);
			}

			for (int i = 0; i < 2; i++)
			{
				LootPack.FilthyRich.Generate(this, rm.Backpack, true, LootPack.GetLuckChanceForKiller(this));
				LootPack.FilthyRich.Generate(this, rm.Backpack, false, LootPack.GetLuckChanceForKiller(this));
			}

			Effects.PlaySound(this, Map, GetDeathSound());
			Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0);
			rm.MoveToWorld(Location, Map);

			Delete();
			return false;
		}

		private DateTime m_PlagueDelay = DateTime.Now;

		public override void OnDamage(int amount, Mobile from, bool willKill, int typ)
		{
			if (typ == 2)
				amount = 0;

			base.OnDamage(amount, from, willKill, typ);
			
			if (from == null)
				return;
			
			if (Utility.RandomDouble() < 0.075)
				Summon(from);

			if(!IsUnderInfluence(from) && Utility.RandomDouble() < 0.015)
			{
				m_PlagueDelay = DateTime.Now + TimeSpan.FromSeconds(90.0);
				Plague(from, this, true);
			}
		}

		public void Summon(Mobile from)
		{
			Map map = this.Map;

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

			Mobile targ = null;

			if (from is PlayerMobile && from.Map == map)
				targ = from;

			MadSquirrel summon = new MadSquirrel(targ, 1.0);

			if (summon == null)
				return;

			bool validLocation = false;
			Point3D loc = this.Location;

			for (int j = 0; !validLocation && j < 10; ++j)
			{
				int x = X + Utility.Random(3) - 1;
				int y = Y + Utility.Random(3) - 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);
			}

			summon.Name = "a shadow skeleton";
			summon.Body = Utility.RandomList(50, 56);
			summon.BaseSoundID = 0x48D;
			summon.Hue = 1;
			summon.MoveToWorld(loc, map);
		}

		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(2.0), TimeSpan.FromSeconds(2.0))
			{
				m_Mobile = m;
				m_From = from;
				Priority = TimerPriority.OneSecond;
			}

			public void DoExpire()
			{
				Stop();
				m_Table.Remove(m_Mobile);
				m_Mobile.SendMessage("Wandering plague faded");
				m_Mobile.SolidHueOverride = -1;
				m_Mobile.FixedParticles(0x373A, 10, 15, 5012, EffectLayer.Waist);
				m_Mobile.PlaySound(0x1E0);
			}

			public void DrainLife()
			{
				if(m_Mobile.Alive && !m_Mobile.Blessed && !m_Mobile.Deleted)
				{
					foreach (Mobile m in m_Mobile.GetMobilesInRange(3))
					{
						if (m != m_Mobile && m.Player && m.AccessLevel == AccessLevel.Player && m_Mobile.InLOS(m))
						{
							if(!IsUnderInfluence(m))
							{
								Plague(m, m_Mobile, true);
							}
						}
					}

					if ((m_Count % 5) == 0)
					{
						//     					m_Mobile.PlaySound( 561 );
						//                   m_Mobile.FixedParticles( 0x36CB, 1, 9, 9911, 67, 5, EffectLayer.Head );
						//                   m_Mobile.FixedParticles( 0x374A, 1, 17, 9502, 1108, 4, (EffectLayer)255 );

						m_Mobile.PlaySound(m_Mobile.Female ? 813 : 1087);

						if (!m_Mobile.Mounted)
							m_Mobile.Animate(32, 5, 1, true, false, 0);

						Point3D p = new Point3D(m_Mobile.Location);

						switch(m_Mobile.Direction)
						{
							case Direction.North:
								p.Y--; break;
							case Direction.South:
								p.Y++; break;
							case Direction.East:
								p.X++; break;
							case Direction.West:
								p.X--; break;
							case Direction.Right:
								p.X++; p.Y--; break;
							case Direction.Down:
								p.X++; p.Y++; break;
							case Direction.Left:
								p.X--; p.Y++; break;
							case Direction.Up:
								p.X--; p.Y--; break;
							default:
								break;
						}

						p.Z = m_Mobile.Map.GetAverageZ(p.X, p.Y);

						bool canFit = Server.Spells.SpellHelper.AdjustField(ref p, m_Mobile.Map, 12, false);

						if (canFit)
						{
							SelfDeletingItem puke = new SelfDeletingItem(Utility.RandomList(0xf3b, 0xf3c), "zvratky", 5);
							puke.Hue = 0x557;
							puke.Map = m_Mobile.Map;
							puke.Location = p;
						}
					}

					m_Mobile.SolidHueOverride = 1960;

					if (m_Mobile.Hits > 1)
					{
						int damage = Engines.XmlSpawner2.XmlSpecial.PercentualDamage(Utility.RandomMinMax(5, 10), m_Mobile);

						if (m_Mobile.Hits > damage)
							m_Mobile.Hits -= damage;
						else
						{
							damage = m_Mobile.Hits - 1;
							m_Mobile.Hits = 1;
						}

						ISTile5.SendDmgPacket(m_Mobile, damage);
					}
				}
				else
					DoExpire();
			}

			protected override void OnTick()
			{
				DrainLife();

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

		public static bool IsUnderInfluence(Mobile mobile)
		{
			if (mobile == null) return false;

			ExpireTimer timer = (ExpireTimer)m_Table[mobile];

			if (timer == null)
				return false;

			return true;
		}

		public static void CurePlague(Mobile mobile)
		{
			if (mobile == null) return;

			ExpireTimer timer = (ExpireTimer)m_Table[mobile];

			if (timer == null)
				return;

			timer.DoExpire();
		}

		public static void Plague(Mobile victim, Mobile from, bool msg)
		{
			if (victim != null && !victim.Deleted && victim.Player && victim.AccessLevel == AccessLevel.Player && victim.Alive)
			{
				if (from is BaseCreature && msg)
					from.PublicOverheadMessage(MessageType.Regular, 193, true, String.Format("Wandering plague on {0}!", victim.RawName));

				victim.SolidHueOverride = 1960;
				victim.RevealingAction();
				victim.PlaySound(0x22F);
				victim.FixedParticles(0x36CB, 1, 9, 9911, 67, 5, EffectLayer.Head);
				victim.FixedParticles(0x374A, 1, 17, 9502, 1108, 4, (EffectLayer)255);

				ExpireTimer timer = new ExpireTimer(victim, from);

				timer.Start();
				m_Table[victim] = timer;
			}
		}

		public override void OnKilledBy(Mobile mob)
		{
			base.OnKilledBy(mob);

			if (Paragon.CheckArtifactChance(mob, this) && mob.Talisman is KhalAnkurAmulet)
			{
				((KhalAnkurAmulet) mob.Talisman).SpendingPoints++;
			}
		}

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