context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.IO;
  using System.Threading;
  using Server.Gumps;
  using Server.Items;
  using Server.Mobiles;
  using Server.Network;
  using Server.Spells;
  
  namespace Server.Multis
  {
      public enum FoundationType
      {
          Stone,
          DarkWood,
          LightWood,
          Dungeon,
          Brick,
          ElvenGrey,
          ElvenNatural,
          Crystal,
          Shadow
      }
  
      public class HouseFoundation : BaseHouse
      {
          private DesignState m_Current; // State which is currently visible.
          private DesignState m_Design;  // State of current design.
          private DesignState m_Backup;  // State at last user backup.
          private Item m_SignHanger;     // Item hanging the sign.
          private Item m_Signpost;       // Item supporting the hanger.
          private int m_SignpostGraphic; // ItemID number of the chosen signpost.
          private int m_LastRevision;    // Latest revision number.
          private List<Item> m_Fixtures; // List of fixtures (teleporters and doors) associated with this house.
          private FoundationType m_Type; // Graphic type of this foundation.
          private Mobile m_Customizer;   // Who is currently customizing this -or- null if not customizing.
  
          public FoundationType Type
          {
              get
              {
                  return this.m_Type;
              }
              set
              {
                  this.m_Type = value;
              }
          }
          public int LastRevision
          {
              get
              {
                  return this.m_LastRevision;
              }
              set
              {
                  this.m_LastRevision = value;
              }
          }
          public List<Item> Fixtures
          {
              get
              {
                  return this.m_Fixtures;
              }
          }
          public Item SignHanger
          {
              get
              {
                  return this.m_SignHanger;
              }
          }
          public Item Signpost
          {
              get
              {
                  return this.m_Signpost;
              }
          }
          public int SignpostGraphic
          {
              get
              {
                  return this.m_SignpostGraphic;
              }
              set
              {
                  this.m_SignpostGraphic = value;
              }
          }
          public Mobile Customizer
          {
              get
              {
                  return this.m_Customizer;
              }
              set
              {
                  this.m_Customizer = value;
              }
          }
  
          public override bool IsAosRules
          {
              get
              {
                  return true;
              }
          }
  
          public override bool IsActive
          {
              get
              {
                  return this.Customizer == null;
              }
          }
  
          public virtual int CustomizationCost
          {
              get
              {
                  return (Core.AOS ? 0 : 10000);
              }
          }
  
          public bool IsFixture(Item item)
          {
              return (this.m_Fixtures != null && this.m_Fixtures.Contains(item));
          }
  
          public override MultiComponentList Components
          {
              get
              {
                  if (this.m_Current == null)
                      this.SetInitialState();
  
                  return this.m_Current.Components;
              }
          }
  
          public override int GetMaxUpdateRange()
          {
              return 24;
          }
  
          public override int GetUpdateRange(Mobile m)
          {
              int w = this.CurrentState.Components.Width;
              int h = this.CurrentState.Components.Height - 1;
              int v = 18 + ((w > h ? w : h) / 2);
  
              if (v > 24)
                  v = 24;
              else if (v < 18)
                  v = 18;
  
              return v;
          }
  
          public DesignState CurrentState
          {
              get
              {
                  if (this.m_Current == null)
                      this.SetInitialState();
                  return this.m_Current;
              }
              set
              {
                  this.m_Current = value;
              }
          }
  
          public DesignState DesignState
          {
              get
              {
                  if (this.m_Design == null)
                      this.SetInitialState();
                  return this.m_Design;
              }
              set
              {
                  this.m_Design = value;
              }
          }
  
          public DesignState BackupState
          {
              get
              {
                  if (this.m_Backup == null)
                      this.SetInitialState();
                  return this.m_Backup;
              }
              set
              {
                  this.m_Backup = value;
              }
          }
  
          public void SetInitialState()
          {
              // This is a new house, it has not yet loaded a design state
              this.m_Current = new DesignState(this, this.GetEmptyFoundation());
              this.m_Design = new DesignState(this.m_Current);
              this.m_Backup = new DesignState(this.m_Current);
          }
  
          public override void OnAfterDelete()
          {
              base.OnAfterDelete();
  
              if (this.m_SignHanger != null)
                  this.m_SignHanger.Delete();
  
              if (this.m_Signpost != null)
                  this.m_Signpost.Delete();
  
              if (this.m_Fixtures == null)
                  return;
  
              for (int i = 0; i < this.m_Fixtures.Count; ++i)
              {
                  Item item = this.m_Fixtures[i];
  
                  if (item != null)
                      item.Delete();
              }
  
              this.m_Fixtures.Clear();
          }
  
          public override void OnLocationChange(Point3D oldLocation)
          {
              base.OnLocationChange(oldLocation);
  
              int x = this.Location.X - oldLocation.X;
              int y = this.Location.Y - oldLocation.Y;
              int z = this.Location.Z - oldLocation.Z;
  
              if (this.m_SignHanger != null)
                  this.m_SignHanger.MoveToWorld(new Point3D(this.m_SignHanger.X + x, this.m_SignHanger.Y + y, this.m_SignHanger.Z + z), this.Map);
  
              if (this.m_Signpost != null)
                  this.m_Signpost.MoveToWorld(new Point3D(this.m_Signpost.X + x, this.m_Signpost.Y + y, this.m_Signpost.Z + z), this.Map);
  
              if (this.m_Fixtures == null)
                  return;
  
              for (int i = 0; i < this.m_Fixtures.Count; ++i)
              {
                  Item item = this.m_Fixtures[i];
  
                  if (this.Doors.Contains(item))
                      continue;
  
                  item.MoveToWorld(new Point3D(item.X + x, item.Y + y, item.Z + z), this.Map);
              }
          }
  
          public override void OnMapChange()
          {
              base.OnMapChange();
  
              if (this.m_SignHanger != null)
                  this.m_SignHanger.Map = this.Map;
  
              if (this.m_Signpost != null)
                  this.m_Signpost.Map = this.Map;
  
              if (this.m_Fixtures == null)
                  return;
  
              for (int i = 0; i < this.m_Fixtures.Count; ++i)
                  this.m_Fixtures[i].Map = this.Map;
          }
  
          public void ClearFixtures(Mobile from)
          {
              if (this.m_Fixtures == null)
                  return;
  
              this.RemoveKeys(from);
  
              for (int i = 0; i < this.m_Fixtures.Count; ++i)
              {
                  this.m_Fixtures[i].Delete();
                  this.Doors.Remove(this.m_Fixtures[i]);
              }
  
              this.m_Fixtures.Clear();
          }
  
          public void AddFixtures(Mobile from, MultiTileEntry[] list)
          {
              if (this.m_Fixtures == null)
                  this.m_Fixtures = new List<Item>();
  
              uint keyValue = 0;
  
              for (int i = 0; i < list.Length; ++i)
              {
                  MultiTileEntry mte = list[i];
                  int itemID = mte.m_ItemID;
  
                  if (itemID >= 0x181D && itemID < 0x1829)
                  {
                      HouseTeleporter tp = new HouseTeleporter(itemID);
  
                      this.AddFixture(tp, mte);
                  }
                  else
                  {
                      BaseDoor door = null;
  
                      if (itemID >= 0x675 && itemID < 0x6F5)
                      {
                          int type = (itemID - 0x675) / 16;
                          DoorFacing facing = (DoorFacing)(((itemID - 0x675) / 2) % 8);
  
                          switch( type )
                          {
                              case 0:
                                  door = new GenericHouseDoor(facing, 0x675, 0xEC, 0xF3);
                                  break;
                              case 1:
                                  door = new GenericHouseDoor(facing, 0x685, 0xEC, 0xF3);
                                  break;
                              case 2:
                                  door = new GenericHouseDoor(facing, 0x695, 0xEB, 0xF2);
                                  break;
                              case 3:
                                  door = new GenericHouseDoor(facing, 0x6A5, 0xEA, 0xF1);
                                  break;
                              case 4:
                                  door = new GenericHouseDoor(facing, 0x6B5, 0xEA, 0xF1);
                                  break;
                              case 5:
                                  door = new GenericHouseDoor(facing, 0x6C5, 0xEC, 0xF3);
                                  break;
                              case 6:
                                  door = new GenericHouseDoor(facing, 0x6D5, 0xEA, 0xF1);
                                  break;
                              case 7:
                                  door = new GenericHouseDoor(facing, 0x6E5, 0xEA, 0xF1);
                                  break;
                          }
                      }
                      else if (itemID >= 0x314 && itemID < 0x364)
                      {
                          int type = (itemID - 0x314) / 16;
                          DoorFacing facing = (DoorFacing)(((itemID - 0x314) / 2) % 8);
                          door = new GenericHouseDoor(facing, 0x314 + (type * 16), 0xED, 0xF4);
                      }
  
gt:                     else if (itemID >= 0x824 && itemID < 0x834)