/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\_custom\quests\_core\KillObjective.cs
Lines of code: 199
***********************************************************/


using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.Items;

namespace Server.Engines.Quests
{
	public class KillObjective : QuestObjective
	{
		public override object Message{ get {return "nothing here!";} }

		private List<QuestKillEntry> tokill= new List<QuestKillEntry>();

		
		public void AddQKE(QuestKillEntry qke)
		{
			tokill.Add(qke);
		}
		
		public void AddQKE(string ptokill,string ptokillname,int amt)
		{
			tokill.Add(new QuestKillEntry(ptokill,ptokillname,amt));
		}
		
		public void AddQKE(string ptokill,string ptokillname,int amt,Rectangle2D loc,Map map)
		{
			tokill.Add(new QuestKillEntry(ptokill,ptokillname,amt,new QuestKillLocation(loc,map)));
		}
		


		public override void ChildDeserialize( GenericReader reader )
		{
			int version = reader.ReadEncodedInt();	

			int tokillsize=reader.ReadInt();
			for(int i=0;i<tokillsize;i++)
			{
				QuestKillEntry kqe = new QuestKillEntry();
				kqe.Deserialize(reader);				
				tokill.Add(kqe);
			}
			
			base.ChildDeserialize(reader);
		}

		public override void ChildSerialize( GenericWriter writer )
		{
			writer.WriteEncodedInt( (int) 0 ); // version
			
			int tokillcount=tokill.Count;
			writer.Write(tokillcount);          
			for(int i=0;i<tokillcount;i++)
			{
				tokill[i].Serialize(writer);				
			}			
			
			base.ChildSerialize(writer);
		}

		public override void Complete()
		{
			CurProgress = MaxProgress;
		}
		
		private object KillList()
		{
			object contents="";
			
			foreach(QuestKillEntry entry in tokill)
			{
				string progress=(entry.Done) ? "   [Completed]" : "   [" + entry.Killed + "/" + entry.Amt + "]";
				
				contents+=entry.ToKillName + progress + "<br>";
			}

			return contents;
		}
		

		public override void RenderMessage( BaseQuestGump gump )
		{			
			gump.AddHtmlObject( 79, 130, 300, 100,"Kill specified creatures:", BaseQuestGump.Blue, false, false );
			
			gump.AddHtmlObject( 79, 145, 300, 90, KillList(), BaseQuestGump.Blue, false, true );
		}
		



		public override void OnKill( BaseCreature creature, Container corpse )
		{
			bool allkilled=true;	

			Debugger.Write("killobjective","Killed {0}, checking if its part of quest...",creature);
			
			Type creaturetype=creature.GetType();
			
			foreach(QuestKillEntry entry in tokill)
			{
				Debugger.Write("killobjective","QuestKillEntry:{0} {1}/{2}...done:{3}",entry.ToKillName,entry.Killed,entry.Amt,entry.Done);

				if(entry.CheckKill(creaturetype,corpse.Location,corpse.Map) && entry.Done && allkilled)
				{
					Debugger.Write("killobjective","{0} done",entry.ToKillName);
					allkilled=true;	
				}

				if(!entry.Done)allkilled=false;				

			}	
			
			if(allkilled)
			{
				Debugger.Write("killobjective","objective completed");
				if(System!=null)System.ShowQuestLogUpdated();
				Complete();
			}
		
		}


	}
	
	
	
	
	
	
	
	
	
	public class QuestKillEntry
	{
		private string m_tokill;
		private string m_tokillname;
		private int m_amt;
		private int m_killed;
		
		public string ToKill { get {return m_tokill;} }
		public string ToKillName { get {return m_tokillname;} }
		public int Amt { get {return m_amt;} }
		public int Killed { get {return m_killed;} set {m_killed=value;} }
		public bool Done{get {return Killed>=Amt;}}
		
		private List <QuestKillLocation> m_locations;			
	
		public QuestKillEntry(string ptokill,string ptokillname,int pamt,QuestKillLocation loc)
		{
			m_tokill=ptokill;
			m_amt=pamt;
			m_tokillname=ptokillname;
			m_locations=new List<QuestKillLocation>();
			if(loc!=null)m_locations.Add(loc);
		}
		
		public QuestKillEntry(string ptokill,string ptokillname,int pamt) : this(ptokill,ptokillname,pamt,null)
		{
		}	

		public QuestKillEntry()
		{
			m_locations=new List<QuestKillLocation>();
		}			
		
		public void AddLocation(Rectangle2D rect,Map map)
		{
			m_locations.Add(new QuestKillLocation(rect,map));
		}
		
		public bool CheckKill(Type KT,Point3D location,Map map)
		{
			Debugger.Write("killobjective","{0} checking kill for {1} @ {2} {3}",ToKillName,KT,location,map);
			Type NT = SpawnerType.GetType(ToKill);
			if(KT==NT)
			{
				Debugger.Write("killobjective","type is right...");
				bool valid=false;
				
				if(m_locations.Count>0)
				{
					foreach(QuestKillLocation qkl in m_locations)
					{
						if(qkl.Has(location,map))
						{
							Debugger.Write("killobjective","location is right...");
							valid=true;
							break;
						}
					}				
				}
				else valid=true;	

				Debugger.Write("killobjective","valid={0}",valid);
				
				if(valid)
				{
					Killed++;	
					return true;
				}
			}
			return false;
		}
		
		
		public void Serialize(GenericWriter writer)
		{
			writer.Write(0); //version
			writer.Write(m_tokill);
			writer.Write(m_tokillname);
			writer.Write(m_amt);
			writer.Write(m_killed);
			
			writer.Write(m_locations.Count);
			for(int i=0;i<m_locations.Count;i++)
			{
				writer.Write(m_locations[i].LocRect);
				writer.Write(m_locations[i].LocMap);				
			}
		}
		
		public void Deserialize(GenericReader reader)
		{
			int version = reader.ReadInt();
			m_tokill=reader.ReadString();
			m_tokillname=reader.ReadString();			
			m_amt=reader.ReadInt();
			m_killed=reader.ReadInt();
			
			int tmpsize=reader.ReadInt();
			
			for(int i=0;i<tmpsize;i++)
			{
				Rectangle2D tmprect=reader.ReadRect2D();
				Map tmpmap=reader.ReadMap();
				m_locations.Add(new QuestKillLocation(tmprect,tmpmap));	
			}
		}		
	}
	

	public class QuestKillLocation
	{
		private Rectangle2D m_rect;
		private Map m_map;
		
		public Rectangle2D LocRect { get {return m_rect;} }
		public Map LocMap { get {return m_map;} }			
	
		public QuestKillLocation(Rectangle2D prect,Map pmap)
		{
			m_rect=prect;
			m_map=pmap;
		}
		
		public bool Has(Point3D loc,Map map)
		{
		return (LocRect.Contains(loc) && LocMap==map);
		}
		
	}	
	
}