/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\_custom\items\quivers\quiver.cs
Lines of code: 251
***********************************************************/



 using System;
 using Server.Targeting;
 using Server.Mobiles;
 
 namespace Server.Items
{
 

	public class Quiver : BaseClothing
	{		
		private int m_Arrows, m_Bolts,m_MaxArrows=1000,m_MaxBolts=1000;
		private AosElementAttributes m_AosElementDamages;
		private int m_WeightReduction;
		
		
		DateTime LastDropTime;
		bool RestrictOpen=false;
		
			
		public override string DefaultName
		{
			get { return "Quiver"; }//Not using cliloc as they do not work with quivers (not sure why)
		}
		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public AosElementAttributes AosElementDamages
		{
			get { return m_AosElementDamages; }
			set { }
		}		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int WeightReduction
		{
			get{ return m_WeightReduction; }
			set{ 
			if(value>100)m_WeightReduction=100;
			else m_WeightReduction = value;			
			InvalidateProperties();UpdateWeight();
			}
		}		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Arrows
		{
			get{ return m_Arrows; }
			set{ m_Arrows = value;InvalidateProperties();UpdateWeight();}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public int Bolts
		{
			get{ return m_Bolts; }
			set{ m_Bolts = value; InvalidateProperties();UpdateWeight(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public int MaxArrows
		{
			get{ return m_MaxArrows; }
			set{ m_MaxArrows = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int MaxBolts
		{
			get{ return m_MaxBolts; }
			set{ m_MaxBolts = value; InvalidateProperties(); }
		}			
		



		public override void GetProperties( ObjectPropertyList list )
		{
			base.GetProperties( list );
		
		
		
			int phys, fire, cold, pois, nrgy,chaos,direct;
			
			phys = m_AosElementDamages.Physical;			
			fire = m_AosElementDamages.Fire;
			cold = m_AosElementDamages.Cold;
			pois = m_AosElementDamages.Poison;
			nrgy = m_AosElementDamages.Energy;
			chaos = m_AosElementDamages.Chaos;
			direct = m_AosElementDamages.Direct;
						
			
			if ( phys > 0 )
				list.Add( 1060403, phys.ToString() ); // physical damage ~1_val~%

			if ( fire != 0 )
				list.Add( 1060405, fire.ToString() ); // fire damage ~1_val~%

			if ( cold != 0 )
				list.Add( 1060404, cold.ToString() ); // cold damage ~1_val~%

			if ( pois != 0 )
				list.Add( 1060406, pois.ToString() ); // poison damage ~1_val~%

			if ( nrgy != 0 )
				list.Add( 1060407, nrgy.ToString() ); // energy damage ~1_val~%
				
			if ( chaos != 0 )
				list.Add( 1072846, chaos.ToString() ); // chaos damage ~1_val~%		

			if( direct != 0)
				list.Add(1060658,"Direct Damage \t{0}", String.Format("{0}%",direct.ToString()));
				
			
			if(m_WeightReduction>0)list.Add( 1072210, m_WeightReduction.ToString()); //Weight reduction: ~1_PERCENTAGE~%

			list.Add( 1075265, String.Format("{0}\t{1}",m_Arrows,m_MaxArrows )); //Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows
			list.Add( 1075266, String.Format("{0}\t{1}",m_Bolts,m_MaxBolts )); //Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows		
			
		}
		
		public override void AddNameProperties( ObjectPropertyList list )
		{	
			base.AddNameProperties( list );	

		}
		
		
		
		public override void OnDoubleClick( Mobile from )
		{
			//this is a workaround to razor treating this as a container and sending double click packet when not desired
			if((from is PlayerMobile && ((((PlayerMobile)from).LoginTime+TimeSpan.FromSeconds(10))>DateTime.Now)) || ((LastDropTime+TimeSpan.FromSeconds(10))>DateTime.Now && RestrictOpen))
			{
			RestrictOpen=false;
			return;
			}
			
		     RestrictOpen=false;
			
		
			if(ParentEntity!=from && !IsChildOf( from.Backpack ))
			{
			from.SendMessage("This is not accessable");
			return;
			}
			
			//make sure its not full
			if(Arrows>=MaxArrows && Bolts>=MaxBolts)
			{
			from.SendMessage("This quiver is full!");
			return;
			}
			
		
		from.Target = new InternalTarget( from,this );
		}	
		
		public void UpdateWeight()
		{
		double tmp = (double)((double)Arrows/10)+(double)((double)Bolts/10);
				
		Weight=5+tmp-(tmp*(double)((double)m_WeightReduction/100));
		}		
		
		public bool ConsumeAmmo(Type type)
		{
			if(type == typeof(Arrow) && m_Arrows>0)
			{
			m_Arrows--;
			InvalidateProperties();
			UpdateWeight();
			return true;
			}
			if(type == typeof(Bolt) && m_Bolts>0)
			{
			m_Bolts--;
			InvalidateProperties();
			UpdateWeight();
			return true;
			}
		
		return false;		
		}
		
		
		//razor treats this as a container and tries to open it when you drag it (to count items) this attempts to prevent this
		public override bool OnDragLift( Mobile from )
		{
		LastDropTime=DateTime.Now;
		RestrictOpen=true;

			return base.OnDragLift(from);
		}		
		

		public class InternalTarget : Target
		{
		Mobile m_mob;
		Quiver m_quiv;

			public InternalTarget(Mobile mob,Quiver quiv) : base( 12, false, TargetFlags.None )
			{
			m_mob=mob;
			m_quiv=quiv;
						
			mob.SendMessage("Target ammo to insert into the quiver (Targeting quiver again will unload it)");
			}

			protected override void OnTarget( Mobile from, object o )
			{
			//do the sanity check again
				if(m_quiv.ParentEntity!=from && !m_quiv.IsChildOf( from.Backpack ))
				{
				from.SendMessage("This is not accessable");
				return;
				}
				
			if(from!=m_mob)return;//I cant see how this can happen, but just in case
				

		
				
			int toadd=0;
			int ammotype=0; //1: arrow, 2: bolt
			
			Item ammo;
			
			//validate targetted item
			
				if (o == m_quiv) 
				{
					if(m_quiv.Arrows!=0 || m_quiv.Bolts!=0)
					{
						from.SendMessage("You retrieve the ammunition from your quiver");
						
						if (m_quiv.Arrows>0)
							from.AddToBackpack(new Arrow(m_quiv.Arrows));
						if (m_quiv.Bolts>0)
							from.AddToBackpack(new Bolt(m_quiv.Bolts));
							
						m_quiv.Arrows=0;
						m_quiv.Bolts=0;
					}
					else from.SendMessage("The quiver is empty!");
					return;
				}
				else if(o is Arrow)
				{
				ammo = (Item)o;
				ammotype=1;
				}
				else if(o is Bolt)
				{
				ammo = (Item)o;
				ammotype=2;
				}			
				else
				{
				from.SendMessage("You may only store arrows or bolts in a quiver");
				return;
				}			
				
				if(!ammo.IsChildOf( from.Backpack ))
				{
				from.SendMessage("Ammo must be in your backpack!");
				return;
				}

			
			//determine how many to take			
			toadd=ammo.Amount;
			

			//add ammo
			if(ammotype==1)
			{
			if(toadd>(m_quiv.MaxArrows-m_quiv.Arrows))toadd=(m_quiv.MaxArrows-m_quiv.Arrows);
			m_quiv.Arrows+=toadd;
			}
			if(ammotype==2)
			{
			if(toadd>(m_quiv.MaxBolts-m_quiv.Bolts))toadd=(m_quiv.MaxBolts-m_quiv.Bolts);
			m_quiv.Bolts+=toadd;
			}
			
			//make sure its not full
			if(toadd<=0)
			{
			from.SendMessage("This quiver is full!");
			return;
			}			
			
			if(toadd>=ammo.Amount)ammo.Delete();
			else ammo.Amount-=toadd;
			
			from.SendMessage("{0} peices of ammo were transferred to the quiver",toadd);
			}

			protected override void OnTargetFinish( Mobile from )
			{
				
			}
		}		
		


		[Constructable]
		public Quiver() :  base( 12215, Layer.Cloak, 0 )
		{		
		Weight=5;
		m_AosElementDamages = new AosElementAttributes( this );
		}


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

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 0); // version
			
			m_AosElementDamages.Serialize( writer );
			
			writer.Write((int)m_Arrows);
			writer.Write((int)m_Bolts);
			writer.Write((int)m_MaxArrows);
			writer.Write((int)m_MaxBolts);
			writer.Write((int)m_WeightReduction);

		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();
			
			m_AosElementDamages = new AosElementAttributes( this, reader );
			
			m_Arrows = reader.ReadInt();
			m_Bolts = reader.ReadInt();
			m_MaxArrows = reader.ReadInt();						
			m_MaxBolts = reader.ReadInt();	
			m_WeightReduction = reader.ReadInt();
		}
	}
}