using System;
using Server.Targeting;
using Server.Network;
using Server.Regions;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using System.Collections;

namespace Server.Spells.Third
{
	public class TeleportSpell : Spell
	{
		private static SpellInfo m_Info = new SpellInfo(
				"Teleport", "Rel Por",
				SpellCircle.Third,
				215,
				9031,
				Reagent.Bloodmoss,
				Reagent.MandrakeRoot
			);

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

		public override bool CheckCast()
		{
			if ( Factions.Sigil.ExistsOn( Caster ) )
			{
				Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
				return false;
			}
			else if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
			{
				Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
				return false;
			}

			return SpellHelper.CheckTravel( Caster, TravelCheckType.TeleportFrom );
		}

		public override void OnCast()
		{
			Caster.Target = new InternalTarget( this );
		}

		public void Target( IPoint3D p )
		{
			IPoint3D orig = p;
			Map map = Caster.Map;

			SpellHelper.GetSurfaceTop( ref p );
			
			CustomRegion customregion = (CustomRegion) Region.Find( new Point3D( p ), map ).GetRegion( typeof( CustomRegion ) );

			if ( Factions.Sigil.ExistsOn( Caster ) )
			{
				Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
			}
			else if ( Server.Misc.WeightOverloading.IsOverloaded( Caster ) )
			{
				Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
			}
			else if ( !SpellHelper.CheckTravel( Caster, TravelCheckType.TeleportFrom ) )
			{
			}
			else if ( !SpellHelper.CheckTravel( Caster, map, new Point3D( p ), TravelCheckType.TeleportTo ) )
			{
			}
			else if ( customregion != null && customregion.Controller != null && customregion.Controller.IsRestrictedSpell( (ISpell) this ) )
			{
            Caster.SendMessage( "Na toto misto se nemuzes teleportovat" );
			}
			else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
			{
				Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
			}
			else if ( SpellHelper.CheckMulti( new Point3D( p ), map ) )
			{
				Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
			}
			else if ( CheckSequence() )
			{
				SpellHelper.Turn( Caster, orig );

				Mobile m = Caster;

				Point3D from = m.Location;
				Point3D to = new Point3D( p );
  
				if ( m is PlayerMobile )
				{
               PlayerMobile.TalentEntry te = ((PlayerMobile)m).GetTalent( PlayerMobile.TalentType.KlamnyCil );
                 
               if ( m.Map != Map.Underworld && Utility.RandomDouble() < 0.5 && te != null && te.Enabled && te.Charges >= 1 )
               {
                  ArrayList targets = Utilitky.GetPlayerTargets( m, 3 );
                  
                  if ( targets.Count > 0 )
                  {
                    BaseCreature clone = new TeleportClone( m );
                    clone.MoveToWorld( from, m.Map );
                    clone.FixedParticles( 0x376A, 1, 14, 0x13B5, EffectLayer.Waist );
                    clone.PlaySound( 0x511 );
                    
                    te.Charges -= 1;
                    
                    if ( te.Charges < 1 )
                       te.Enabled = false;
                  }
               }
               
               m.Location = to;
               m.ProcessDelta();
               Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
					Effects.SendLocationParticles( EffectItem.Create(   to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );
				}
				else
				{
					m.FixedParticles( 0x376A, 9, 32, 0x13AF, EffectLayer.Waist );
               m.Location = to;
               m.ProcessDelta();
				}

				m.PlaySound( 0x1FE );
			}

			FinishSequence();
		}

		public class InternalTarget : Target
		{
			private TeleportSpell m_Owner;

			public InternalTarget( TeleportSpell owner ) : base( 12, true, TargetFlags.None )
			{
				m_Owner = owner;
			}

			protected override void OnTarget( Mobile from, object o )
			{
				IPoint3D p = o as IPoint3D;

				if ( p != null )
					m_Owner.Target( p );
			}

			protected override void OnTargetFinish( Mobile from )
			{
				m_Owner.FinishSequence();
			}
		}
	}
}

namespace Server.Mobiles
{
	public class TeleportClone : BaseCreature
	{
		public TeleportClone( Mobile caster ) : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			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 = 1;
			DamageMax = 2;
			
			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 = 0;

			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 = 2;
          		   weapon.MinDamage = 1;
          		   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 );
            }
			}

         CantWalk = true;
         Frozen = true;
			Warmode = false;
			Summoned = true;
			SummonMaster = caster;
			Controlled = false;
			ControlMaster = caster;
			ControlTarget = null;
         ControlOrder = OrderType.Stay;
         
			TimeSpan duration = TimeSpan.FromSeconds( 10 );

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

		public override bool IsHumanInTown() { return false; }
      
		public override void OnThink()
      {
         Hits = HitsMax;
         Warmode = false;
         base.OnThink();
      }

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

		public override bool DeleteCorpseOnDeath { get { return true; } }
		
    	public override bool OnMoveOver( Mobile m )
    	{
    		return true;
    	}
		
      public override void OnDelete()
		{
			Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x3728, 10, 15, 5042 );
         
			Effects.PlaySound( Location, Map, 0x207 );
			ZoogiVejce.EffectCircle( Location, Map, 3, 0x376A );
			
			foreach ( Mobile mobile in this.Map.GetMobilesInRange( this.Location, 3 ) )
			{
				if ( mobile == null || mobile.Deleted || mobile.Blessed || !mobile.Alive || !mobile.InLOS( this ) || mobile is BaseChampion )
					continue;
				
				if ( mobile is BaseCreature && !((BaseCreature)mobile).Controlled && !mobile.IsDeadBondedPet )
				{
					((BaseCreature)mobile).Pacify( this, DateTime.Now + TimeSpan.FromSeconds( 3.0 ) ); // TODO check
				}
			}

			base.OnDelete();
		}
	
      public override bool OnBeforeDeath() 
      { 
// 			Delete();
			return false;
      } 

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

		public TeleportClone( Serial serial ) : base( serial )
		{
		}
      
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.WriteEncodedInt( 0 ); // version
		}

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