using System;
using Server;
using Server.Gumps;
using Server.Mobiles;
using Server.Targeting;
using Server.Network;

namespace Server
{
	public class SacrificeVirtue
	{
		private static TimeSpan GainDelay = TimeSpan.FromDays( 1.0 );
		private static TimeSpan LossDelay = TimeSpan.FromDays( 7.0 );
		private const int LossAmount = 500;

		public static void Initialize()
		{
			VirtueGump.Register( 110, new OnVirtueUsed( OnVirtueUsed ) );
		}

		public static void OnVirtueUsed( Mobile from )
		{
			if ( !from.Hidden )
			{
				if ( from.Alive )
					from.Target = new InternalTarget();
				else
					Resurrect( from );
			}
			else 
				from.SendLocalizedMessage( 1052015 ); // You cannot do that while hidden.
		}

		public static void CheckAtrophy( Mobile from )
		{
			PlayerMobile pm = from as PlayerMobile;

			if ( pm == null )
				return;

			try
			{
				if ( (pm.LastSacrificeLoss + LossDelay) < DateTime.Now )
				{
					if ( VirtueHelper.Atrophy( from, VirtueName.Sacrifice, LossAmount ) )
						from.SendLocalizedMessage( 1052041 ); // You have lost some Sacrifice.

					VirtueLevel level = VirtueHelper.GetLevel( from, VirtueName.Sacrifice );

					pm.AvailableResurrects = (int)level;
					pm.LastSacrificeLoss = DateTime.Now;
				}
			}
			catch
			{
			}
		}

		public static void Resurrect( Mobile from )
		{
			if ( from.Alive )
				return;

			PlayerMobile pm = from as PlayerMobile;

			if ( pm == null )
				return;

			if ( from.Criminal )
			{
				from.SendLocalizedMessage( 1052007 ); // You cannot use this ability while flagged as a criminal.
			}
			else if ( !VirtueHelper.IsSeeker( from, VirtueName.Sacrifice ) )
			{
				from.SendLocalizedMessage( 1052004 ); // You cannot use this ability.
			}
			else if ( pm.AvailableResurrects <= 0 )
			{
				from.SendLocalizedMessage( 1052005 ); // You do not have any resurrections left.
			}
			else
			{
				/*
				 * We need to wait for them to accept the gump or they can just use
				 * Sacrifice and cancel to have items in their backpack for free.
				 */
				from.CloseGump( typeof( ResurrectGump ) );
				from.SendGump( new ResurrectGump( from, true ) );
			}
		}

		public static void Sacrifice( Mobile from, object targeted )
		{
			if ( !from.CheckAlive() )
				return;

			PlayerMobile pm = from as PlayerMobile;

			if ( pm == null )
				return;

			Mobile targ = targeted as Mobile;

			if ( targ == null )
				return;

			if ( !ValidateCreature( targ ) )
			{
				from.SendLocalizedMessage( 1052014 ); // You cannot sacrifice your fame for that creature.
			}
			else if ( ((targ.Hits * 100) / Math.Max( targ.HitsMax, 1 )) < 90 )
			{
				from.SendLocalizedMessage( 1052013 ); // You cannot sacrifice for this monster because it is too damaged.
			}
			else if ( from.Hidden )
			{
				from.SendLocalizedMessage( 1052015 ); // You cannot do that while hidden.
			}
			else if ( VirtueHelper.IsHighestPath( from, VirtueName.Sacrifice ) )
			{
				from.SendLocalizedMessage( 1052068 ); // You have already attained the highest path in this virtue.
			}
			else if ( from.Fame < 2500 )
			{
				from.SendLocalizedMessage( 1052017 ); // You do not have enough fame to sacrifice.
			}
			else if ( DateTime.Now < (pm.LastSacrificeGain + GainDelay) )
			{
				from.SendLocalizedMessage( 1052016 ); // You must wait approximately one day before sacrificing again.
			}
			else
			{
				int toGain;

				if( from.Fame < 5000 )
					toGain = 500;
				else if( from.Fame < 10000 )
					toGain = 1000;
				else
					toGain = 2000;

				from.Fame = 0;

				// I have seen the error of my ways!
				targ.PublicOverheadMessage( MessageType.Regular, 0x3B2, 1052009 );

				from.SendLocalizedMessage( 1052010 ); // You have set the creature free.

				Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerCallback( targ.Delete ) );

				pm.LastSacrificeGain = DateTime.Now;

				bool gainedPath = false;

				if ( VirtueHelper.Award( from, VirtueName.Sacrifice, toGain, ref gainedPath ) )
				{
					if ( gainedPath )
					{
						from.SendLocalizedMessage( 1052008 ); // You have gained a path in Sacrifice!

						if ( pm.AvailableResurrects < 3 )
							++pm.AvailableResurrects;
					}
					else
					{
						from.SendLocalizedMessage( 1054160 ); // You have gained in sacrifice.
					}
				}

				from.SendLocalizedMessage( 1052016 ); // You must wait approximately one day before sacrificing again.
			}
		}

		public static bool ValidateCreature( Mobile m )
		{
			if ( m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned) )
				return false;

			return ( m is Lich || m is Succubus || m is Daemon || m is EvilMage || m is EnslavedGargoyle || m is GargoyleEnforcer );
		}

		private class InternalTarget : Target
		{
			public InternalTarget() : base( 8, false, TargetFlags.None )
			{
			}

			protected override void OnTarget( Mobile from, object targeted )
			{
				Sacrifice( from, targeted );
			}
		}
	}
}