using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Network;
using System.IO;

namespace Server.Items
{
	public class Collector : Container
	{
		public override int DefaultMaxWeight{ get{ return 0; } } // A value of 0 signals unlimited weight
		public override bool Decays{ get{ return false; } }
		public override bool DisplayWeight { get { return false; } }
		public override bool DisplaysContent{ get{ return false; } }
		public override bool IsPublicContainer{ get{ return true; } }
		public override bool IsDecoContainer{ get{ return false; } }
		// 		public override string DefaultName { get { return "Collector"; } }

		private double i_Delay;
		private string m_Key1;
		private int m_Key1_cur;
		private int m_Key1_max;
		private string m_Key2;
		private int m_Key2_cur;
		private int m_Key2_max;
		private string m_Key3;
		private int m_Key3_cur;
		private int m_Key3_max;

		private bool m_AllKeys;
		
		[CommandProperty( AccessLevel.GameMaster )]
		public double DeleteDelay
		{
			get { return i_Delay; }
			set { i_Delay = value; }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public String Key1
		{
			get { return m_Key1; }
			set
			{
				string str = value;

				if ( str != null )
				{
					str = str.ToLower();
					str = str.Trim();

					Type type = SpawnerType.GetType( str );

					if ( type != null )
						m_Key1 = str;
					else
						m_Key1 = "-invalid-";
				}
				else
					m_Key1 = null;

				InvalidateProperties();
			}
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key1_cur
		{
			get { return m_Key1_cur; }
			set { m_Key1_cur = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key1_max
		{
			get { return m_Key1_max; }
			set { m_Key1_max = value; InvalidateProperties(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public String Key2
		{
			get { return m_Key2; }
			set
			{
				string str = value;

				if ( str != null )
				{
					str = str.ToLower();
					str = str.Trim();

					Type type = SpawnerType.GetType( str );

					if ( type != null )
						m_Key2 = str;
					else
						m_Key2 = "-invalid-";
				}
				else
					m_Key2 = null;

				InvalidateProperties();
			}
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key2_cur
		{
			get { return m_Key2_cur; }
			set { m_Key2_cur = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key2_max
		{
			get { return m_Key2_max; }
			set { m_Key2_max = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public String Key3
		{
			get { return m_Key3; }
			set
			{
				string str = value;

				if ( str != null )
				{
					str = str.ToLower();
					str = str.Trim();

					Type type = SpawnerType.GetType( str );

					if ( type != null )
						m_Key3 = str;
					else
						m_Key3 = "-invalid-";
				}
				else
					m_Key3 = null;

				InvalidateProperties();
			}
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key3_cur
		{
			get { return m_Key3_cur; }
			set { m_Key3_cur = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int Key3_max
		{
			get { return m_Key3_max; }
			set { m_Key3_max = value; InvalidateProperties(); }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public bool AllKeys
		{
			get { return m_AllKeys; }
			set { m_AllKeys = value; InvalidateProperties(); }
		}
		
		[Constructable]
		public Collector() : this( 2.0 ) {}
		
		[Constructable]
		public Collector( double DelayTime ) : base( 0x9A8 )
		{
			Movable = false;
			LiftOverride = false;
			Name = "Magicka skrinka";
			i_Delay = DelayTime;
			m_Key1_cur = 0;
			m_Key2_cur = 0;
			m_Key3_cur = 0;
			m_Key1_max = 1;
			m_Key2_max = 1;
			m_Key3_max = 1;
		}
		
		public override void AddNameProperties( ObjectPropertyList list )
		{
			base.AddNameProperties( list );
			list.Add( "Seznam predmetu:" );
			if (m_Key1 != null)
				list.Add( 1060658, "{0}\t{1}", m_Key1.ToString(), String.Format("{0}/{1}", m_Key1_cur, m_Key1_max ) );
			if (m_Key2 != null)
				list.Add( 1060659, "{0}\t{1}", m_Key2.ToString(), String.Format("{0}/{1}", m_Key2_cur, m_Key2_max ) );
			if (m_Key3 != null)
				list.Add( 1060660, "{0}\t{1}", m_Key3.ToString(), String.Format("{0}/{1}", m_Key3_cur, m_Key3_max ) );
		}

		public override void GetProperties( ObjectPropertyList list )
		{
			base.GetProperties( list );
         Server.Engines.XmlSpawner2.XmlAttach.AddAttachmentProperties(this, list);
		}

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

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

			writer.Write( (int) 0 ); // version
			writer.Write((double)i_Delay );
			writer.Write( m_Key1 );
			writer.Write( (int)m_Key1_cur );
			writer.Write( (int)m_Key1_max );
			writer.Write( m_Key2 );
			writer.Write( (int)m_Key2_cur );
			writer.Write( (int)m_Key2_max );
			writer.Write( m_Key3 );
			writer.Write( (int)m_Key3_cur );
			writer.Write( (int)m_Key3_max );
			writer.Write( (bool)m_AllKeys );
		}

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

			int version = reader.ReadInt();
			switch( version )
			{
				case 0:
					{
						i_Delay = reader.ReadDouble();
						m_Key1 = reader.ReadString();
						m_Key1_cur = reader.ReadInt();
						m_Key1_max = reader.ReadInt();
						m_Key2 = reader.ReadString();
						m_Key2_cur = reader.ReadInt();
						m_Key2_max = reader.ReadInt();
						m_Key3 = reader.ReadString();
						m_Key3_cur = reader.ReadInt();
						m_Key3_max = reader.ReadInt();
						m_AllKeys = reader.ReadBool();
						break;
					}
			}

			if ( Items.Count > 0 )
			{
				m_Timer = new EmptyTimer( this, i_Delay );
				m_Timer.Start();
			}
		}

		public override bool OnDragDrop( Mobile from, Item dropped )
		{
			if ( m_Key1 == "-invalid-" || m_Key1 == null || m_Key2 == "-invalid-" || m_Key2 == null || m_Key3 == "-invalid-" || m_Key3 == null)
			{
				from.SendMessage( "Collector je spatne nastaven. Kontaktuj prosim Game mastera." );
				return false;
			}
			
			if ( m_AllKeys )
			{
				from.SendMessage( "V {0} je plny, chvili pockej az se vyprazdni.", this.Name );
				return false;
			}

			Type typeKey1 = SpawnerType.GetType( m_Key1 );
			Type typeKey2 = SpawnerType.GetType( m_Key2 );
			Type typeKey3 = SpawnerType.GetType( m_Key3 );
			
			if ( dropped.GetType() == typeKey1 || dropped.GetType() == typeKey2 || dropped.GetType() == typeKey3 )
			{
				int droppedAmount = dropped.Amount;
				
				if (( dropped.GetType() == typeKey1 && ( m_Key1_cur == m_Key1_max || m_Key1_cur + droppedAmount > m_Key1_max ) ) ||
				    ( dropped.GetType() == typeKey2 && ( m_Key2_cur == m_Key2_max || m_Key2_cur + droppedAmount > m_Key2_max ) ) ||
				    ( dropped.GetType() == typeKey3 && ( m_Key3_cur == m_Key3_max || m_Key3_cur + droppedAmount > m_Key3_max ) ))
				{
					from.SendMessage( "Pozadovane mnozstvi tohoto predmetu je jiz v {0} umisteno, nebo vhazujes prilis mnoho.", this.Name );
					return false;
				}
				else //ok
				{
					if ( dropped.GetType() == typeKey1 )
						m_Key1_cur += droppedAmount;
					else if ( dropped.GetType() == typeKey2 )
						m_Key2_cur += droppedAmount;
					else if ( dropped.GetType() == typeKey3 )
						m_Key3_cur += droppedAmount;

					if ( (m_Key1_cur == m_Key1_max) && (m_Key2_cur == m_Key2_max) && (m_Key3_cur == m_Key3_max) )
					{
						m_AllKeys = true;
						Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x376A, 9, 32, 5024 );
						Effects.PlaySound( Location, Map, 0x1FF );
						from.SendMessage( "V {0} jsou nyni umisteny vsechny pozadovane predmety.", this.Name );
					}
					else
						from.SendMessage( "Predmet byl umisten do {0}.", this.Name );
					
					from.SendMessage( "{0} bude vyprazdnen za {1} minuty.", this.Name, i_Delay );
					
					if ( m_Timer != null )
						m_Timer.Stop();
					
					m_Timer = null;
					m_Timer = new EmptyTimer( this, i_Delay );

					m_Timer.Start();
					return base.OnDragDrop( from, dropped );
				}
			}
			else
			{
				from.SendMessage( "Tento predmet nelze do {0} umistit.", this.Name );
				return false;
			}
		}

		// 		public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
		// 		{
		// 			from.SendMessage( "Predmet byl umisten do colectoru." );
		// 
		// 			if ( m_Timer != null )
		// 				m_Timer.Stop();
		// 			else
		// 				m_Timer = new EmptyTimer( this, i_Delay );
		// 
		// 			m_Timer.Start();
		// 			return base.OnDragDropInto( from, item, p );
		// 		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( (int) from.AccessLevel > (int) AccessLevel.Player )
				base.OnDoubleClick( from );
		}

		public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
		{
			if ( (int) from.AccessLevel > (int) AccessLevel.Player )
				return base.CheckLift( from, item, ref reject );
			else
				reject = LRReason.CannotLift;
			
			return false;
		}
		
		public override void DisplayTo( Mobile m )
		{
			if ( (int) m.AccessLevel > (int) AccessLevel.Player )
				base.DisplayTo( m );
		}
		
		public override void OnItemUsed( Mobile from, Item item )
		{
			if ( (int) from.AccessLevel > (int) AccessLevel.Player )
            base.OnItemUsed( from, item );
		}
		
		public override void OnAfterDelete()
		{
			if ( m_Timer != null )
				m_Timer.Stop();
				
			m_Timer = null;
			base.OnAfterDelete();
		}

		public void Empty()
		{
			List<Item> items = this.Items;

			if ( items.Count > 0 )
			{
				PublicOverheadMessage( MessageType.Regular, 0x3B2, false, String.Format("*{0} byl vyprazdnen*", this.Name) );
				Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
				Effects.PlaySound( Location, Map, 0x201 );

				for ( int i = items.Count - 1; i >= 0; --i )
				{
					if ( i >= items.Count )
						continue;

					items[i].Delete();
				}
			}

			if ( m_Timer != null )
				m_Timer.Stop();

			m_Timer = null;
			
			m_Key1_cur = 0;
			m_Key2_cur = 0;
			m_Key3_cur = 0;
			InvalidateProperties();
			m_AllKeys = false;
		}

		private Timer m_Timer;

		private class EmptyTimer : Timer
		{
			private Collector m_Barrel;
			
			public EmptyTimer( Collector barrel, double i_Delay ) : base( TimeSpan.FromMinutes( i_Delay ) )
			{
				m_Barrel = barrel;
				Priority = TimerPriority.FiveSeconds;
			}

			protected override void OnTick()
			{
				m_Barrel.Empty();
			}
		}
	}
}
