context: using System;
  using System.IO;
  using System.Collections;
  using Server;
  using Server.Items;
  
  namespace Server.Mobiles
  {
  	public class Spawner : Item
  	{
  		private int m_Team;
  		private int m_HomeRange;
  		private int m_Count;
  		private TimeSpan m_MinDelay;
  		private TimeSpan m_MaxDelay;
  		private ArrayList m_CreaturesName;
  		private ArrayList m_Creatures;
  		private DateTime m_End;
  		private InternalTimer m_Timer;
  		private bool m_Running;
  		private bool m_Group;
  		private WayPoint m_WayPoint;
  
  		public bool IsFull { get { return ( m_Creatures != null && m_Creatures.Count >= m_Count ); } }
  
  		public ArrayList CreaturesName
  		{
  			get { return m_CreaturesName; }
  			set
  			{
  				m_CreaturesName = value;
  				if ( m_CreaturesName.Count < 1 )
  				{
  					Stop();
  				}
  
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Count
  		{
  			get { return m_Count; }
  			set
  			{
  				m_Count = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public WayPoint WayPoint { get { return m_WayPoint; } set { m_WayPoint = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool Running
  		{
  			get { return m_Running; }
  			set
  			{
  				if ( value )
  				{
  					Start();
  				}
  				else
  				{
  					Stop();
  				}
  
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int HomeRange
  		{
  			get { return m_HomeRange; }
  			set
  			{
  				m_HomeRange = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Team
  		{
  			get { return m_Team; }
  			set
  			{
  				m_Team = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public TimeSpan MinDelay
  		{
  			get { return m_MinDelay; }
  			set
  			{
  				m_MinDelay = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public TimeSpan MaxDelay
  		{
  			get { return m_MaxDelay; }
  			set
  			{
  				m_MaxDelay = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public TimeSpan NextSpawn
  		{
  			get
  			{
  				if ( m_Running )
  				{
  					return m_End - DateTime.Now;
  				}
  				else
  				{
  					return TimeSpan.FromSeconds( 0 );
  				}
  			}
  			set
  			{
  				Start();
  				DoTimer( value );
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool Group
  		{
  			get { return m_Group; }
  			set
  			{
  				m_Group = value;
  				InvalidateProperties();
  			}
  		}
  
  		[Constructable]
  		public Spawner( int amount, int minDelay, int maxDelay, int team, int homeRange, string creatureName )
  			: base( 0x1f13 )
  		{
  			ArrayList creaturesName = new ArrayList();
  			creaturesName.Add( creatureName.ToLower() );
  			InitSpawn( amount, TimeSpan.FromMinutes( minDelay ), TimeSpan.FromMinutes( maxDelay ), team, homeRange, creaturesName );
  		}
  
  		[Constructable]
  		public Spawner( string creatureName )
  			: base( 0x1f13 )
  		{
  			ArrayList creaturesName = new ArrayList();
  			creaturesName.Add( creatureName.ToLower() );
  			InitSpawn( 1, TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 10 ), 0, 4, creaturesName );
  		}
  
  		[Constructable]
  		public Spawner()
  			: base( 0x1f13 )
  		{
  			ArrayList creaturesName = new ArrayList();
  			InitSpawn( 1, TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 10 ), 0, 4, creaturesName );
  		}
  
  		public Spawner( int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, ArrayList creaturesName )
  			: base( 0x1f13 )
  		{
  			InitSpawn( amount, minDelay, maxDelay, team, homeRange, creaturesName );
  		}
  
  		public void InitSpawn( int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, ArrayList creaturesName )
  		{
  			Visible = false;
  			Movable = false;
  			m_Running = true;
  			m_Group = false;
  			Name = "Spawner";
  			m_MinDelay = minDelay;
  			m_MaxDelay = maxDelay;
  			m_Count = amount;
  			m_Team = team;
  			m_HomeRange = homeRange;
  			m_CreaturesName = creaturesName;
  			m_Creatures = new ArrayList();
  			DoTimer( TimeSpan.FromSeconds( 1 ) );
  		}
  
  		public Spawner( Serial serial )
  			: base( serial )
  		{
  		}
  
  		public override void OnDoubleClick( Mobile from )
  		{
  			if ( from.AccessLevel < AccessLevel.GameMaster )
  			{
  				return;
  			}
  
  			SpawnerGump g = new SpawnerGump( this );
  			from.SendGump( g );
  		}
  
  		public override void GetProperties( ObjectPropertyList list )
  		{
  			base.GetProperties( list );
  
  			if ( m_Running )
  			{
  				list.Add( 1060742 ); // active
  
  				list.Add( 1060656, m_Count.ToString() ); // amount to make: ~1_val~
  				list.Add( 1061169, m_HomeRange.ToString() ); // range ~1_val~
  
  				list.Add( 1060658, "group\t{0}", m_Group ); // ~1_val~: ~2_val~
  				list.Add( 1060659, "team\t{0}", m_Team ); // ~1_val~: ~2_val~
  				list.Add( 1060660, "speed\t{0} to {1}", m_MinDelay, m_MaxDelay ); // ~1_val~: ~2_val~
  
  				for ( int i = 0; i < 3 && i < m_CreaturesName.Count; ++i )
  				{
  					list.Add( 1060661 + i, "{0}\t{1}", m_CreaturesName[i], CountCreatures( (string) m_CreaturesName[i] ) );
  				}
  			}
  			else
  			{
  				list.Add( 1060743 ); // inactive
  			}
  		}
  
  		public void Start()
  		{
  			if ( !m_Running )
  			{
  				if ( m_CreaturesName.Count > 0 )
  				{
  					m_Running = true;
  					DoTimer();
  				}
  			}
  		}
  
  		public void Stop()
  		{
  			if ( m_Running )
  			{
  				m_Timer.Stop();
  				m_Running = false;
  			}
  		}
  
  		public void Defrag()
  		{
  			bool removed = false;
  
  			for ( int i = 0; i < m_Creatures.Count; ++i )
  			{
  
gt: 				object o = m_Creatures[i];