/**********************************************************
RunUO AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by Red Squirrel on Mar-04-2011 09:28:15pm
Filepath: scripts\Mobiles\Healers\BaseHealer.cs
Lines of code: 186

Description: 

***********************************************************/


using System;
using System.Collections;
using Server;
using Server.Misc;
using Server.Items;
using Server.Gumps;
using Server.Targeting;
using Server.Spells.Fourth;

namespace Server.Mobiles
{
	public abstract class BaseHealer : BaseVendor
	{
		private ArrayList m_SBInfos = new ArrayList();
		protected override ArrayList SBInfos{ get { return m_SBInfos; } }

		public override bool IsActiveVendor{ get{ return false; } }
		public override bool IsInvulnerable{ get{ return false; } }
		public override bool CantbeParagon { get { return true;} }				

		public override void InitSBInfo()
		{
		}

		public BaseHealer() : base( null )
		{
			if ( !IsInvulnerable )
			{
				AI = AIType.AI_Super;
				ActiveSpeed = 0.2;
				PassiveSpeed = 0.8;
				RangePerception = BaseCreature.DefaultRangePerception;
				FightMode = FightMode.Aggressor;
			}

			SpeechHue = 0;

			SetStr( 304, 400 );
			SetDex( 102, 150 );
			SetInt( 204, 300 );

			SetDamage( 10, 23 );

			SetDamageType( ResistanceType.Physical, 100 );

			SetResistance( ResistanceType.Physical, 40, 50 );
			SetResistance( ResistanceType.Fire, 40, 50 );
			SetResistance( ResistanceType.Cold, 40, 50 );
			SetResistance( ResistanceType.Poison, 40, 50 );
			SetResistance( ResistanceType.Energy, 40, 50 );

			SetSkill( SkillName.Anatomy, 75.0, 97.5 );
			SetSkill( SkillName.EvalInt, 82.0, 100.0 );
			SetSkill( SkillName.Healing, 75.0, 97.5 );
			SetSkill( SkillName.Magery, 130.0 );			
			SetSkill( SkillName.MagicResist, 82.0, 100.0 );
			SetSkill( SkillName.Tactics, 82.0, 100.0 );

			Fame = 1000;
			Karma = 10000;

			PackItem( new Bandage( Utility.RandomMinMax( 5, 10 ) ) );
			PackItem( new HealPotion() );
			PackItem( new CurePotion() );
		}

		public override VendorShoeType ShoeType{ get{ return VendorShoeType.Sandals; } }

		public virtual int GetRobeColor()
		{
			return Utility.RandomYellowHue();
		}

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

			AddItem( new Robe( GetRobeColor() ) );
		}

		public virtual bool HealsYoungPlayers{ get{ return true; } }

		public virtual bool CheckResurrect( Mobile m )
		{
			return true;
		}

		private DateTime m_NextResurrect;
		private static TimeSpan ResurrectDelay = TimeSpan.FromSeconds( 2.0 );

		public virtual void OfferResurrection( Mobile m )
		{
			Direction = GetDirectionTo( m );
			Say( 501224 ); // Thou hast strayed from the path of virtue, but thou still deservest a second chance.

			m.PlaySound( 0x214 );
			m.FixedEffect( 0x376A, 10, 16 );

			m.CloseGump( typeof( ResurrectGump ) );
			m.SendGump( new ResurrectGump( m, ResurrectMessage.Healer ) );
			
			Timer healtimer = new HealTimer(m,this);
			healtimer.Start();
		}
		
		private static Hashtable m_ToHealTable = new Hashtable();
		
		private class HealTimer : Timer
		{
			private Mobile m_Target;
			private BaseHealer m_Healer;
			private DateTime m_End;
			private TimeSpan expiretime=TimeSpan.FromSeconds( 10.0 );
			

			public HealTimer( Mobile target,BaseHealer healer ) : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 10.0 ) )
			{
				m_Target = target;
				m_Healer=healer;
				m_End = DateTime.Now + TimeSpan.FromMinutes(10);
				m_ToHealTable[m_Target] = m_Target;

				Priority = TimerPriority.OneSecond;
			}

			protected override void OnTick()
			{
			if(m_Target.Hits>=m_Target.HitsMax || !m_Healer.InRange(m_Target,10))m_ToHealTable.Remove( m_Target );
			else m_Healer.ToHealMobile=m_Target;
			
			
				if ( m_Target.Deleted|| !m_Target.Alive || DateTime.Now >= m_End || !m_ToHealTable.Contains( m_Target ))
				{
					m_ToHealTable.Remove( m_Target );

					Stop();
				}
			}
		}			
		

		public virtual void OfferHeal( PlayerMobile m )
		{
			Direction = GetDirectionTo( m );

			if ( m.CheckYoungHealTime() )
			{
				Say( 501229 ); // You look like you need some healing my child.

				m.PlaySound( 0x1F2 );
				m.FixedEffect( 0x376A, 9, 32 );

				m.Hits = m.HitsMax;
			}
			else
			{
				Say( 501228 ); // I can do no more for you at this time.
			}
		}
		
		private Mobile ToHealMobile;

		public override void OnMovement( Mobile m, Point3D oldLocation )
		{		
			if ( !m.Frozen && DateTime.Now >= m_NextResurrect && InRange( m, 4 ) && !InRange( oldLocation, 4 ) && InLOS( m ) )
			{
				if ( !m.Alive )
				{
					m_NextResurrect = DateTime.Now + ResurrectDelay;

					if ( m.Map == null || !m.Map.CanFit( m.Location, 16, false, false ) )
					{
						m.SendLocalizedMessage( 502391 ); // Thou can not be resurrected there!
					}
					else if ( CheckResurrect( m ) )
					{
						OfferResurrection( m );
					}
				}
				else if ( this.HealsYoungPlayers && m.Hits < m.HitsMax && m is PlayerMobile && ((PlayerMobile)m).Young )
				{
					OfferHeal( (PlayerMobile) m );
				}
			}
		}
		
		
		public override void OnThink()
        {	
			base.OnThink();
			
			if(Combatant!=null || ToHealMobile==null)return;
			
			if(ToHealMobile.Hits==ToHealMobile.HitsMax)
			{
			ToHealMobile=null;
			return;
			}
		
			//check if beneficial target is pending (most likely a heal - but slight chance to pickup any other spell it happened to be casting)
			Target targ = this.Target;
			
			if(targ!=null && ((targ.Flags & TargetFlags.Beneficial) != 0) && ToHealMobile!=null)
			{
			targ.Invoke( this, ToHealMobile );			
			ToHealMobile=null;			
			return;
			}
			
			if(this.Spell!=null && this.Spell.IsCasting)return;
			
			//if we made it here, we have a person we need to heal, so we cast greater heal
			
			if(ToHealMobile.Poison!=null)new ArchCureSpell( this, null ).Cast();
			else new GreaterHealSpell( this, null ).Cast();		
		}
		
		
		

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

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

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

			if ( !IsInvulnerable )
			{
				AI = AIType.AI_Super;
				ActiveSpeed = 0.2;
				PassiveSpeed = 0.8;
				RangePerception = BaseCreature.DefaultRangePerception;
				FightMode = FightMode.Aggressor;
			}
		}
	}
}