context: using System;
  using System.Collections.Generic;
  
  using Server;
  using Server.Engines.Housing;
  using Server.Engines.Housing.Multis;
  using Server.Gumps;
  using Server.Multis;
  using Server.Network;
  using Server.Engines.VeteranRewards;
  
  namespace Server.Items
  {
  	public enum MiningCartType
  	{
  		OreSouth = 100,
  		OreEast = 101,
  		GemSouth = 102,
  		GemEast = 103
  	}
  
  	public class MiningCart : BaseAddon, IRewardItem
  	{
  		public override BaseAddonDeed Deed
  		{
  			get
  			{
  				MiningCartDeed deed = new MiningCartDeed();
  				deed.IsRewardItem = m_IsRewardItem;
  				deed.Gems = m_Gems;
  				deed.Ore = m_Ore;
  
  				return deed;
  			}
  		}
  
  		private bool m_IsRewardItem;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool IsRewardItem
  		{
  			get { return m_IsRewardItem; }
  			set { m_IsRewardItem = value; }
  		}
  
  		private MiningCartType m_CartType;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public MiningCartType CartType
  		{
  			get { return m_CartType; }
  		}
  
  		private int m_Gems;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Gems
  		{
  			get { return m_Gems; }
  			set { m_Gems = value; }
  		}
  
  		private int m_Ore;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Ore
  		{
  			get { return m_Ore; }
  			set { m_Ore = value; }
  		}
  
  		private Timer m_Timer;
  
  		[Constructable]
  		public MiningCart( MiningCartType type )
  			: base()
  		{
  			m_CartType = type;
  
  			switch ( type )
  			{
  				case MiningCartType.OreSouth:
  					AddComponent( new AddonComponent( 0x1A83 ), 0, 0, 0 );
  					AddComponent( new AddonComponent( 0x1A82 ), 0, 1, 0 );
  					AddComponent( new AddonComponent( 0x1A86 ), 0, -1, 0 );
  					break;
  				case MiningCartType.OreEast:
  					AddComponent( new AddonComponent( 0x1A88 ), 0, 0, 0 );
  					AddComponent( new AddonComponent( 0x1A87 ), 1, 0, 0 );
  					AddComponent( new AddonComponent( 0x1A8B ), -1, 0, 0 );
  					break;
  				case MiningCartType.GemSouth:
  					AddComponent( new LocalizedAddonComponent( 0x1A83, 1080388 ), 0, 0, 0 );
  					AddComponent( new LocalizedAddonComponent( 0x1A82, 1080388 ), 0, 1, 0 );
  					AddComponent( new LocalizedAddonComponent( 0x1A86, 1080388 ), 0, -1, 0 );
  
  					AddComponent( new AddonComponent( 0xF2C ), 0, 0, 6 );
  					AddComponent( new AddonComponent( 0xF1D ), 0, 0, 5 );
  					AddComponent( new AddonComponent( 0xF2B ), 0, 0, 2 );
  					AddComponent( new AddonComponent( 0xF21 ), 0, 0, 1 );
  					AddComponent( new AddonComponent( 0xF22 ), 0, 0, 4 );
  					AddComponent( new AddonComponent( 0xF2F ), 0, 0, 5 );
  					AddComponent( new AddonComponent( 0xF26 ), 0, 0, 6 );
  					AddComponent( new AddonComponent( 0xF27 ), 0, 0, 3 );
  					AddComponent( new AddonComponent( 0xF29 ), 0, 0, 0 );
  					break;
  				case MiningCartType.GemEast:
  					AddComponent( new LocalizedAddonComponent( 0x1A88, 1080388 ), 0, 0, 0 );
  					AddComponent( new LocalizedAddonComponent( 0x1A87, 1080388 ), 1, 0, 0 );
  					AddComponent( new LocalizedAddonComponent( 0x1A8B, 1080388 ), -1, 0, 0 );
  
  					AddComponent( new AddonComponent( 0xF2E ), 0, 0, 6 );
  					AddComponent( new AddonComponent( 0xF12 ), 0, 0, 3 );
  					AddComponent( new AddonComponent( 0xF29 ), 0, 0, 1 );
  					AddComponent( new AddonComponent( 0xF24 ), 0, 0, 5 );
  					AddComponent( new AddonComponent( 0xF21 ), 0, 0, 1 );
  					AddComponent( new AddonComponent( 0xF2B ), 0, 0, 3 );
  					AddComponent( new AddonComponent( 0xF2F ), 0, 0, 4 );
  					AddComponent( new AddonComponent( 0xF23 ), 0, 0, 3 );
  					AddComponent( new AddonComponent( 0xF27 ), 0, 0, 3 );
  					break;
  			}
  
  			m_Timer = Timer.DelayCall( TimeSpan.FromDays( 1 ), TimeSpan.FromDays( 1 ), new TimerCallback( GiveResources ) );
  		}
  
  		public MiningCart( Serial serial )
  			: base( serial )
  		{
  		}
  
  		private void GiveResources()
  		{
  			switch ( m_CartType )
  			{
  				case MiningCartType.OreSouth:
  				case MiningCartType.OreEast:
  					m_Ore = Math.Min( 100, m_Ore + 10 );
  					break;
  				case MiningCartType.GemSouth:
  				case MiningCartType.GemEast:
  					m_Gems = Math.Min( 50, m_Gems + 5 );
  					break;
  			}
  		}
  
  		public override void OnComponentUsed( AddonComponent c, Mobile from )
  		{
  			var house = HousingHelper.FindHouseAt( this );
  
  			if ( house != null && house.HasSecureAccess( from, SecureLevel.Friends ) )
  			{
  				switch ( m_CartType )
  				{
  					case MiningCartType.OreSouth:
  					case MiningCartType.OreEast:
  						if ( m_Ore > 0 )
  						{
  							Item ingots = null;
  
  							switch ( Utility.Random( 9 ) )
  							{
  								case 0:
  									ingots = new IronIngot();
  									break;
  								case 1:
  									ingots = new DullCopperIngot();
  									break;
  								case 2:
  									ingots = new ShadowIronIngot();
  									break;
  								case 3:
  									ingots = new CopperIngot();
  									break;
  								case 4:
  									ingots = new BronzeIngot();
  									break;
  								case 5:
  									ingots = new GoldIngot();
  									break;
  								case 6:
  									ingots = new AgapiteIngot();
  									break;
  								case 7:
  									ingots = new VeriteIngot();
  									break;
  								case 8:
  									ingots = new ValoriteIngot();
  									break;
  							}
  
  							int amount = Math.Min( 10, m_Ore );
  							ingots.Amount = amount;
  
  							if ( !from.PlaceInBackpack( ingots ) )
  							{
  								ingots.Delete();
  								from.SendLocalizedMessage( 1078837 ); // Your backpack is full! Please make room and try again.
  							}
  							else
  							{
  								PublicOverheadMessage( MessageType.Regular, 0, 1094724, amount.ToString() ); // Ore: ~1_COUNT~
  								m_Ore -= amount;
  							}
  						}
  						else
  							from.SendLocalizedMessage( 1094725 ); // There are no more resources available at this time.
  
  						break;
  					case MiningCartType.GemSouth:
  					case MiningCartType.GemEast:
  						if ( m_Gems > 0 )
  						{
  							Item gems = null;
  
  							switch ( Utility.Random( 9 ) )
  							{
  								case 0:
  									gems = new Amber();
  									break;
  								case 1:
  									gems = new Amethyst();
  									break;
  								case 2:
  									gems = new Citrine();
  									break;
  								case 3:
  									gems = new Diamond();
  									break;
  								case 4:
  									gems = new Emerald();
  									break;
  								case 5:
  									gems = new Ruby();
  									break;
  								case 6:
  									gems = new Sapphire();
  									break;
  								case 7:
  									gems = new StarSapphire();
  									break;
  								case 8:
  									gems = new Tourmaline();
  									break;
  							}
  
  							int amount = Math.Min( 5, m_Gems );
  							gems.Amount = amount;
  
  							if ( !from.PlaceInBackpack( gems ) )
  							{
  								gems.Delete();
  								from.SendLocalizedMessage( 1078837 ); // Your backpack is full! Please make room and try again.
  							}
  							else
  							{
  								PublicOverheadMessage( MessageType.Regular, 0, 1094723, amount.ToString() ); // Gems: ~1_COUNT~
  								m_Gems -= amount;
  							}
  						}
  						else
  							from.SendLocalizedMessage( 1094725 ); // There are no more resources available at this time.
  
  						break;
  				}
  			}
  			else
  				from.SendLocalizedMessage( 1061637 ); // You are not allowed to access this.
  		}
  
  		public override void Serialize( GenericWriter writer )
  		{
  			base.Serialize( writer );
  
  			writer.WriteEncodedInt( 1 ); // version
  
  			#region version 1
  			writer.Write( (int) m_CartType );
  			#endregion
  
  			writer.Write( (bool) m_IsRewardItem );
  			writer.Write( (int) m_Gems );
  			writer.Write( (int) m_Ore );
  
  			if ( m_Timer != null )
  				writer.Write( (DateTime) m_Timer.Next );
  			else
  				writer.Write( (DateTime) DateTime.UtcNow + TimeSpan.FromDays( 1 ) );
  		}
  
  		public override void Deserialize( GenericReader reader )
  		{
  			base.Deserialize( reader );
  
  			int version = reader.ReadEncodedInt();
  
  			switch ( version )
  			{
  				case 1:
  					m_CartType = (MiningCartType) reader.ReadInt();
  					goto case 0;
  				case 0:
  					m_IsRewardItem = reader.ReadBool();
  					m_Gems = reader.ReadInt();
  					m_Ore = reader.ReadInt();
  
  					DateTime next = reader.ReadDateTime();
  
  					if ( next < DateTime.UtcNow )
  						next = DateTime.UtcNow;
  
  					m_Timer = Timer.DelayCall( next - DateTime.UtcNow, TimeSpan.FromDays( 1 ), new TimerCallback( GiveResources ) );
  					break;
  			}
  		}
  	}
  
  	public class MiningCartDeed : BaseAddonDeed, IRewardItem, IRewardOption
  	{
  		public override int LabelNumber { get { return 1080385; } } // deed for a mining cart decoration
  
  		public override BaseAddon Addon
  		{
  			get
  			{
  				MiningCart addon = new MiningCart( m_CartType );
  				addon.IsRewardItem = m_IsRewardItem;
  				addon.Gems = m_Gems;
  				addon.Ore = m_Ore;
  
  				return addon;
  			}
  		}
  
  		private MiningCartType m_CartType;
  
  		private bool m_IsRewardItem;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool IsRewardItem
  		{
  			get { return m_IsRewardItem; }
  			set { m_IsRewardItem = value; InvalidateProperties(); }
  		}
  
  		private int m_Gems;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Gems
  		{
  			get { return m_Gems; }
  			set { m_Gems = value; }
  		}
  
  		private int m_Ore;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Ore
  		{
  			get { return m_Ore; }
  			set { m_Ore = value; }
  		}
  
  		[Constructable]
  		public MiningCartDeed()
  			: base()
  		{
  			LootType = LootType.Blessed;
  		}
  
  		public MiningCartDeed( Serial serial )
  			: base( serial )
  		{
  		}
  
  		public override void GetProperties( ObjectPropertyList list )
  		{
  			base.GetProperties( list );
  
  			if ( m_IsRewardItem )
  				list.Add( 1080457 ); // 10th Year Veteran Reward
  		}
  
  		public override void OnDoubleClick( Mobile from )
  		{
  			if ( m_IsRewardItem && !RewardSystem.CheckIsUsableBy( from, this, null ) )
  				return;
  
  			if ( IsChildOf( from.Backpack ) )
  			{
  				from.CloseGump<RewardOptionGump>();
  				from.SendGump( new RewardOptionGump( this ) );
  			}
  			else
  				from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.       	
  		}
  
  		public override void Serialize( GenericWriter writer )
  		{
  			base.Serialize( writer );
  
  			writer.WriteEncodedInt( 0 ); // version
  
  			writer.Write( (bool) m_IsRewardItem );
  			writer.Write( (int) m_Gems );
  
gt: 			writer.Write( (int) m_Ore );