context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using Server;
  using Server.Gumps;
  using Server.Items;
  using Server.Multis;
  using Server.ContextMenus;
  using Server.Network;
  
  namespace Server.Engines.Plants
  {
  	public enum PlantStatus
  	{
  		BowlOfDirt		= 0,
  		Seed			= 1,
  		Sapling			= 2,
  		Plant			= 4,
  		FullGrownPlant	= 7,
  		DecorativePlant = 10,
  		DeadTwigs		= 11,
  
  		Stage1			= 1,
  		Stage2			= 2,
  		Stage3			= 3,
  		Stage4			= 4,
  		Stage5			= 5,
  		Stage6			= 6,
  		Stage7			= 7,
  		Stage8			= 8,
  		Stage9			= 9
  	}
  
  	public class PlantItem : Item, ISecurable
  	{
  		/*
  		 * Clients 7.0.12.0+ expect a container type in the plant label.
  		 * To support older (and only older) clients, change this to false.
  		 */
  		private static readonly bool ShowContainerType = true;
  
  		private PlantSystem m_PlantSystem;
  
  		private PlantStatus m_PlantStatus;
  		private PlantType m_PlantType;
  		private PlantHue m_PlantHue;
  		private bool m_ShowType;
  
  		private SecureLevel m_Level;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public SecureLevel Level
  		{
  			get{ return m_Level; }
  			set{ m_Level = value; }
  		}
  
  		public PlantSystem PlantSystem { get { return m_PlantSystem; } }
  
  		public override bool ForceShowProperties{ get{ return ObjectPropertyList.Enabled; } }
  
          #region Magincia/Raised Garden Plant Support
          public virtual bool RequiresUpkeep { get { return true; } }
          public virtual bool MaginciaPlant { get { return false; } }
          public virtual int BowlOfDirtID { get { return 0x1602; } }
          public virtual int GreenBowlID { get { return 0x1600; } }
  
          public virtual int ContainerLocalization { get { return 1150435; } }
          public virtual int OnPlantLocalization { get { return 1061922; } }
          public virtual int CantUseLocalization { get { return 1061921; } }
          #endregion
  
          public override void OnSingleClick( Mobile from )
  		{
  			if ( m_PlantStatus >= PlantStatus.DeadTwigs )
  				LabelTo( from, LabelNumber );
  			else if ( m_PlantStatus >= PlantStatus.DecorativePlant )
  				LabelTo( from, 1061924 ); // a decorative plant
  			else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
  				LabelTo( from, PlantTypeInfo.GetInfo( m_PlantType ).Name );
  			else
  				LabelTo( from, 1029913 ); // plant bowl
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public PlantStatus PlantStatus
  		{
  			get { return m_PlantStatus; }
  			set
  			{
  				if ( m_PlantStatus == value || value < PlantStatus.BowlOfDirt || value > PlantStatus.DeadTwigs )
  					return;
  
  				double ratio;
  				if ( m_PlantSystem != null )
  					ratio = (double) m_PlantSystem.Hits / m_PlantSystem.MaxHits;
  				else
  					ratio = 1.0;
  
  				m_PlantStatus = value;
  
  				if ( m_PlantStatus >= PlantStatus.DecorativePlant )
  				{
  					m_PlantSystem = null;
  				}
  				else
  				{
  					if ( m_PlantSystem == null )
  						m_PlantSystem = new PlantSystem( this, false );
  
  					int hits = (int)( m_PlantSystem.MaxHits * ratio );
  
  					if ( hits == 0 && m_PlantStatus > PlantStatus.BowlOfDirt )
  						m_PlantSystem.Hits = hits + 1;
  					else
  						m_PlantSystem.Hits = hits;
  				}
  
  				Update();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public PlantType PlantType
  		{
  			get { return m_PlantType; }
  			set
  			{
  				m_PlantType = value;
  				Update();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public PlantHue PlantHue
  		{
  			get { return m_PlantHue; }
  			set
  			{
  				m_PlantHue = value;
  				Update();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool ShowType
  		{
  			get { return m_ShowType; }
  			set
  			{
  				m_ShowType = value;
  				InvalidateProperties();
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public virtual bool ValidGrowthLocation
  		{
  			get
  			{
  				if ( IsLockedDown && RootParent == null )
  					return true;
  
  
  				Mobile owner = RootParent as Mobile;
  				if ( owner == null )
  					return false;
  
  				if ( owner.Backpack != null && IsChildOf( owner.Backpack ) )
  					return true;
  
  				BankBox bank = owner.FindBankNoCreate();
  				if ( bank != null && IsChildOf( bank ) )
  					return true;
  
  				return false;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool IsGrowable
  		{
  			get { return m_PlantStatus >= PlantStatus.BowlOfDirt && m_PlantStatus <= PlantStatus.Stage9; }
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool IsCrossable
  		{
  			get { return PlantHueInfo.IsCrossable( this.PlantHue ) && PlantTypeInfo.IsCrossable( this.PlantType ); }
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool Reproduces
  		{
  			get { return PlantHueInfo.CanReproduce( this.PlantHue ) && PlantTypeInfo.CanReproduce( this.PlantType ); }
  		}
  
  		private static ArrayList m_Instances = new ArrayList();
  
  		public static ArrayList Plants{ get{ return m_Instances; } }
  
  		[Constructable]
  		public PlantItem() : this( 0x1602, false )
  		{
  		}
  
          [Constructable]
          public PlantItem(int itemID) : this(itemID, false)
          {
          }
  
          [Constructable]
          public PlantItem(bool fertileDirt) : this(0x1602, fertileDirt)
          {
          }
  
  		[Constructable]
  		public PlantItem( int itemID, bool fertileDirt ) : base( itemID )
  		{
  			Weight = 1.0;
  
  			m_PlantStatus = PlantStatus.BowlOfDirt;
  			m_PlantSystem = new PlantSystem( this, fertileDirt );
  			m_Level = SecureLevel.Owner;
  
  			m_Instances.Add( this );
  		}
  
  		public PlantItem( Serial serial ) : base( serial )
  		{
  		}
  
  		public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
  		{
  			base.GetContextMenuEntries( from, list );
  
              if (m_PlantStatus != PlantStatus.DecorativePlant)
              {
                  SetSecureLevelEntry.AddTo(from, this, list);
              }
  		}
  
  		public int GetLocalizedPlantStatus()
  		{
  			if ( m_PlantStatus >= PlantStatus.Plant )
  				return 1060812; // plant
  			else if ( m_PlantStatus >= PlantStatus.Sapling )
  				return 1023305; // sapling
  			else if ( m_PlantStatus >= PlantStatus.Seed )
  				return 1060810; // seed
  			else
  				return 1026951; // dirt
  		}
  
  		public int GetLocalizedContainerType()
  		{
              return ContainerLocalization; // mound -or- bowl
  		}
  
  		private void Update()
  		{
  			if ( m_PlantStatus >= PlantStatus.DeadTwigs )
  			{
  				ItemID = 0x1B9D;
  				Hue = PlantHueInfo.GetInfo( m_PlantHue ).Hue;
  			}
  			else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
  			{
  				ItemID = PlantTypeInfo.GetInfo( m_PlantType ).ItemID;
  				Hue = PlantHueInfo.GetInfo( m_PlantHue ).Hue;
  			}
  			else if ( m_PlantStatus >= PlantStatus.Plant )
  			{
  				ItemID = GreenBowlID;
  				Hue = 0;
  			}
  			else
  			{
                  ItemID = BowlOfDirtID;
  				Hue = 0;
  			}
  
  			InvalidateProperties();
  		}
  
  		public override void AddNameProperty( ObjectPropertyList list )
  		{
  			if ( m_PlantStatus >= PlantStatus.DeadTwigs )
  			{
  				base.AddNameProperty( list );
  			}
  			else if ( m_PlantStatus < PlantStatus.Seed )
  			{
  				string args;
  
  				if ( ShowContainerType )
  					args = String.Format( "#{0}\t#{1}", GetLocalizedContainerType(), m_PlantSystem.GetLocalizedDirtStatus() );
  				else
  					args = String.Format( "#{0}", m_PlantSystem.GetLocalizedDirtStatus() );
  
  
gt: 				list.Add( 1060830, args ); // a ~1_val~ of ~2_val~ dirt