using System;
using Server;
using Server.Items;
using System.Collections;
using Server.Spells;
using Server.Spells.Seventh;
using Server.Spells.Fifth;
using Server.Engines.CannedEvil;
using System.Collections.Generic;
using Server.Spells.Necromancy;
using Server.Spells.Ninjitsu;
using Server.Spells.Spellweaving;
using Server.Targeting;

namespace Server.Mobiles
{
	[CorpseName( "a Queen Lamia corpse" )]
	public class QueenLamia : BaseCreature
	{

		private ArrayList spawns = new ArrayList();
		private bool SnakesSummoned = false; 

		[Constructable]
		public QueenLamia() : base( AIType.AI_Super, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			Name = "Queen Lamia";
			Body = 87;
			Hue = 88; 
			BaseSoundID = 644;

			SetStr( 281, 305 );
			SetDex( 291, 315 );
			SetInt( 150, 200 );
			
			SetMana( 200 );
			SetHits( 1069, 1083 );
			SetStam( 100, 200 );

			SetDamage( 20, 25 );

			SetDamageType( ResistanceType.Physical, 100 );

			SetResistance( ResistanceType.Physical, 60, 65 );
			SetResistance( ResistanceType.Fire, 60, 70 );
			SetResistance( ResistanceType.Cold, 30, 40 );
			SetResistance( ResistanceType.Poison, 50, 60 );
			SetResistance( ResistanceType.Energy, 25, 35 );

			SetSkill( SkillName.EvalInt, 50.0, 60.0 );
			SetSkill( SkillName.Magery, 50.0, 60.0 );
			
			SetSkill( SkillName.Necromancy, 80.0 );
			SetSkill( SkillName.SpiritSpeak, 80.0 );
			SetSkill( SkillName.Meditation, 50.0, 60.0 );
			
			SetSkill( SkillName.MagicResist, 87.0, 100.0 );
			SetSkill( SkillName.Tactics, 77.7, 97.5 );
			SetSkill( SkillName.Wrestling, 120 );

			Fame = 12000;
			Karma = -12000;

			VirtualArmor = 44;

			PackReg( 15, 35 );
			PackNecroReg( 15, 35 );
		}
		
		public override void OnDeath( Container c )
		{
			if ( Utility.Random( 3 ) == 0 )
			{		
				Item item;

				switch ( Utility.Random( 1 ))
				{
								default:
					case 1: item = new QueenLamiaKey(); break;
							}

				c.DropItem( item );
			}

			base.OnDeath( c );
		}

		public override void GenerateLoot()
		{
			AddLoot( LootPack.FilthyRich, 3 );
			AddLoot( LootPack.Rich, 1 );
			AddLoot( LootPack.MedScrolls, 7 );
		}

		public override int Meat{ get{ return 1; } }
		
		
		public override void OnThink()
		{
		
			if (this.Combatant != null && 0.05 >= Utility.RandomDouble())
			{
				Mobile target = this.Combatant; 
				SummonSnakes( target );
			}
		
			if (this.Combatant != null && 0.05 >= Utility.RandomDouble() && 0.03 >= Utility.RandomDouble())
			{
				Mobile target = this.Combatant; 
				FrogForm( target );
			}
			else if (this.Combatant != null && 0.05 >= Utility.RandomDouble() && 0.03 >= Utility.RandomDouble())
			{
				Mobile target = this.Combatant;
				if ( !IsSleeping( target ) && this.InLOS( target ))
				{
					target.SendMessage("Queen Lamia puts you to sleep");
					Effects.SendLocationParticles( EffectItem.Create( target.Location, target.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 2406, 7, 9915, 0 );
					target.PlaySound( 0x1F8 );
					BeginSleep( target, this );
				}
			}	
			
			base.OnThink();		
		}
		
		public override void OnDamage( int amount, Mobile attacker, bool willKill ) 
		{
			if (attacker!=null && 0.2 >= Utility.RandomDouble() )
			{
				Charm(attacker, amount); 
			}
			
			base.OnDamage(amount, attacker, willKill);	
		}
		
		public void Charm( Mobile attacker, int amount )
		{
			ArrayList list = new ArrayList();

			foreach ( Mobile m in this.GetMobilesInRange( 20 ) )
			{
				if ( m == this || !CanBeHarmful( m ) || !this.InLOS( m ))
					continue;
				if ( m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned || ((BaseCreature)m).Team != this.Team) )
					list.Add( m );
				else if ( m.Player )
					list.Add( m );
			}
			if(list.Count<1)return;
			
				Mobile n = list[Utility.Random(list.Count)] as Mobile;
				n.Damage( amount );
				
				if (n.Name == attacker.Name)
				{
					attacker.SendMessage("Queen Lamia Charms you to attack yourself");
					attacker.SendMessage("You hit yourself for " + amount + " damage");
				}
				else
				{
					n.SendMessage("Queen Lamia Charms " + attacker.Name + " to attack you (" + amount + " damage)" );
					attacker.SendMessage("Queen Lamia charms you to attack " + n.Name + "(" + amount + " damage)");
				}
				
				Effects.SendLocationParticles( EffectItem.Create( attacker.Location, attacker.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 20, 332, 7, 9915, 0 );
				attacker.FixedParticles( 0x373A, 1, 30, 9913, 332, 7, EffectLayer.Head );
				attacker.PlaySound( 0x5C9 );
				
				Effects.SendLocationParticles( EffectItem.Create( n.Location, n.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 20, 332, 7, 9915, 0 );
				attacker.FixedParticles( 0x373A, 1, 30, 9913, 332, 7, EffectLayer.Head );
				n.PlaySound( 0x5C9 );
				
				this.Say("*Queen Lamia charms " + attacker.Name + " to attack " + n.Name + "*");
		}
		
		public void SummonSnakes( Mobile attacker )
		{
			if ( attacker != this && SnakesSummoned == false )
			{
				Mobile spawn;
				SnakesSummoned = true; 
		
				spawn = new LamiaSeaSnake();
				spawn.MoveToWorld( this.Location, this.Map );
				spawn = new LamiaSeaSnake();
				spawn.MoveToWorld( this.Location, this.Map );
				spawn = new LamiaSeaSnake();
				spawn.MoveToWorld( this.Location, this.Map );			
				attacker.SendMessage( "Queen Lamia sends sea snakes after you" );
				spawn.Combatant = attacker;
			}
		}
		
		public void Polymorph( Mobile m )
		{
				foreach ( Mobile n in this.GetMobilesInRange( 100 ) )
				{
					if ( n is BaseCreature && (((BaseCreature)n).Controlled || ((BaseCreature)n).Summoned || ((BaseCreature)n).Team != this.Team) )
						n.Combatant = null;
					else if ( n.Player )
						n.Combatant = null;
				}
				
			if (Spells.Necromancy.TransformationSpell.UnderTransformation( m )) //Removes necromancer form
			{
				TransformationSpell.RemoveContext( m, true );
			}
			
			if (Spells.Ninjitsu.AnimalForm.UnderTransformation( m )) //Removes animal form
			{
				AnimalForm.RemoveContext( m, true );
			}
			
			if ( !m.CanBeginAction( typeof( PolymorphSpell ) ) || !m.CanBeginAction( typeof( IncognitoSpell ) ) || m.IsBodyMod )
				return;

			IMount mount = m.Mount;

			if ( mount != null )
				mount.Rider = null;

			if ( m.Mounted )
				return;

			if ( m.BeginAction( typeof( PolymorphSpell ) ) )
			{
				Item disarm = m.FindItemOnLayer( Layer.OneHanded );

				if ( disarm != null && disarm.Movable )
					m.AddToBackpack( disarm );

				disarm = m.FindItemOnLayer( Layer.TwoHanded );

				if ( disarm != null && disarm.Movable )
					m.AddToBackpack( disarm );

				m.BodyMod = 81;
				m.HueMod = 372;

				new ExpirePolymorphTimer( m ).Start();
			}
		}

		private class ExpirePolymorphTimer : Timer
		{
			private Mobile m_Owner;

			public ExpirePolymorphTimer( Mobile owner ) : base( TimeSpan.FromSeconds( 30.0 ) )
			{
				m_Owner = owner;

				Priority = TimerPriority.OneSecond;
			}

			protected override void OnTick()
			{
				if ( !m_Owner.CanBeginAction( typeof( PolymorphSpell ) ) )
				{
					m_Owner.BodyMod = 0;
					m_Owner.HueMod = -1;
					m_Owner.EndAction( typeof( PolymorphSpell ) );
				}
			}
		}
	
		private static Hashtable FrogTable = new Hashtable();

		private class ExpireTimer : Timer
		{
			private Mobile m_Mobile;
			private List<ResistanceMod> m_Mods;

			public ExpireTimer( Mobile m, List<ResistanceMod> mods, TimeSpan delay ) : base( delay )
			{
				m_Mobile = m;
				m_Mods = mods;
				Priority = TimerPriority.TwoFiftyMS;
			}

			public void DoExpire()
			{
				for ( int i = 0; i < m_Mods.Count; ++i )
					m_Mobile.RemoveResistanceMod( m_Mods[i] );

				Stop();
				FrogTable.Remove( m_Mobile );
			}

			protected override void OnTick()
			{
				DoExpire();
			}
		}
		
		private static Hashtable SleepTable = new Hashtable();

		public static bool IsSleeping( Mobile m )
		{
			return SleepTable.Contains( m );
		}

		public static void BeginSleep( Mobile m, Mobile from )
		{
			m.Frozen = true;
			Timer t = (Timer)SleepTable[m];

			if ( t != null )
				t.Stop();

			t = new InternalTimer( from, m );
			SleepTable[m] = t;

			t.Start();
		}

		public static void LifeCheck( Mobile m, Mobile from )
		{
			if ( !m.Alive )
			{
				EndSleep( m );
			}
		}

		public static void EndSleep( Mobile m )
		{
			Timer t = (Timer)SleepTable[m];

			if ( t != null )
				t.Stop();

			SleepTable.Remove( m );

			m.Frozen = false;
			m.SendMessage("You wake up"); 
		}
		
		private class InternalTimer : Timer
		{
			private Mobile m_From;
			private Mobile m_Mobile;
			private int m_Count;

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

			protected override void OnTick()
			{
				LifeCheck( m_Mobile, m_From );
				
				m_Mobile.Say(501239);

				if ( ++m_Count == 5 ) //5 seconds
					EndSleep( m_Mobile );
			}
		}
		
		public override void OnGaveMeleeAttack( Mobile defender )
		{
			base.OnGaveMeleeAttack( defender );
			
			if ( 0.2 > Utility.RandomDouble() )
				FrogForm( defender );
			else if ( 0.1 > Utility.RandomDouble() )
			{
				if ( !IsSleeping( defender ) )
				{
					defender.SendMessage("Queen Lamia puts you to sleep");
									Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 32314, 7, 9915, 0 );
					defender.PlaySound( 0x1F8 );
					BeginSleep( defender, this );
				}
			}	
		}
		
		public override void OnGotMeleeAttack( Mobile attacker )
		{
			base.OnGaveMeleeAttack( attacker );
			
			if ( 0.3 > Utility.RandomDouble() && !attacker.InRange( this, 3 ))
			{
				if ( !IsSleeping( attacker ) )
				{
					attacker.SendMessage("Queen Lamia puts you to sleep");
					Effects.SendLocationParticles( EffectItem.Create( attacker.Location, attacker.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 32314, 7, 9915, 0 );
					attacker.PlaySound( 0x1F8 );
					this.Combatant = attacker;
					BeginSleep( attacker, this );
				}
			}	
			else if ( 0.5 > Utility.RandomDouble() && !attacker.InRange( this, 3 ))
			{
				FrogForm( attacker );
				this.Location = attacker.Location;
				this.Combatant = attacker;
			}
			else if ( 0.05 > Utility.RandomDouble() && !attacker.InRange( this, 1 ))
				FrogForm( attacker );
			else if ( 0.05 > Utility.RandomDouble() && !attacker.InRange( this, 1 ))
			{
				if ( !IsSleeping( attacker ) )
				{
					attacker.SendMessage("Queen Lamia puts you to sleep");
					Effects.SendLocationParticles( EffectItem.Create( attacker.Location, attacker.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 32314, 7, 9915, 0 );
					attacker.PlaySound( 0x1F8 );
					BeginSleep( attacker, this );
				}
			} 
		}
		
		public override void OnDamagedBySpell( Mobile attacker )
		{
			base.OnDamagedBySpell( attacker );
			
			if ( 0.1 > Utility.RandomDouble() && !attacker.InRange( this, 1 ))
			{
				if ( !IsSleeping( attacker ) && this.InLOS( attacker ))
				{
					attacker.SendMessage("The lamia puts you to sleep");
					Effects.SendLocationParticles( EffectItem.Create( attacker.Location, attacker.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 32314, 7, 9915, 0 );
					attacker.PlaySound( 0x1F8 );
					BeginSleep( attacker, this );
				}
			}	
			else if ( 0.1 > Utility.RandomDouble() && !attacker.InRange( this, 1 ))
				FrogForm( attacker );
		}
		
		public void FrogForm( Mobile defender )
		{
			ExpireTimer timer = (ExpireTimer)FrogTable[defender];
				
			if ( timer != null )
			{
				timer.DoExpire();
			}		
			else if ( timer == null && this.InLOS( defender ))
			{
			
				if (!defender.CanBeginAction( typeof( PolymorphSpell ) ) && defender.BodyMod != 81) //Removes magery form
				{
					defender.BodyMod = 0;
					defender.HueMod = -1;
					defender.EndAction( typeof( PolymorphSpell ) );

					BaseArmor.ValidateMobile( defender );
					BaseClothing.ValidateMobile( defender );
				}	
				
				if (Spells.Necromancy.TransformationSpell.UnderTransformation( defender )) //Removes necromancer form
				{
					TransformationSpell.RemoveContext( defender, true );
				}
			
				if (Spells.Ninjitsu.AnimalForm.UnderTransformation( defender )) //Removes animal form
				{
					AnimalForm.RemoveContext( defender, true );
				}
				
				if (Spells.Spellweaving.ArcaneForm.UnderTransformation( defender )) //Removes weaver forms
				{
					ArcaneForm.RemoveContext( defender, true );
				}
				
				if ( defender.BodyMod == 183 || defender.BodyMod == 184 )
				{
					Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 28, 7, 9915, 0 );
					Effects.PlaySound( defender.Location, defender.Map, 0x229 );
					defender.SendMessage("The tribal paint seems to make you resistant to the attack");
				}
				
				if ( !defender.CanBeginAction( typeof( PolymorphSpell ) ) || !defender.CanBeginAction( typeof( IncognitoSpell ) ) || defender.IsBodyMod )
					return;
					
				if ( defender.BodyMod != 183 || defender.BodyMod != 184 )
				{
					Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 28, 7, 9915, 0 );
					Effects.PlaySound( defender.Location, defender.Map, 0x229 );
				
					Polymorph( defender );
					defender.SendMessage( "The lamia turns you into a frog" );
					
					List<ResistanceMod> mods = new List<ResistanceMod>();
					
					double penalty = 0;
				
					if ( defender.PhysicalResistance > 0 ) 
					{
						penalty = -(defender.PhysicalResistance); 
						mods.Add( new ResistanceMod( ResistanceType.Physical,(int)penalty));
					}
		
					if ( defender.FireResistance > 0 )
					{
						penalty = -(defender.FireResistance);
						mods.Add( new ResistanceMod( ResistanceType.Fire,(int)penalty));
					}

					if ( defender.ColdResistance > 0 )
					{
						penalty = -(defender.ColdResistance);
						mods.Add( new ResistanceMod( ResistanceType.Cold,(int)penalty));
					}

					if ( defender.PoisonResistance > 0 )
					{
						penalty = -(defender.PoisonResistance);
						mods.Add( new ResistanceMod( ResistanceType.Poison,(int)penalty));
					}

					if ( defender.EnergyResistance > 0 )
					{
						penalty = -(defender.EnergyResistance);
						mods.Add( new ResistanceMod( ResistanceType.Energy,(int)penalty));
					}
				
					for ( int i = 0; i < mods.Count; ++i )
						defender.AddResistanceMod( mods[i] );

					timer = new ExpireTimer( defender, mods, TimeSpan.FromSeconds( 30.0 ) ); 
					timer.Start();
					FrogTable[defender] = timer;
				}
			}
		}		
		
		public override bool Unprovokable{ get{ return true; } }
		public override bool Uncalmable{ get{ return true; } }
		
		public override bool AutoDispel{ get{ return true; } }
		public override double AutoDispelChance{ get{ return 0.7; } }
		
		public override double BonusPetDamageScalar{ get{ return 2.0; } }
		public override bool CantbeSupreme{ get{ return true; } }
		
		public override bool IsMLCreature { get { return true;} } 
		public override bool IsMLBoss { get { return true;} }	
		

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