context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using Server;
  using Server.ContextMenus;
  using Server.Engines.Housing;
  using Server.Engines.Housing.Multis;
  using Server.Gumps;
  using Server.Items;
  using Server.Multis;
  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
  	{
  		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 ObjectPropertyListPacket.Enabled; } }
  
  		[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 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;
  				}
  				if ( owner.BankBox != null && IsChildOf( owner.BankBox ) )
  				{
  					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( false )
  		{
  		}
  
  		[Constructable]
  		public PlantItem( bool fertileDirt )
  			: base( 0x1602 )
  		{
  			Weight = 1.0;
  
  			m_PlantStatus = PlantStatus.BowlOfDirt;
  			m_PlantSystem = new PlantSystem( this, fertileDirt );
  			m_Level = SecureLevel.CoOwners;
  
  			m_Instances.Add( this );
  		}
  
  		public PlantItem( Serial serial )
  			: base( serial )
  		{
  		}
  
  		public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
  		{
  			base.GetContextMenuEntries( from, list );
  
  			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 1150435; // 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 = 0x1600;
  				Hue = 0;
  			}
  			else
  			{
  				ItemID = 0x1602;
  				Hue = 0;
  			}
  
  			InvalidateProperties();
  		}
  
  		public override LocalizedText GetNameProperty()
  		{
  			if ( m_PlantStatus >= PlantStatus.DeadTwigs )
  			{
  				return new LocalizedText( 1027069 ); // twigs
  			}
  			else if ( m_PlantStatus < PlantStatus.Seed )
  			{
  				string args = String.Format( "#{0}\t#{1}", GetLocalizedContainerType(), m_PlantSystem.GetLocalizedDirtStatus() );
  
  				return new LocalizedText( 1060830, args ); // a ~1_val~ of ~2_val~ dirt
  			}
  			else
  			{
  				PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_PlantType );
  				PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_PlantHue );
  
  				if ( m_PlantStatus >= PlantStatus.DecorativePlant )
  				{
  					return new LocalizedText( typeInfo.GetPlantLabelDecorative( hueInfo ), String.Format( "#{0}\t#{1}", hueInfo.Name, typeInfo.Name ) );
  				}
  				else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
  				{
  					return new LocalizedText( typeInfo.GetPlantLabelFullGrown( hueInfo ), String.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), hueInfo.Name, typeInfo.Name ) );
  				}
  				else
  				{
  					string args = String.Format( "#{0}\t#{1}\t#{2}", GetLocalizedContainerType(), m_PlantSystem.GetLocalizedDirtStatus(), m_PlantSystem.GetLocalizedHealth() );
  
  					if ( m_ShowType )
  					{
  						args += String.Format( "\t#{0}\t#{1}\t#{2}", hueInfo.Name, typeInfo.Name, GetLocalizedPlantStatus() );
  
  						if ( m_PlantStatus == PlantStatus.Plant )
  							return new LocalizedText( typeInfo.GetPlantLabelPlant( hueInfo ), args );
  						else
  							return new LocalizedText( typeInfo.GetPlantLabelSeed( hueInfo ), args );
  					}
  					else
  					{
  						args += String.Format( "\t#{0}\t#{1}", ( typeInfo.PlantCategory == PlantCategory.Default ) ? hueInfo.Name : (int) typeInfo.PlantCategory, GetLocalizedPlantStatus() );
  
  						return new LocalizedText( hueInfo.IsBright() ? 1060832 : 1060831, args ); // a ~1_val~ of ~2_val~ dirt with a ~3_val~ [bright] ~4_val~ ~5_val~
  					}
  				}
  			}
  		}
  
  		public bool IsUsableBy( Mobile from )
  		{
  			Item root = RootParent as Item;
  			return IsChildOf( from.Backpack ) || IsChildOf( from.BankBox ) || IsLockedDown && IsAccessibleTo( from ) || root != null && root.IsSecure && root.IsAccessibleTo( from );
  		}
  
  		public override void OnDoubleClick( Mobile from )
  		{
  			if ( m_PlantStatus >= PlantStatus.DecorativePlant )
  				return;
  
  			Point3D loc = this.GetWorldLocation();
  
  			if ( !from.InLOS( loc ) || !from.InRange( loc, 2 ) )
  			{
  				from.LocalOverheadMessage( MessageType.Regular, 0x3E9, 1019045 ); // I can't reach that.
  				return;
  			}
  
  			if ( !IsUsableBy( from ) )
  			{
  				LabelTo( from, 1061856 ); // You must have the item in your backpack or locked down in order to use it.
  				return;
  			}
  
  
gt: 			from.SendGump( new MainPlantGump( this ) );