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

namespace Server.Engines.XmlSpawner2
{
	public class XmlLightning : XmlAttachment
	{
		private int m_Damage = 0;
		private TimeSpan m_Refractory = TimeSpan.FromSeconds(5);    // 5 seconds default time between activations
		private DateTime m_EndTime;
		private int proximityrange = 5;                 // default movement activation from 5 tiles away

		[CommandProperty( AccessLevel.GameMaster )]
		public int Damage { get{ return m_Damage; } set { m_Damage = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory  = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Range { get { return proximityrange; } set { proximityrange  = value; } }

		// These are the various ways in which the message attachment can be constructed.
		// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
		// Other overloads could be defined to handle other types of arguments

		// a serial constructor is REQUIRED
		public XmlLightning(ASerial serial) :  base(serial)
		{
		}
        
		[Attachable]
		public XmlLightning(int damage)
		{
			m_Damage = damage;
		}

		[Attachable]
		public XmlLightning(int damage, double refractory)
		{
			m_Damage = damage;
			Refractory = TimeSpan.FromSeconds(refractory);

		}
        
		[Attachable]
		public XmlLightning(int damage, double refractory, double expiresin)
		{
			m_Damage = damage;
			Expiration = TimeSpan.FromMinutes(expiresin);
			Refractory = TimeSpan.FromSeconds(refractory);
		}


		// note that this method will be called when attached to either a mobile or a weapon
		// when attached to a weapon, only that weapon will do additional damage
		// when attached to a mobile, any weapon the mobile wields will do additional damage
		public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
		{
			// if it is still refractory then return
			if(DateTime.UtcNow < m_EndTime) return;

			int damage = 0;

			if(m_Damage > 0)
				damage = Utility.Random(m_Damage);

			if(defender != null && attacker != null && damage > 0)
			{
				defender.BoltEffect( 0 );

				SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );

				m_EndTime = DateTime.UtcNow + Refractory;
			}
		}
        
		//public override bool HandlesOnMovement { get { return true; } }

		// restrict the movement detection feature to non-movable items

		public override bool HandlesOnMovement 
		{ 
			get 
			{ 
				if(AttachedTo is Item && !((Item)AttachedTo).Movable)
					return true;
				else
					return false; 
			} 
		}



		public override void OnMovement(MovementEventArgs e )
		{
			base.OnMovement(e);
   
			if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;

			if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
			{
				OnTrigger(null, e.Mobile);
			} 
			else
				return;
		}

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

			writer.Write( (int) 1 );
			// version 1
			writer.Write(proximityrange);
			// version 0
			writer.Write(m_Damage);
			writer.Write(m_Refractory);
			writer.Write(m_EndTime - DateTime.UtcNow);

		}

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

			int version = reader.ReadInt();
			switch(version)
			{
				case 1:
					proximityrange = reader.ReadInt();
					goto case 0;
				case 0:
					// version 0
					m_Damage = reader.ReadInt();
					Refractory = reader.ReadTimeSpan();
					TimeSpan remaining = reader.ReadTimeSpan();
					m_EndTime = DateTime.UtcNow + remaining;
					break;
			}
		}

		public override string OnIdentify(Mobile from)
		{
			string msg = null;

			if(Expiration > TimeSpan.Zero)
			{
				msg = String.Format("Lightning Damage {0} expires in {1} mins", m_Damage, Expiration.TotalMinutes);
			} 
			else
			{
				msg = String.Format("Lightning Damage {0}",m_Damage);
			}

			if(Refractory > TimeSpan.Zero)
			{
				return String.Format("{0} - {1} secs between uses",msg, Refractory.TotalSeconds);
			} 
			else
				return msg;
		}
		
		public override void OnTrigger(object activator, Mobile m)
		{
			if(m == null ) return;

			// if it is still refractory then return
			if(DateTime.UtcNow < m_EndTime) return;

			int damage = 0;

			if(m_Damage > 0)
				damage = Utility.Random(m_Damage);

			if(damage > 0)
			{
				m.BoltEffect( 0 );

				SpellHelper.Damage( TimeSpan.Zero, m, damage, 0, 0, 0, 0, 100 );
			}

			m_EndTime = DateTime.UtcNow + Refractory;

		}    
	}
}
