using System;
using System.Collections;
using Server;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Mobiles;
using Server.Items;
using Server.Spells.Ninjitsu;

namespace Server.Spells.Ninjitsu
{
	public class MirrorImage : NinjaSpell
	{
		private static Hashtable m_CloneCount = new Hashtable();

		public static bool HasClone( Mobile m )
		{
			return (m_CloneCount.Contains( m ) && ((int)m_CloneCount[m]) > 0);
		}

		public static void AddClone( Mobile m )
		{
			if( m == null )
				return;

			if( m_CloneCount.Contains( m ) )
				m_CloneCount[m] = ((int)m_CloneCount[m] +1);
			else
				m_CloneCount.Add( m, 1 );
		}

		public static void RemoveClone( Mobile m )
		{
			if( m == null )
				return;

			if( m_CloneCount.Contains( m ) )
			{
				m_CloneCount[m] = ((int)m_CloneCount[m] -1);

				if( ((int)m_CloneCount[m]) <= 0 )
					m_CloneCount.Remove( m );
			}
		}

		private static SpellInfo m_Info = new SpellInfo(
			"Mirror Image", null,
			SpellCircle.Sixth, // 1.5s base cast delay
			-1,
			9002
			);

		public override double RequiredSkill{ get{ return 40.0; } }
		public override int RequiredMana{ get{ return 10; } }

		public override bool BlockedByAnimalForm{ get{ return false; } }

		public MirrorImage( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
		{
		}

		public override bool CheckCast()
		{
			if ( Caster.Mounted )
			{
				Caster.SendLocalizedMessage( 1063132 ); // You cannot use this ability while mounted.
				return false;
			}
			else if ( (Caster.Followers + 2) > Caster.FollowersMax )
			{
				Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers.
				return false;
			}
			else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
			{
				Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
				return false;
			}

			return base.CheckCast();
		}

		public override bool CheckDisturb( DisturbType type, bool firstCircle, bool resistable )
		{
			return false;
		}

		public override void OnBeginCast()
		{
			base.OnBeginCast();

			Caster.SendLocalizedMessage( 1063134 ); // You begin to summon a mirror image of yourself.
		}

		public override void OnCast()
		{
			if ( Caster.Mounted )
			{
				Caster.SendLocalizedMessage( 1063132 ); // You cannot use this ability while mounted.
			}
			else if ( (Caster.Followers + 2) > Caster.FollowersMax )
			{
				Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers.
			}
			else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) )
			{
				Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form.
			}
			else if ( CheckSequence() )
			{
				Caster.FixedParticles( 0x376A, 1, 14, 0x13B5, EffectLayer.Waist );
				Caster.PlaySound( 0x511 );

				new Clone( Caster ).MoveToWorld( Caster.Location, Caster.Map );
			}

			FinishSequence();
		}
	}
}

namespace Server.Mobiles
{
	public class Clone : BaseCreature
	{
		private Mobile m_Caster;

		public Clone( Mobile caster ) : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			m_Caster = caster;

			Body = caster.Body;

			Hue = caster.Hue;
			Female = caster.Female;

			Name = caster.Name;
			NameHue = caster.NameHue;

			Title = null;//caster.Title;
			Kills = caster.Kills;

			HairItemID = caster.HairItemID;
			HairHue = caster.HairHue;

			FacialHairItemID = caster.FacialHairItemID;
			FacialHairHue = caster.FacialHairHue;
			
			Dex = (int) (caster.RawDex / 2);
			Int = (int) (caster.RawInt / 2);
			Str = (int) (caster.RawStr / 2);
			Hits = HitsMax;
			Mana = ManaMax;
			Stam = StamMax;
			DamageMin = (int) 5 + (caster.Skills.Ninjitsu.Fixed / 100);
			DamageMax = (int) 10 + (caster.Skills.Ninjitsu.Fixed / 50);
			
			SetResistance( ResistanceType.Physical, caster.PhysicalResistance );
			SetResistance( ResistanceType.Fire, caster.FireResistance );
			SetResistance( ResistanceType.Cold, caster.ColdResistance );
			SetResistance( ResistanceType.Poison, caster.PoisonResistance );
			SetResistance( ResistanceType.Energy, caster.EnergyResistance );
			
			VirtualArmor = 10;
			ControlSlots = 2;

			for ( int i = 0; i < caster.Skills.Length; ++i )
			{
				Skills[i].Base = caster.Skills[i].Base;
				Skills[i].Cap = caster.Skills[i].Cap;
			}

			for( int i = 0; i < caster.Items.Count; i++ )
			{
            if ( caster.Items[i] is BaseWeapon )
            {
               try
			      {
                  BaseWeapon weapon =  (BaseWeapon) Activator.CreateInstance( caster.Items[i].GetType() );

    			      ((Item)weapon).ItemID = caster.Items[i].ItemID;
    			      ((Item)weapon).Hue = caster.Items[i].Hue;
    			      ((Item)weapon).Layer = caster.Items[i].Layer;
    			      ((Item)weapon).Movable = false;
    			      ((Item)weapon).Name = caster.Items[i].Name;
			      
//       		   weapon.Attributes = ((BaseWeapon)caster.Items[i]).Attributes;
//                weapon.WeaponAttributes = ((BaseWeapon)caster.Items[i]).WeaponAttributes;
      		   
                 weapon.Attributes.RegenHits = 0;
                 weapon.Attributes.RegenStam = 0;
                 weapon.Attributes.RegenMana = 0;
                 weapon.Attributes.DefendChance = 0;
                 weapon.Attributes.AttackChance = 0;
                 weapon.Attributes.BonusStr = 0;
                 weapon.Attributes.BonusDex = 0;
                 weapon.Attributes.BonusInt = 0;
                 weapon.Attributes.BonusHits = 0;
                 weapon.Attributes.BonusStam = 0;
                 weapon.Attributes.BonusMana = 0;
                 weapon.Attributes.WeaponDamage = 0;
                 weapon.Attributes.WeaponSpeed = 0;
                 weapon.Attributes.SpellDamage = 0;
                 weapon.Attributes.CastRecovery = 0;
                 weapon.Attributes.CastSpeed = 0;
                 weapon.Attributes.LowerManaCost = 0;
                 weapon.Attributes.LowerRegCost = 0;
                 weapon.Attributes.ReflectPhysical = 0;
                 weapon.Attributes.EnhancePotions = 0;
                 weapon.Attributes.Luck = 0;
                 weapon.Attributes.SpellChanneling = 0;
                 weapon.Attributes.NightSight = 0;

                 weapon.WeaponAttributes.LowerStatReq = 0;
                 weapon.WeaponAttributes.SelfRepair = 0;
                 weapon.WeaponAttributes.HitLeechHits = 0;
                 weapon.WeaponAttributes.HitLeechStam = 0;
                 weapon.WeaponAttributes.HitLeechMana = 0;
                 weapon.WeaponAttributes.HitLowerAttack = 0;
                 weapon.WeaponAttributes.HitLowerDefend = 0;
                 weapon.WeaponAttributes.HitMagicArrow = 0;
                 weapon.WeaponAttributes.HitHarm = 0;
                 weapon.WeaponAttributes.HitFireball = 0;
                 weapon.WeaponAttributes.HitLightning = 0;
                 weapon.WeaponAttributes.HitDispel = 0;
                 weapon.WeaponAttributes.HitColdArea = 0;
                 weapon.WeaponAttributes.HitFireArea = 0;
                 weapon.WeaponAttributes.HitPoisonArea = 0;
                 weapon.WeaponAttributes.HitPhysicalArea = 0;
                 weapon.WeaponAttributes.ResistPhysicalBonus = 0;
                 weapon.WeaponAttributes.ResistFireBonus = 0;
                 weapon.WeaponAttributes.ResistColdBonus = 0;
                 weapon.WeaponAttributes.ResistPoisonBonus = 0;
                 weapon.WeaponAttributes.ResistEnergyBonus = 0;
                 weapon.WeaponAttributes.UseBestSkill = 0;
                 weapon.WeaponAttributes.MageWeapon = 0;
                 weapon.WeaponAttributes.DurabilityBonus = 0;
                 
                  weapon.Animation = ((BaseWeapon)caster.Items[i]).Animation;
          		   weapon.AosElementDamages = ((BaseWeapon)caster.Items[i]).AosElementDamages;
          		   weapon.HitPoints = 50;
          		   weapon.MaxHitPoints = 50;
          		   weapon.HitSound = ((BaseWeapon)caster.Items[i]).HitSound;
          		   weapon.MaxDamage = ((BaseWeapon)caster.Items[i]).MaxDamage;
          		   weapon.MinDamage = ((BaseWeapon)caster.Items[i]).MinDamage;
          		   weapon.MaxRange = ((BaseWeapon)caster.Items[i]).MaxRange;
          		   weapon.MissSound = ((BaseWeapon)caster.Items[i]).MissSound;
          		   weapon.Skill = ((BaseWeapon)caster.Items[i]).Skill;
//           		   weapon.Slayer = ((BaseWeapon)caster.Items[i]).Slayer;
//           		   weapon.Slayer2 = ((BaseWeapon)caster.Items[i]).Slayer2;
                  weapon.Slayer = SlayerName.None;
                  weapon.Slayer2 = SlayerName.None;
          		   weapon.Speed = ((BaseWeapon)caster.Items[i]).Speed;
          		   weapon.Type = ((BaseWeapon)caster.Items[i]).Type;
    		   
                  AddItem( weapon );
			      }
			      catch
			      {
			         caster.SendMessage( "Error pri vytvareni zbrane" );
			      }
            }
            else
            {
			      Item newItem = new Item( caster.Items[i].ItemID );
			      newItem.Hue = caster.Items[i].Hue;
			      newItem.Layer = caster.Items[i].Layer;
			      newItem.Movable = false;
			      newItem.Name = caster.Items[i].Name;               
               AddItem( newItem );
            }
			}

			Warmode = true;

			Summoned = true;
			SummonMaster = caster;

			Controlled = true;
			ControlMaster = caster;
			ControlTarget = caster;
         ControlOrder = OrderType.Guard;
         
			TimeSpan duration = TimeSpan.FromSeconds( 10 + ( caster.Skills.Ninjitsu.Fixed / 6 ) );

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

			MirrorImage.AddClone( m_Caster );
		}

// 		protected override BaseAI ForcedAI { get { return new CloneAI( this ); } }

		public override bool IsHumanInTown() { return false; }

// 		public override void OnDamage( int amount, Mobile from, bool willKill, int typ )
// 		{
// 			Delete();
// 		}

		public override bool DeleteCorpseOnDeath { get { return Summoned; } }
		
    	public override bool OnMoveOver( Mobile m )
    	{
    		return true;
    	}
		
      public override void OnDelete()
		{
			Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x3728, 10, 15, 5042 );

			base.OnDelete();
		}

		public override void OnAfterDelete()
		{
			MirrorImage.RemoveClone( m_Caster );
			base.OnAfterDelete();
		}
		
      public override bool OnBeforeDeath() 
      { 

			MirrorImage.RemoveClone( m_Caster );
			Delete();
			return true;
//          base.OnDeath( c ); 
      } 

		public override bool IsDispellable { get { return false; } }
		public override bool Commandable { get { return true; } }

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

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.WriteEncodedInt( 0 ); // version

			writer.Write( m_Caster );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadEncodedInt();

			m_Caster = reader.ReadMobile();

			MirrorImage.AddClone( m_Caster );
		}
	}
}


// namespace Server.Mobiles
// {
// 	public class CloneAI : BaseAI
// 	{
// 		public CloneAI( Clone m ) : base ( m )
// 		{
// 			m.CurrentSpeed = m.ActiveSpeed;
// 		}
// 
// 		public override bool Think()
// 		{
// 			// Clones only follow their owners
// 			Mobile master = m_Mobile.SummonMaster;
// 
// 			if ( master != null && master.Map == m_Mobile.Map && master.InRange( m_Mobile, m_Mobile.RangePerception ) )
// 			{
// 				int iCurrDist = (int)m_Mobile.GetDistanceToSqrt( master );
// 				bool bRun = (iCurrDist > 5);
// 
// 				WalkMobileRange( master, 2, bRun, 0, 1 );
// 			}
// 			else
// 				WalkRandom( 2, 2, 1 );
// 
// 			return true;
// 		}
// 	}
// }
