context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Globalization;
  using Server.ContextMenus;
  using Server.Gumps;
  using Server.Items;
  using Server.Misc;
  using Server.Multis;
  using Server.Prompts;
  using Server.Targeting;
  
  namespace Server.Mobiles
  {
      [AttributeUsage(AttributeTargets.Class)]
      public class PlayerVendorTargetAttribute : Attribute
      {
          public PlayerVendorTargetAttribute()
          {
          }
      }
  
      public class VendorItem
      {
          private readonly Item m_Item;
          private readonly int m_Price;
          private readonly DateTime m_Created;
          private string m_Description;
          private bool m_Valid;
          public VendorItem(Item item, int price, string description, DateTime created)
          {
              this.m_Item = item;
              this.m_Price = price;
  
              if (description != null)
                  this.m_Description = description;
              else
                  this.m_Description = "";
  
              this.m_Created = created;
  
              this.m_Valid = true;
          }
  
          public Item Item
          {
              get
              {
                  return this.m_Item;
              }
          }
          public int Price
          {
              get
              {
                  return this.m_Price;
              }
          }
          public string FormattedPrice
          {
              get
              {
                  if (Core.ML)
                      return this.m_Price.ToString("N0", CultureInfo.GetCultureInfo("en-US"));
  
                  return this.m_Price.ToString();
              }
          }
          public string Description
          {
              get
              {
                  return this.m_Description;
              }
              set
              {
                  if (value != null)
                      this.m_Description = value;
                  else
                      this.m_Description = "";
  
                  if (this.Valid)
                      this.Item.InvalidateProperties();
              }
          }
          public DateTime Created
          {
              get
              {
                  return this.m_Created;
              }
          }
          public bool IsForSale
          {
              get
              {
                  return this.Price >= 0;
              }
          }
          public bool IsForFree
          {
              get
              {
                  return this.Price == 0;
              }
          }
          public bool Valid
          {
              get
              {
                  return this.m_Valid;
              }
          }
          public void Invalidate()
          {
              this.m_Valid = false;
          }
      }
  
      public class VendorBackpack : Backpack
      {
          public VendorBackpack()
          {
              this.Layer = Layer.Backpack;
              this.Weight = 1.0;
          }
  
          public VendorBackpack(Serial serial)
              : base(serial)
          {
          }
  
          public override int DefaultMaxWeight
          {
              get
              {
                  return 0;
              }
          }
          public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
          {
              if (!base.CheckHold(m, item, message, checkItems, plusItems, plusWeight))
                  return false;
  
              if (Ethics.Ethic.IsImbued(item, true))
              {
                  if (message)
                      m.SendMessage("Imbued items may not be sold here.");
  
                  return false;
              }
  
              if (!BaseHouse.NewVendorSystem && this.Parent is PlayerVendor)
              {
                  BaseHouse house = ((PlayerVendor)this.Parent).House;
  
                  if (house != null && house.IsAosRules && !house.CheckAosStorage(1 + item.TotalItems + plusItems))
                  {
                      if (message)
                          m.SendLocalizedMessage(1061839); // This action would exceed the secure storage limit of the house.
  
                      return false;
                  }
              }
  
              return true;
          }
  
          public override bool IsAccessibleTo(Mobile m)
          {
              return true;
          }
  
          public override bool CheckItemUse(Mobile from, Item item)
          {
              if (!base.CheckItemUse(from, item))
                  return false;
  
              if (item is Container || item is Engines.BulkOrders.BulkOrderBook)
                  return true;
  
              from.SendLocalizedMessage(500447); // That is not accessible.
              return false;
          }
  
          public override bool CheckTarget(Mobile from, Target targ, object targeted)
          {
              if (!base.CheckTarget(from, targ, targeted))
                  return false;
  
              if (from.AccessLevel >= AccessLevel.GameMaster)
                  return true;
  
              return targ.GetType().IsDefined(typeof(PlayerVendorTargetAttribute), false);
          }
  
          public override void GetChildContextMenuEntries(Mobile from, List<ContextMenuEntry> list, Item item)
          {
              base.GetChildContextMenuEntries(from, list, item);
  
              PlayerVendor pv = this.RootParent as PlayerVendor;
  
              if (pv == null || pv.IsOwner(from))
                  return;
  
              VendorItem vi = pv.GetVendorItem(item);
  
              if (vi != null)
                  list.Add(new BuyEntry(item));
          }
  
          public override void GetChildNameProperties(ObjectPropertyList list, Item item)
          {
              base.GetChildNameProperties(list, item);
  
              PlayerVendor pv = this.RootParent as PlayerVendor;
  
              if (pv == null)
                  return;
  
              VendorItem vi = pv.GetVendorItem(item);
  
              if (vi == null)
                  return;
  
              if (!vi.IsForSale)
                  list.Add(1043307); // Price: Not for sale.
              else if (vi.IsForFree)
                  list.Add(1043306); // Price: FREE!
              else
                  list.Add(1043304, vi.FormattedPrice); // Price: ~1_COST~
          }
  
          public override void GetChildProperties(ObjectPropertyList list, Item item)
          {
              base.GetChildProperties(list, item);
  
              PlayerVendor pv = this.RootParent as PlayerVendor;
  
              if (pv == null)
                  return;
  
              VendorItem vi = pv.GetVendorItem(item);
  
              if (vi != null && vi.Description != null && vi.Description.Length > 0)
                  list.Add(1043305, vi.Description); // <br>Seller's Description:<br>"~1_DESC~"
          }
  
          public override void OnSingleClickContained(Mobile from, Item item)
          {
              if (this.RootParent is PlayerVendor)
              {
                  PlayerVendor vendor = (PlayerVendor)this.RootParent;
  
                  VendorItem vi = vendor.GetVendorItem(item);
  
                  if (vi != null)
                  {
                      if (!vi.IsForSale)
                          item.LabelTo(from, 1043307); // Price: Not for sale.
                      else if (vi.IsForFree)
                          item.LabelTo(from, 1043306); // Price: FREE!
                      else
                          item.LabelTo(from, 1043304, vi.FormattedPrice); // Price: ~1_COST~
  
                      if (!String.IsNullOrEmpty(vi.Description))
                      {
                          // The localized message (1043305) is no longer valid - <br>Seller's Description:<br>"~1_DESC~"
                          item.LabelTo(from, "Description: {0}", vi.Description);
                      }
                  }
              }
  
              base.OnSingleClickContained(from, item);
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              writer.Write((int)0); // version
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
  
              int version = reader.ReadInt();
          }
  
          private class BuyEntry : ContextMenuEntry
          {
              private readonly Item m_Item;
              public BuyEntry(Item item)
                  : base(6103)
              {
                  this.m_Item = item;
              }
  
              public override bool NonLocalUse
              {
                  get
                  {
                      return true;
                  }
              }
              public override void OnClick()
              {
                  if (this.m_Item.Deleted)
                      return;
  
                  PlayerVendor.TryToBuy(this.m_Item, this.Owner.From);
              }
          }
      }
  
      public class PlayerVendor : Mobile
      {
          private Hashtable m_SellItems;
          private Mobile m_Owner;
          private BaseHouse m_House;
          private int m_BankAccount;
          private int m_HoldGold;
          private string m_ShopName;
          private Timer m_PayTimer;
          private DateTime m_NextPayTime;
          private PlayerVendorPlaceholder m_Placeholder;
          public PlayerVendor(Mobile owner, BaseHouse house)
          {
              this.Owner = owner;
              this.House = house;
  
              if (BaseHouse.NewVendorSystem)
              {
                  this.m_BankAccount = 0;
                  this.m_HoldGold = 4;
              }
              else
              {
                  this.m_BankAccount = 1000;
                  this.m_HoldGold = 0;
              }
  
              this.ShopName = "Shop Not Yet Named";
  
              this.m_SellItems = new Hashtable();
  
              this.CantWalk = true;
  
              if (!Core.AOS)
                  this.NameHue = 0x35;
  
              this.InitStats(75, 75, 75);
              this.InitBody();
              this.InitOutfit();
  
              TimeSpan delay = PayTimer.GetInterval();
  
  
gt:             this.m_PayTimer = new PayTimer(this, delay);