context: /***************************************************************************
   *                               SecureTrade.cs
   *                            -------------------
   *   begin                : May 1, 2002
   *   copyright            : (C) The RunUO Software Team
   *   email                : info@runuo.com
   *
   *   $Id$
   *
   ***************************************************************************/
  
  /***************************************************************************
   *
   *   This program is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License as published by
   *   the Free Software Foundation; either version 2 of the License, or
   *   (at your option) any later version.
   *
   ***************************************************************************/
  
  #region References
  using System;
  
  using Server.Accounting;
  using Server.Items;
  using Server.Network;
  #endregion
  
  namespace Server
  {
  	public class SecureTrade
  	{
  		private readonly SecureTradeInfo m_From;
  		private readonly SecureTradeInfo m_To;
  
  		private bool m_Valid;
  
  		public SecureTrade(Mobile from, Mobile to)
  		{
  			m_Valid = true;
  
  			m_From = new SecureTradeInfo(this, from, new SecureTradeContainer(this));
  			m_To = new SecureTradeInfo(this, to, new SecureTradeContainer(this));
  
  			var from6017 = (from.NetState != null && from.NetState.ContainerGridLines);
  			var to6017 = (to.NetState != null && to.NetState.ContainerGridLines);
  
  			var from704565 = (from.NetState != null && from.NetState.NewSecureTrading);
  			var to704565 = (to.NetState != null && to.NetState.NewSecureTrading);
  
  			from.Send(new MobileStatus(from, to));
  			from.Send(new UpdateSecureTrade(m_From.Container, false, false));
  
  			if (from6017)
  			{
  				from.Send(new SecureTradeEquip6017(m_To.Container, to));
  			}
  			else
  			{
  				from.Send(new SecureTradeEquip(m_To.Container, to));
  			}
  
  			from.Send(new UpdateSecureTrade(m_From.Container, false, false));
  
  			if (from6017)
  			{
  				from.Send(new SecureTradeEquip6017(m_From.Container, from));
  			}
  			else
  			{
  				from.Send(new SecureTradeEquip(m_From.Container, from));
  			}
  
  			from.Send(new DisplaySecureTrade(to, m_From.Container, m_To.Container, to.Name));
  			from.Send(new UpdateSecureTrade(m_From.Container, false, false));
  
  			if (from.Account != null && from704565)
  			{
  				from.Send(
  					new UpdateSecureTrade(m_From.Container, TradeFlag.UpdateLedger, from.Account.TotalGold, from.Account.TotalPlat));
  			}
  
  			to.Send(new MobileStatus(to, from));
  			to.Send(new UpdateSecureTrade(m_To.Container, false, false));
  
  			if (to6017)
  			{
  				to.Send(new SecureTradeEquip6017(m_From.Container, from));
  			}
  			else
  			{
  				to.Send(new SecureTradeEquip(m_From.Container, from));
  			}
  
  			to.Send(new UpdateSecureTrade(m_To.Container, false, false));
  
  			if (to6017)
  			{
  				to.Send(new SecureTradeEquip6017(m_To.Container, to));
  			}
  			else
  			{
  				to.Send(new SecureTradeEquip(m_To.Container, to));
  			}
  
  			to.Send(new DisplaySecureTrade(from, m_To.Container, m_From.Container, from.Name));
  			to.Send(new UpdateSecureTrade(m_To.Container, false, false));
  
  			if (to.Account != null && to704565)
  			{
  				to.Send(new UpdateSecureTrade(m_To.Container, TradeFlag.UpdateLedger, to.Account.TotalGold, to.Account.TotalPlat));
  			}
  		}
  
  		public SecureTradeInfo From { get { return m_From; } }
  		public SecureTradeInfo To { get { return m_To; } }
  
  		public bool Valid { get { return m_Valid; } }
  
  		public void Cancel()
  		{
  			if (!m_Valid)
  			{
  				return;
  			}
  
  			var list = m_From.Container.Items;
  
  			for (var i = list.Count - 1; i >= 0; --i)
  			{
  				if (i < list.Count)
  				{
  					var item = list[i];
  
  					if (item == m_From.VirtualCheck)
  					{
  						continue;
  					}
  
  					item.OnSecureTrade(m_From.Mobile, m_To.Mobile, m_From.Mobile, false);
  
  					if (!item.Deleted)
  					{
  						m_From.Mobile.AddToBackpack(item);
  					}
  				}
  			}
  
  			list = m_To.Container.Items;
  
  			for (var i = list.Count - 1; i >= 0; --i)
  			{
  				if (i < list.Count)
  				{
  					var item = list[i];
  
  					if (item == m_To.VirtualCheck)
  					{
  						continue;
  					}
  
  					item.OnSecureTrade(m_To.Mobile, m_From.Mobile, m_To.Mobile, false);
  
  					if (!item.Deleted)
  					{
  						m_To.Mobile.AddToBackpack(item);
  					}
  				}
  			}
  
  			Close();
  		}
  
  		public void Close()
  		{
  			if (!m_Valid)
  			{
  				return;
  			}
  
  			m_From.Mobile.Send(new CloseSecureTrade(m_From.Container));
  			m_To.Mobile.Send(new CloseSecureTrade(m_To.Container));
  
  			m_Valid = false;
  
  			var ns = m_From.Mobile.NetState;
  
  			if (ns != null)
  			{
  				ns.RemoveTrade(this);
  			}
  
  			ns = m_To.Mobile.NetState;
  
  			if (ns != null)
  			{
  				ns.RemoveTrade(this);
  			}
  
  			Timer.DelayCall(m_From.Dispose);
  			Timer.DelayCall(m_To.Dispose);
  		}
  
  		public void UpdateFromCurrency()
  		{
  			UpdateCurrency(m_From, m_To);
  		}
  
  		public void UpdateToCurrency()
  		{
  			UpdateCurrency(m_To, m_From);
  		}
  
  		private static void UpdateCurrency(SecureTradeInfo left, SecureTradeInfo right)
  		{
  			if (left.Mobile.NetState != null && left.Mobile.NetState.NewSecureTrading)
  			{
  				var plat = left.Mobile.Account.TotalPlat;
  				var gold = left.Mobile.Account.TotalGold;
  
  				left.Mobile.Send(new UpdateSecureTrade(left.Container, TradeFlag.UpdateLedger, gold, plat));
  			}
  
  			if (right.Mobile.NetState != null && right.Mobile.NetState.NewSecureTrading)
  			{
  				right.Mobile.Send(new UpdateSecureTrade(right.Container, TradeFlag.UpdateGold, left.Gold, left.Plat));
  			}
  		}
  
  		public void Update()
  		{
  			if (!m_Valid)
  			{
  				return;
  			}
  
  			if (!m_From.IsDisposed && m_From.Accepted && !m_To.IsDisposed && m_To.Accepted)
  			{
  				var list = m_From.Container.Items;
  
  				var allowed = true;
  
  				for (var i = list.Count - 1; allowed && i >= 0; --i)
  				{
  					if (i < list.Count)
  					{
  						var item = list[i];
  
  						if (item == m_From.VirtualCheck)
  						{
  							continue;
  						}
  
  						if (!item.AllowSecureTrade(m_From.Mobile, m_To.Mobile, m_To.Mobile, true))
  						{
  							allowed = false;
  						}
  					}
  				}
  
  				list = m_To.Container.Items;
  
  				for (var i = list.Count - 1; allowed && i >= 0; --i)
  				{
  					if (i < list.Count)
  					{
  						var item = list[i];
  
  						if (item == m_To.VirtualCheck)
  						{
  							continue;
  						}
  
  						if (!item.AllowSecureTrade(m_To.Mobile, m_From.Mobile, m_From.Mobile, true))
  						{
  							allowed = false;
  						}
  					}
  				}
  
  				if (AccountGold.Enabled)
  				{
  					if (m_From.Mobile.Account != null)
  					{
  						var cur = m_From.Mobile.Account.TotalCurrency;
  						var off = m_From.Plat + (m_From.Gold / Math.Max(1.0, AccountGold.CurrencyThreshold));
  
  						if (off > cur)
  						{
  							allowed = false;
  							m_From.Mobile.SendMessage("You do not have enough currency to complete this trade.");
  						}
  					}
  
  					if (m_To.Mobile.Account != null)
  					{
  						var cur = m_To.Mobile.Account.TotalCurrency;
  						var off = m_To.Plat + (m_To.Gold / Math.Max(1.0, AccountGold.CurrencyThreshold));
  
  						if (off > cur)
  						{
  							allowed = false;
  							m_To.Mobile.SendMessage("You do not have enough currency to complete this trade.");
  						}
  					}
  				}
  
  				if (!allowed)
  				{
  					m_From.Accepted = false;
  					m_To.Accepted = false;
  
  					m_From.Mobile.Send(new UpdateSecureTrade(m_From.Container, m_From.Accepted, m_To.Accepted));
  					m_To.Mobile.Send(new UpdateSecureTrade(m_To.Container, m_To.Accepted, m_From.Accepted));
  
  					return;
  				}
  
  				if (AccountGold.Enabled && m_From.Mobile.Account != null && m_To.Mobile.Account != null)
  				{
  					HandleAccountGoldTrade();
  				}
  
  				list = m_From.Container.Items;
  
  				for (var i = list.Count - 1; i >= 0; --i)
  				{
  
gt: 					if (i < list.Count)