context: using System;
  using System.Collections.Generic;
  using Server.ContextMenus;
  using Server.Engines.Craft;
  using Server.Factions;
  using Server.Network;
  using Server.MainConfiguration;
  using Server.T2AConfiguration;
  
  namespace Server.Items
  {
      public enum ClothingQuality
      {
          Low,
          Regular,
          Exceptional
      }
  
      public interface IArcaneEquip
      {
          bool IsArcane { get; }
          int CurArcaneCharges { get; set; }
          int MaxArcaneCharges { get; set; }
      }
  
      public abstract class BaseClothing : Item, IDyable, IScissorable, IFactionItem, ICraftable, IWearableDurability, ISetItem
      {
          private FactionItem m_FactionState;
  
          public FactionItem FactionItemState
          {
              get
              {
                  return m_FactionState;
              }
              set
              {
                  m_FactionState = value;
  
                  if (m_FactionState == null)
                      Hue = 0;
  
                  LootType = (m_FactionState == null ? LootType.Regular : LootType.Blessed);
              }
          }
  
          private bool m_Identified;
          [CommandProperty(AccessLevel.GameMaster)]
          public bool Identified
          {
              get { return m_Identified; }
              set { m_Identified = value; InvalidateProperties(); }
          }
  
          //public virtual bool CanFortify { get { return m_TimesImbued == 0 && NegativeAttributes.Antique < 3; } }
          //public virtual bool CanFortify { get { return m_IsImbued == false && NegativeAttributes.Antique < 3; } }
          public virtual bool CanFortify { get { return !IsImbued  && NegativeAttributes.Antique < 3; } }
          public virtual bool CanRepair { get { return m_NegativeAttributes.NoRepair == 0; } }
          public virtual bool CanImbue { get { return ArtifactRarity == 0; } }
  
          private int m_MaxHitPoints;
          private int m_HitPoints;
          private Mobile m_Crafter;
          private ClothingQuality m_Quality;
          private bool m_PlayerConstructed;
          protected CraftResource m_Resource;
          private int m_StrReq = -1;
  
          private AosAttributes m_AosAttributes;
          private AosArmorAttributes m_AosClothingAttributes;
          private AosSkillBonuses m_AosSkillBonuses;
          private AosElementAttributes m_AosResistances;
          private SAAbsorptionAttributes m_SAAbsorptionAttributes;
          private NegativeAttributes m_NegativeAttributes;
  
          private int m_TimesImbued;
          private bool m_IsImbued;
          private int m_PhysImbuing;
          private int m_FireImbuing;
          private int m_ColdImbuing;
          private int m_PoisonImbuing;
          private int m_EnergyImbuing;
          private bool m_BlockRepair;
          private ItemPower m_ItemPower;
          private ReforgedPrefix m_ReforgedPrefix;
          private ReforgedSuffix m_ReforgedSuffix;
  
          private bool m_Altered;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int MaxHitPoints
          {
              get { return m_MaxHitPoints; }
              set
              {
                  m_MaxHitPoints = value;
                  if (m_MaxHitPoints <= HitPoints)
                      HitPoints = m_MaxHitPoints;
                  else
                      InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int HitPoints
          {
              get
              {
                  return m_HitPoints;
              }
              set
              {
                  if (value != m_HitPoints && MaxHitPoints > 0)
                  {
                      if (value >= MaxHitPoints)
                      {
                          m_HitPoints = MaxHitPoints;
                          if (m_SelfRepairTimer != null)
                              m_SelfRepairTimer.Stop();
                      }
                      else
                      {
                          if (value < 1)
                              Delete();
                          else
                          {
                              m_HitPoints = value;
                              if (m_AosClothingAttributes.SelfRepair > 0 && Parent is Mobile)
                              {
                                  if (m_SelfRepairTimer == null)
                                      m_SelfRepairTimer = Timer.DelayCall(GetSelfRepairTimeSpan(), GetSelfRepairTimeSpan(), new TimerCallback(OnSelfRepairTimerTick));
                                  else
                                      m_SelfRepairTimer.Start();
                              }
                          }
                      }
  
                      InvalidateProperties();
                  }
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile Crafter
          {
              get
              {
                  return m_Crafter;
              }
              set
              {
                  m_Crafter = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int StrRequirement
          {
              get
              {
                  //return (m_StrReq == -1 ? (Core.AOS ? AosStrReq : OldStrReq) : m_StrReq);
                  return (int)((double)(m_StrReq == -1 ? (Core.AOS ? AosStrReq : OldStrReq) : m_StrReq) * (m_NegativeAttributes.Massive > 0 ? 1.5 : 1)); 
              }
              set
              {
                  m_StrReq = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ClothingQuality Quality
          {
              get
              {
                  return m_Quality;
              }
              set
              {
                  m_Quality = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool PlayerConstructed
          {
              get
              {
                  return m_PlayerConstructed;
              }
              set
              {
                  m_PlayerConstructed = value;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int TimesImbued
          {
              get { return m_TimesImbued; }
              set { m_TimesImbued = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool IsImbued
          {
              get
              {
                  //if (this.TimesImbued >= 1)
                  if (TimesImbued >= 1 && !m_IsImbued)
                  {
                      m_IsImbued = true;
                  }
                  return m_IsImbued;
              }
              set
              {
                  if (TimesImbued >= 1)
                  {
                      m_IsImbued = true;
                  }
                  else
                  {
                      m_IsImbued = value; InvalidateProperties();
                  }
              }
          }
  
          public int PhysImbuing
          {
              get { return m_PhysImbuing; }
              set { m_PhysImbuing = value; }
          }
  
          public int FireImbuing
          {
              get { return m_FireImbuing; }
              set { m_FireImbuing = value; }
          }
  
          public int ColdImbuing
          {
              get { return m_ColdImbuing; }
              set { m_ColdImbuing = value; }
          }
  
          public int PoisonImbuing
          {
              get { return m_PoisonImbuing; }
              set { m_PoisonImbuing = value; }
          }
  
          public int EnergyImbuing
          {
              get { return m_EnergyImbuing; }
              set { m_EnergyImbuing = value; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ReforgedPrefix ReforgedPrefix
          {
              get { return m_ReforgedPrefix; }
              set { m_ReforgedPrefix = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ReforgedSuffix ReforgedSuffix
          {
              get { return m_ReforgedSuffix; }
              set { m_ReforgedSuffix = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool BlockRepair
          {
              get { return m_BlockRepair; }
              set { m_BlockRepair = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ItemPower ItemPower
          {
              get { return m_ItemPower; }
              set { m_ItemPower = value; InvalidateProperties(); }
          }
  
          #region Personal Bless Deed
          private Mobile m_BlessedBy;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile BlessedBy
          {
              get
              {
                  return m_BlessedBy;
              }
              set
              {
                  m_BlessedBy = value;
                  InvalidateProperties();
              }
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
  
              if (BlessedFor == from && BlessedBy == from && RootParent == from)
              {
                  list.Add(new UnBlessEntry(from, this));
              }
          }
  
          private class UnBlessEntry : ContextMenuEntry
          {
              private readonly Mobile m_From;
              private readonly BaseClothing m_Item;
  
              public UnBlessEntry(Mobile from, BaseClothing item)
                  : base(6208, -1)
              {
                  m_From = from;
                  m_Item = item; // BaseArmor, BaseWeapon or BaseClothing
              }
  
              public override void OnClick()
              {
                  m_Item.BlessedFor = null;
                  m_Item.BlessedBy = null;
  
                  Container pack = m_From.Backpack;
  
                  if (pack != null)
                  {
                      pack.DropItem(new PersonalBlessDeed(m_From));
                      m_From.SendLocalizedMessage(1062200); // A personal bless deed has been placed in your backpack.
                  }
              }
          }
          #endregion
  
          public virtual CraftResource DefaultResource
          {
              get
              {
                  return CraftResource.None;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public CraftResource Resource
          {
              get
              {
                  return m_Resource;
              }
              set
              {
                  m_Resource = value;
                  Hue = CraftResources.GetHue(m_Resource);
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosAttributes Attributes
          {
              get
              {
                  return m_AosAttributes;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosArmorAttributes ClothingAttributes
          {
              get
              {
                  return m_AosClothingAttributes;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosSkillBonuses SkillBonuses
          {
              get
              {
                  return m_AosSkillBonuses;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosElementAttributes Resistances
          {
              get
              {
                  return m_AosResistances;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public SAAbsorptionAttributes AbsorptionAttributes { get { return m_SAAbsorptionAttributes; } set { } }
  
          [CommandProperty(AccessLevel.GameMaster)]  
          public NegativeAttributes NegativeAttributes  
          {  
              get   
              {   
                  return m_NegativeAttributes;  
              }  
              set   
              {  
              }  
          }
  
          public virtual int BasePhysicalResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseFireResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseColdResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BasePoisonResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseEnergyResistance
          {
              get
              {
                  return 0;
              }
          }
  
          public override int PhysicalResistance
          {
              get
              {
                  return BasePhysicalResistance + m_AosResistances.Physical + (m_SetEquipped ? m_SetPhysicalBonus : 0);
              }
          }
          public override int FireResistance
          {
              get
              {
                  return BaseFireResistance + m_AosResistances.Fire + (m_SetEquipped ? m_SetFireBonus : 0);
              }
          }
          public override int ColdResistance
          {
              get
              {
                  return BaseColdResistance + m_AosResistances.Cold + (m_SetEquipped ? m_SetColdBonus : 0);
              }
          }
          public override int PoisonResistance
          {
              get
              {
                  return BasePoisonResistance + m_AosResistances.Poison + (m_SetEquipped ? m_SetPoisonBonus : 0);
              }
          }
          public override int EnergyResistance
          {
              get
              {
                  return BaseEnergyResistance + m_AosResistances.Energy + (m_SetEquipped ? m_SetEnergyBonus : 0);
              }
          }
  
          public virtual int ArtifactRarity
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual int BaseStrBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseDexBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseIntBonus
          {
              get
              {
                  return 0;
              }
          }
  
          public override double DefaultWeight
          {
              get
              {
                  if (NegativeAttributes == null || NegativeAttributes.Unwieldly == 0)
                      return base.DefaultWeight;
  
                  return base.DefaultWeight * 3;
              }
          }
  
          public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
          {
              if (!Ethics.Ethic.CheckTrade(from, to, newOwner, this))
                  return false;
  
              return base.AllowSecureTrade(from, to, newOwner, accepted);
          }
  
          public virtual Race RequiredRace
          {
              get
              {
                  return null;
              }
          }
  
          public virtual bool CanBeWornByGargoyles
          {
              get
              {
                  return false;
              }
          }
  
          public override bool CanEquip(Mobile from)
          {
              if (!Ethics.Ethic.CheckEquip(from, this))
                  return false;
  
              if (from.IsPlayer())
              {
                  if (MainConfig.MainItemIDEnabled || T2AConfig.T2AItemIDEnabled)
                  {
                      if (from.Race == Race.Gargoyle && !CanBeWornByGargoyles)
                      {
                          from.SendLocalizedMessage(1111708); // Gargoyles can't wear 
                          return false;
                      }
                      else if (RequiredRace != null && from.Race != RequiredRace)
                      {
                          if (RequiredRace == Race.Elf)
                              from.SendLocalizedMessage(1072203); // Only Elves may use 
                          else if (RequiredRace == Race.Gargoyle)
                              from.SendLocalizedMessage(1111707); // Only gargoyles can wear 
                          else
                              from.SendMessage("Only {0} may use ", RequiredRace.PluralName);
  
                          return false;
                      }
                      else if (m_Identified == false)
                      {
                          from.SendMessage("You are hesitant to put on something that is unknown to you");
                          return false;
                      }
                      else if (!AllowMaleWearer && !from.Female)
                      {
                          if (AllowFemaleWearer)
                              from.SendLocalizedMessage(1010388); // Only females can wear 
                          else
                              from.SendMessage("You may not wear ");
  
                          return false;
                      }
                      else if (!AllowFemaleWearer && from.Female)
                      {
                          if (AllowMaleWearer)
                              from.SendLocalizedMessage(1063343); // Only males can wear 
                          else
                              from.SendMessage("You may not wear ");
  
                          return false;
                      }
                      else if (BlessedBy != null && BlessedBy != from)
                      {
                          from.SendLocalizedMessage(1075277); // That item is blessed by another player.
  
                          return false;
                      }
                      else
                      {
                          int strBonus = ComputeStatBonus(StatType.Str);
                          int strReq = ComputeStatReq(StatType.Str);
  
                          if (from.Str < strReq || (from.Str + strBonus) < 1)
                          {
                              from.SendLocalizedMessage(500213); // You are not strong enough to equip that.
                              return false;
                          }
                      }
                  }
                  else
                  {
                      if (from.Race == Race.Gargoyle && !CanBeWornByGargoyles)
                      {
                          from.SendLocalizedMessage(1111708); // Gargoyles can't wear 
                          return false;
                      }
                      else if (RequiredRace != null && from.Race != RequiredRace)
                      {
                          if (RequiredRace == Race.Elf)
                              from.SendLocalizedMessage(1072203); // Only Elves may use 
                          else if (RequiredRace == Race.Gargoyle)
                              from.SendLocalizedMessage(1111707); // Only gargoyles can wear 
                          else
                              from.SendMessage("Only {0} may use ", RequiredRace.PluralName);
  
                          return false;
                      }
                      else if (!AllowMaleWearer && !from.Female)
                      {
                          if (AllowFemaleWearer)
                              from.SendLocalizedMessage(1010388); // Only females can wear 
                          else
                              from.SendMessage("You may not wear ");
  
                          return false;
                      }
                      else if (!AllowFemaleWearer && from.Female)
                      {
                          if (AllowMaleWearer)
                              from.SendLocalizedMessage(1063343); // Only males can wear 
                          else
                              from.SendMessage("You may not wear ");
  
                          return false;
                      }
                      else if (BlessedBy != null && BlessedBy != from)
                      {
                          from.SendLocalizedMessage(1075277); // That item is blessed by another player.
  
                          return false;
                      }
                      else
                      {
                          int strBonus = ComputeStatBonus(StatType.Str);
                          int strReq = ComputeStatReq(StatType.Str);
  
                          if (from.Str < strReq || (from.Str + strBonus) < 1)
                          {
                              from.SendLocalizedMessage(500213); // You are not strong enough to equip that.
                              return false;
                          }
                      }
                  }
              }
  
              return base.CanEquip(from);
          }
  
          public virtual int AosStrReq
          {
              get
              {
                  return 10;
              }
          }
          public virtual int OldStrReq
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual int InitMinHits
          {
              get
              {
                  return 0;
              }
          }
          public virtual int InitMaxHits
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual bool Brittle { get { return false; } }
          public virtual bool NoRepairs { get { return false; } }
  
          public virtual bool AllowMaleWearer
          {
              get
              {
                  return true;
              }
          }
          public virtual bool AllowFemaleWearer
          {
              get
              {
                  return true;
              }
          }
          public virtual bool CanBeBlessed
          {
              get
              {
                  return true;
              }
          }
  
          public int ComputeStatReq(StatType type)
          {
              return ItemAttributes.Scale(StrRequirement, 100 - GetLowerStatReq());
          }
  
          public int ComputeStatBonus(StatType type)
          {
              if (type == StatType.Str)
                  return BaseStrBonus + Attributes.BonusStr;
              else if (type == StatType.Dex)
                  return BaseDexBonus + Attributes.BonusDex;
              else
                  return BaseIntBonus + Attributes.BonusInt;
          }
  
          public virtual void AddStatBonuses(Mobile parent)
          {
              if (parent == null)
                  return;
  
              int strBonus = ComputeStatBonus(StatType.Str);
              int dexBonus = ComputeStatBonus(StatType.Dex);
              int intBonus = ComputeStatBonus(StatType.Int);
  
              if (strBonus == 0 && dexBonus == 0 && intBonus == 0)
                  return;
  
              string modName = Serial.ToString();
  
              if (strBonus != 0)
                  parent.AddStatMod(new StatMod(StatType.Str, modName + "Str", strBonus, TimeSpan.Zero));
  
              if (dexBonus != 0)
                  parent.AddStatMod(new StatMod(StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero));
  
              if (intBonus != 0)
                  parent.AddStatMod(new StatMod(StatType.Int, modName + "Int", intBonus, TimeSpan.Zero));
          }
  
          public static void ValidateMobile(Mobile m)
          {
              for (int i = m.Items.Count - 1; i >= 0; --i)
              {
                  if (i >= m.Items.Count)
                      continue;
  
                  Item item = m.Items[i];
  
                  if (item is BaseClothing)
                  {
                      BaseClothing clothing = (BaseClothing)item;
  
                      if (m.Race == Race.Gargoyle && !clothing.CanBeWornByGargoyles)
                      {
                          m.SendLocalizedMessage(1111708); // Gargoyles can't wear 
                          m.AddToBackpack(clothing);
                      }
  
                      if (clothing.RequiredRace != null && m.Race != clothing.RequiredRace)
                      {
                          if (clothing.RequiredRace == Race.Elf)
                              m.SendLocalizedMessage(1072203); // Only Elves may use 
                          else if (clothing.RequiredRace == Race.Gargoyle)
                              m.SendLocalizedMessage(1111707); // Only gargoyles can wear 
                          else
                              m.SendMessage("Only {0} may use ", clothing.RequiredRace.PluralName);
  
                          m.AddToBackpack(clothing);
                      }
                      else if (!clothing.AllowMaleWearer && !m.Female && m.AccessLevel < AccessLevel.GameMaster)
                      {
                          if (clothing.AllowFemaleWearer)
                              m.SendLocalizedMessage(1010388); // Only females can wear 
                          else
                              m.SendMessage("You may not wear ");
  
                          m.AddToBackpack(clothing);
                      }
                      else if (!clothing.AllowFemaleWearer && m.Female && m.AccessLevel < AccessLevel.GameMaster)
                      {
                          if (clothing.AllowMaleWearer)
                              m.SendLocalizedMessage(1063343); // Only males can wear 
                          else
                              m.SendMessage("You may not wear ");
  
                          m.AddToBackpack(clothing);
                      }
                  }
              }
          }
  
          public int GetLowerStatReq()
          {
              if (!Core.AOS)
                  return 0;
  
              return m_AosClothingAttributes.LowerStatReq;
          }
  
          public override void OnAdded(IEntity parent)
          {
              Mobile mob = parent as Mobile;
  
              if (mob != null)
              {
                  if (Core.AOS)
                      m_AosSkillBonuses.AddTo(mob);
  
                  if (IsSetItem)
                  {
                      m_SetEquipped = SetHelper.FullSetEquipped(mob, SetID, Pieces);
  
                      if (m_SetEquipped)
                      {
                          m_LastEquipped = true;
                          SetHelper.AddSetBonus(mob, SetID);
                      }
                  }
  
                  AddStatBonuses(mob);
                  mob.CheckStatTimers();
  
                  if (HitPoints < MaxHitPoints && m_AosClothingAttributes.SelfRepair > 0)
                  {
                      if (m_SelfRepairTimer == null)
                          m_SelfRepairTimer = Timer.DelayCall(GetSelfRepairTimeSpan(), GetSelfRepairTimeSpan(), new TimerCallback(OnSelfRepairTimerTick));
                      else
                          m_SelfRepairTimer.Start();
                  }
              }
  
              base.OnAdded(parent);
          }
  
          protected Timer m_SelfRepairTimer;
  
          public override void OnMapChange()
          {
              if (m_AosClothingAttributes.SelfRepair > 0)
              {
                  if (Map == null || Map == Map.Internal)
                  {
                      if (m_SelfRepairTimer != null)
                          m_SelfRepairTimer.Stop();
                  }
                  else if (Parent is Mobile && HitPoints < MaxHitPoints)
                  {
                      if (m_SelfRepairTimer == null)
                          m_SelfRepairTimer = Timer.DelayCall(GetSelfRepairTimeSpan(), GetSelfRepairTimeSpan(), new TimerCallback(OnSelfRepairTimerTick));
                      else
                          m_SelfRepairTimer.Start();
                  }
              }
          }
  
          public void OnSelfRepairChanged()
          {
              if (m_SelfRepairTimer != null)
              {
                  m_SelfRepairTimer.Stop();
                  m_SelfRepairTimer = null;
              }
  
              if (m_AosClothingAttributes.SelfRepair > 0)
                  m_SelfRepairTimer = Timer.DelayCall(GetSelfRepairTimeSpan(), GetSelfRepairTimeSpan(), new TimerCallback(OnSelfRepairTimerTick));
          }
  
          private void OnSelfRepairTimerTick()
          {
              if (Deleted || Map == null || Map == Map.Internal)
                  m_SelfRepairTimer.Stop();
              else
                  ++HitPoints;
          }
  
          private TimeSpan GetSelfRepairTimeSpan()
          {
              switch (m_AosClothingAttributes.SelfRepair)
              {
                  case 10: return TimeSpan.FromSeconds(7.03125);
                  case 9: return TimeSpan.FromSeconds(14.0625);
                  case 8: return TimeSpan.FromMinutes(0.46875);
                  case 7: return TimeSpan.FromMinutes(0.9375);
                  case 6: return TimeSpan.FromMinutes(1.875);
                  case 5: return TimeSpan.FromMinutes(3.75);
                  case 4: return TimeSpan.FromMinutes(7.5);
                  case 3: return TimeSpan.FromMinutes(15);
                  case 2: return TimeSpan.FromMinutes(30);
                  case 1: return TimeSpan.FromMinutes(60);
                  case 0:
                  default: return TimeSpan.FromMinutes(0.1171875);
              }
          }
  
          public override void OnRemoved(IEntity parent)
          {
  
gt:             if (m_SelfRepairTimer != null)