context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using Server;
  using Server.Engines.Housing;
  using Server.Engines.Housing.Items;
  using Server.Engines.Housing.Multis;
  using Server.Gumps;
  using Server.Multis;
  using Server.ContextMenus;
  using Server.Prompts;
  
  namespace Server.Mobiles
  {
  	public class VendorRentalDuration
  	{
  		public static readonly VendorRentalDuration[] Instances = new VendorRentalDuration[]
  			{
  				new VendorRentalDuration( TimeSpan.FromDays( 7.0 ), 1062361 ), // 1 Week
  				new VendorRentalDuration( TimeSpan.FromDays( 14.0 ), 1062362 ), // 2 Weeks
  				new VendorRentalDuration( TimeSpan.FromDays( 21.0 ), 1062363 ), // 3 Weeks
  				new VendorRentalDuration( TimeSpan.FromDays( 28.0 ), 1062364 ) // 1 Month
  			};
  
  		private TimeSpan m_Duration;
  		private int m_Name;
  
  		public TimeSpan Duration { get { return m_Duration; } }
  		public int Name { get { return m_Name; } }
  
  		public int ID
  		{
  			get
  			{
  				for ( int i = 0; i < Instances.Length; i++ )
  				{
  					if ( Instances[i] == this )
  						return i;
  				}
  
  				return 0;
  			}
  		}
  
  		private VendorRentalDuration( TimeSpan duration, int name )
  		{
  			m_Duration = duration;
  			m_Name = name;
  		}
  	}
  
  	public class RentedVendor : PlayerVendor
  	{
  		private VendorRentalDuration m_RentalDuration;
  		private int m_RentalPrice;
  		private bool m_LandlordRenew;
  		private bool m_RenterRenew;
  		private int m_RenewalPrice;
  
  		private int m_RentalGold;
  
  		private DateTime m_RentalExpireTime;
  		private Timer m_RentalExpireTimer;
  
  		public RentedVendor( Mobile owner, IHouse house, VendorRentalDuration duration, int rentalPrice, bool landlordRenew, int rentalGold )
  			: base( owner, house )
  		{
  			m_RentalDuration = duration;
  			m_RentalPrice = m_RenewalPrice = rentalPrice;
  			m_LandlordRenew = landlordRenew;
  			m_RenterRenew = false;
  
  			m_RentalGold = rentalGold;
  
  			m_RentalExpireTime = DateTime.UtcNow + duration.Duration;
  			m_RentalExpireTimer = new RentalExpireTimer( this, duration.Duration );
  			m_RentalExpireTimer.Start();
  		}
  
  		public RentedVendor( Serial serial )
  			: base( serial )
  		{
  		}
  
  		public VendorRentalDuration RentalDuration { get { return m_RentalDuration; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int RentalPrice { get { return m_RentalPrice; } set { m_RentalPrice = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool LandlordRenew { get { return m_LandlordRenew; } set { m_LandlordRenew = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool RenterRenew { get { return m_RenterRenew; } set { m_RenterRenew = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool Renew { get { return LandlordRenew && RenterRenew && House != null && House.DecayType != DecayType.Condemned; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int RenewalPrice { get { return m_RenewalPrice; } set { m_RenewalPrice = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int RentalGold { get { return m_RentalGold; } set { m_RentalGold = value; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public DateTime RentalExpireTime { get { return m_RentalExpireTime; } }
  
  		public override bool IsOwner( Mobile m )
  		{
  			return m == Owner || m.AccessLevel >= AccessLevel.GameMaster;
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile Landlord
  		{
  			get
  			{
  				if ( House != null )
  					return House.Owner;
  
  				return null;
  			}
  		}
  
  		public bool IsLandlord( Mobile m )
  		{
  			return House != null && House.IsOwner( m );
  		}
  
  		public void ComputeRentalExpireDelay( out int days, out int hours )
  		{
  			TimeSpan delay = RentalExpireTime - DateTime.UtcNow;
  
  			if ( delay <= TimeSpan.Zero )
  			{
  				days = 0;
  				hours = 0;
  			}
  			else
  			{
  				days = delay.Days;
  				hours = delay.Hours;
  			}
  		}
  
  		public void SendRentalExpireMessage( Mobile to )
  		{
  			int days, hours;
  			ComputeRentalExpireDelay( out days, out hours );
  
  			to.SendLocalizedMessage( 1062464, days.ToString() + "\t" + hours.ToString() ); // The rental contract on this vendor will expire in ~1_DAY~ day(s) and ~2_HOUR~ hour(s).
  		}
  
  		public override void OnAfterDelete()
  		{
  			base.OnAfterDelete();
  
  			m_RentalExpireTimer.Stop();
  		}
  
  		public override void Destroy( bool toBackpack )
  		{
  			if ( RentalGold > 0 && House != null )
  			{
  				if ( House.MovingCrate == null )
  					House.MovingCrate = new MovingCrate( House );
  
  				Banker.Deposit( House.MovingCrate, RentalGold );
  				RentalGold = 0;
  			}
  
  			base.Destroy( toBackpack );
  		}
  
  		public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
  		{
  			if ( from.Alive )
  			{
  				if ( IsLandlord( from ) )
  				{
  					if ( RentalGold > 0 )
  						list.Add( new CollectRentEntry( this ) );
  
  					list.Add( new TerminateContractEntry( this ) );
  					list.Add( new ContractOptionsEntry( this ) );
  				}
  				else if ( IsOwner( from ) )
  				{
  					list.Add( new ContractOptionsEntry( this ) );
  				}
  			}
  
  			base.GetContextMenuEntries( from, list );
  		}
  
  		private class ContractOptionsEntry : ContextMenuEntry
  		{
  			private RentedVendor m_Vendor;
  
  			public ContractOptionsEntry( RentedVendor vendor )
  				: base( 6209 )
  			{
  				m_Vendor = vendor;
  			}
  
  			public override void OnClick()
  			{
  				Mobile from = Owner.From;
  
  				if ( m_Vendor.Deleted || !from.CheckAlive() )
  					return;
  
  				if ( m_Vendor.IsOwner( from ) )
  				{
  					from.CloseGump<RenterVendorRentalGump>();
  					from.SendGump( new RenterVendorRentalGump( m_Vendor ) );
  
  					m_Vendor.SendRentalExpireMessage( from );
  				}
  				else if ( m_Vendor.IsLandlord( from ) )
  				{
  					from.CloseGump<LandlordVendorRentalGump>();
  					from.SendGump( new LandlordVendorRentalGump( m_Vendor ) );
  
  					m_Vendor.SendRentalExpireMessage( from );
  				}
  			}
  		}
  
  		private class CollectRentEntry : ContextMenuEntry
  		{
  			private RentedVendor m_Vendor;
  
  			public CollectRentEntry( RentedVendor vendor )
  				: base( 6212 )
  			{
  				m_Vendor = vendor;
  
  				if ( m_Vendor.RentalGold <= 0 )
  					Flags |= Network.CMEFlags.Disabled;
  			}
  
  			public override void OnClick()
  			{
  				Mobile from = Owner.From;
  
  				if ( m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord( from ) )
  					return;
  
  				if ( m_Vendor.RentalGold > 0 )
  				{
  					int depositedGold = Banker.DepositUpTo( from, m_Vendor.RentalGold );
  					m_Vendor.RentalGold -= depositedGold;
  
  					if ( depositedGold > 0 )
  						from.SendLocalizedMessage( 1060397, depositedGold.ToString() ); // ~1_AMOUNT~ gold has been deposited into your bank box.
  
  					if ( m_Vendor.RentalGold > 0 )
  						from.SendLocalizedMessage( 500390 ); // Your bank box is full.
  				}
  			}
  		}
  
  		private class TerminateContractEntry : ContextMenuEntry
  		{
  			private RentedVendor m_Vendor;
  
  			public TerminateContractEntry( RentedVendor vendor )
  				: base( 6218 )
  			{
  				m_Vendor = vendor;
  			}
  
  			public override void OnClick()
  			{
  				Mobile from = Owner.From;
  
  				if ( m_Vendor.Deleted || !from.CheckAlive() || !m_Vendor.IsLandlord( from ) )
  					return;
  
  				from.Prompt = new RefundOfferPrompt( m_Vendor );
  			}
  		}
  
  		private class RefundOfferPrompt : Prompt
  		{
  			// Enter the amount of gold you wish to offer the renter in exchange for immediate termination of this contract?
  			public override int MessageCliloc { get { return 1062503; } }
  
  			private RentedVendor m_Vendor;
  
  			public RefundOfferPrompt( RentedVendor vendor )
  				: base( vendor )
  			{
  				m_Vendor = vendor;
  			}
  
  			public override void OnResponse( Mobile from, string text )
  			{
  				if ( !m_Vendor.CanInteractWith( from, false ) || !m_Vendor.IsLandlord( from ) )
  					return;
  
  				text = text.Trim();
  
  				int amount;
  				try { amount = Convert.ToInt32( text ); }
  
gt: 				catch { amount = -1; }