using System;
using Server;
using Server.Mobiles;

namespace Server.Items
{
	public class HealingStone : Item
	{
		private Mobile m_Caster;
		private int m_LifeForce;
        private int m_MaxLifeForce;
        private int m_MaxHeal;
        private int m_MaxHealTotal;
        private Timer m_Timer;

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Caster { get { return m_Caster; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int LifeForce { get { return m_LifeForce; } set { m_LifeForce = value;  InvalidateProperties(); } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int MaxLifeForce { get { return m_MaxLifeForce; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int MaxHeal { get { return m_MaxHeal; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int MaxHealTotal { get { return m_MaxHealTotal; } }

        public override bool Nontransferable { get { return true; } }

		[Constructable]
		public HealingStone( Mobile caster, int amount, int maxHeal ) : base( 0x4078 )
		{
			m_Caster = caster;
			m_LifeForce = amount;
            m_MaxHeal = maxHeal;

            m_MaxLifeForce = amount;
            m_MaxHealTotal = maxHeal;

            LootType = LootType.Blessed;
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( !from.InRange( this.GetWorldLocation(), 1 ) )
			{
				from.SendLocalizedMessage( 502138 ); // That is too far away for you to use
				return;
			}
			else if ( from != m_Caster )
			{
			}
            else if (!BasePotion.HasFreeHand(from))
            {
                from.SendLocalizedMessage(1080116); // You must have a free hand to use a Healing Stone.
            }
            else if (from.Hits >= from.HitsMax && !from.Poisoned)
            {
                from.SendLocalizedMessage(1049547); //You are already at full health.
            }
            else if (from.BeginAction(typeof(HealingStone)))
            {
                if (m_MaxHeal > m_LifeForce)
                    m_MaxHeal = m_LifeForce;

                if (from.Poisoned)
                {
                    int toUse = Math.Min(120, from.Poison.RealLevel * 25);

                    if (m_MaxLifeForce < toUse)
                        from.SendLocalizedMessage(1115265); //Your Mysticism, Focus, or Imbuing Skills are not enough to use the heal stone to cure yourself.
                    else if (m_LifeForce < toUse)
                    {
                        from.SendLocalizedMessage(1115264); //Your healing stone does not have enough energy to remove the poison.
                        LifeForce -= toUse / 3;
                    }
                    else
                    {
                        from.CurePoison(from);

                        from.SendLocalizedMessage(500231); // You feel cured of poison!

                        from.FixedEffect(0x373A, 10, 15);
                        from.PlaySound(0x1E0);

                        LifeForce -= toUse;
                    }

                    if (m_LifeForce <= 0)
                        this.Consume();

                    Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(ReleaseHealLock), from);
                    return;
                }
                else
                {
                    int toHeal = Math.Min(m_MaxHeal, from.HitsMax - from.Hits);
                    from.Heal(toHeal);
                    Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(ReleaseHealLock), from);

                    from.FixedParticles(0x376A, 9, 32, 5030, EffectLayer.Waist);
                    from.PlaySound(0x202);

                    LifeForce -= toHeal;
                    m_MaxHeal = 1;
                }

                if (m_LifeForce <= 0)
                {
                    from.SendLocalizedMessage(1115266); //The healing stone has used up all its energy and has been destroyed.
                    this.Consume();
                }
                else
                {
                    if (m_Timer != null)
                        m_Timer.Stop();

                    m_Timer = new InternalTimer(this);
                }
            }
            else
                from.SendLocalizedMessage(1095172); // You must wait a few seconds before using another Healing Stone.
		}

        public void OnTick()
        {
            if (m_MaxHeal < m_MaxHealTotal)
            {
                int maxToHeal = m_MaxHealTotal - m_MaxHeal;
                m_MaxHeal += Math.Min(maxToHeal, m_MaxHealTotal / 15);

                if (m_MaxHeal > m_MaxHealTotal)
                    m_MaxHeal = m_MaxHealTotal;
            }
        }

        private class InternalTimer : Timer
        {
            private HealingStone m_Stone;
            private int m_Ticks;

            public InternalTimer ( HealingStone stone ) : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
            {
                m_Stone = stone;
                m_Ticks = 0;
                this.Start();
            }

            protected override void OnTick()
            {
                m_Ticks++;

                m_Stone.OnTick();

                if (m_Ticks >= 15)
                    this.Stop();
            }
        }

		public override bool DropToWorld( Mobile from, Point3D p )
		{
			Delete();
			return false;
		}

		public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
		{
			return false;
		}

		private static void ReleaseHealLock( object state )
		{
			((Mobile)state).EndAction( typeof( HealingStone ) );
		}

        public override void Delete()
        {
            if (m_Timer != null)
            {
                m_Timer.Stop();
                m_Timer = null;
            }

            base.Delete();
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);

            list.Add(1115274, m_LifeForce.ToString());
        }

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

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

            writer.Write(m_Caster);
            writer.Write(m_LifeForce);
            writer.Write(m_MaxLifeForce);
            writer.Write(m_MaxHeal);
            writer.Write(m_MaxHealTotal);
        }

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

            switch (version)
            {
                case 1:
                    m_Caster = reader.ReadMobile();
                    m_LifeForce = reader.ReadInt();
                    m_MaxLifeForce = reader.ReadInt();
                    m_MaxHeal = reader.ReadInt();
                    m_MaxHealTotal = reader.ReadInt();
                    break;
                case 0:
                    break;
            }

            if (m_LifeForce <= 0)
            {
                Delete();
            }
        }
	}
}