context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.IO;
  using System.Reflection;
  using Server.Gumps;
  using Server.Network;
  
  
  namespace Server.ACC.CM
  {
      public enum Pages
      {
          Home,
          ListMobiles,
          ListItems,
          ListModulesFor
      };
  
      public class CMGumpParams : ACCGumpParams
      {
          public Pages PageName;
          public Serial SelectedSerial;
          public int PageIndex;
  
          public CMGumpParams()
              : base()
          {
          }
      }
  
      public partial class CentralMemory : ACCSystem
      {
          internal static List<Type> m_Types = new List<Type>();
          private static Dictionary<Serial, ModuleList> m_DictionaryOfModuleLists = new Dictionary<Serial, ModuleList>();
          public static Dictionary<Serial, ModuleList> DictionaryOfModuleLists
          {
              get
              {
                  return m_DictionaryOfModuleLists;
              }
          }
  
          public static void Configure()
          {
              ACC.RegisterSystem("Server.ACC.CM.CentralMemory");
          }
  
          public static bool Running
          {
              get { return ACC.SysEnabled("Server.ACC.CM.CentralMemory"); }
          }
  
          #region BasicOverrides
          public override string Name() { return "Central Memory"; }
  
          public override void Enable()
          {
              Console.WriteLine("{0} has just been enabled!", Name());
          }
  
          public override void Disable()
          {
              Console.WriteLine("{0} has just been disabled!", Name());
          }
          #endregion //BasicOverrides
  
          #region Methods
          public static void Flush()
          {
              List<Serial> RemoveList = new List<Serial>();
  
              foreach (Serial s in m_DictionaryOfModuleLists.Keys)
              {
                  if (s.IsItem)
                  {
                      Item i = World.FindItem(s);
                      if (i == null || i.Deleted)
                          RemoveList.Add(s);
                  }
                  else if (s.IsMobile)
                  {
                      Mobile m = World.FindMobile(s);
                      if (m == null || m.Deleted)
                          RemoveList.Add(s);
                  }
  
                  if (m_DictionaryOfModuleLists[s].Count == 0)
                      RemoveList.Add(s);
              }
  
              foreach (Serial s in RemoveList)
              {
                  Remove(s);
              }
  
              RemoveList.Clear();
  
              Console.Write("Flushed...");
          }
  
          public static bool Contains(Serial ser)
          {
              return m_DictionaryOfModuleLists.ContainsKey(ser);
          }
  
          public static bool ContainsModule(Serial ser, Type type)
          {
              if (Contains(ser))
              {
                  if (m_DictionaryOfModuleLists[ser] != null)
                      return m_DictionaryOfModuleLists[ser].Contains(type);
              }
              return false;
          }
  
          public static void Add(Serial ser)
          {
              if (Contains(ser))
                  return;
  
              m_DictionaryOfModuleLists.Add(ser, new ModuleList(ser));
          }
  
          public static void Add(Serial ser, ModuleList list)
          {
              m_DictionaryOfModuleLists[ser] = list;
          }
  
          public static void AddModule(Module mod)
          {
              if (!m_DictionaryOfModuleLists.ContainsKey(mod.Owner))
                  Add(mod.Owner);
  
              m_DictionaryOfModuleLists[mod.Owner].Add(mod);
          }
  
          public static void AddModule(Serial ser, Type type)
          {
              if (!m_DictionaryOfModuleLists.ContainsKey(ser))
                  Add(ser);
  
              m_DictionaryOfModuleLists[ser].Add(type);
          }
  
          public static void ChangeModule(Serial ser, Module mod)
          {
              if (!m_DictionaryOfModuleLists.ContainsKey(ser))
                  Add(ser);
  
              m_DictionaryOfModuleLists[ser].Change(mod);
          }
  
          public static void AppendModule(Serial ser, Module mod, bool negatively)
          {
              if (!m_DictionaryOfModuleLists.ContainsKey(ser))
                  Add(ser);
              else if (!ContainsModule(ser, mod.GetType()))
              {
                  AddModule(mod);
                  return;
              }
              else
              {
                  m_DictionaryOfModuleLists[ser].Append(mod, negatively);
              }
          }
  
          public static void Remove(Serial ser)
          {
              m_DictionaryOfModuleLists.Remove(ser);
          }
  
          public static void RemoveModule(Serial ser, Module mod)
          {
              if (m_DictionaryOfModuleLists.ContainsKey(ser))
                  m_DictionaryOfModuleLists[ser].Remove(mod);
          }
  
          public static void RemoveModule(Serial ser, Type type)
          {
              if (m_DictionaryOfModuleLists.ContainsKey(ser))
                  m_DictionaryOfModuleLists[ser].Remove(type);
          }
  
          public static Module GetModule(Serial ser, Type type)
          {
              if (m_DictionaryOfModuleLists.ContainsKey(ser))
                  return m_DictionaryOfModuleLists[ser].Get(type);
  
              return null;
          }
  
          public static List<Mobile> GetMobiles()
          {
              List<Mobile> list = new List<Mobile>();
              foreach (Serial s in m_DictionaryOfModuleLists.Keys)
              {
                  if (s.IsMobile)
                  {
                      Mobile m = World.FindMobile(s);
                      if (m != null && !m.Deleted)
                          list.Add(m);
                  }
              }
  
              return list;
          }
  
          public static List<Item> GetItems()
          {
              List<Item> list = new List<Item>();
              foreach (Serial s in m_DictionaryOfModuleLists.Keys)
              {
                  if (s.IsItem)
                  {
                      Item i = World.FindItem(s);
                      if (i != null && !i.Deleted)
                          list.Add(i);
                  }
              }
  
              return list;
          }
          #endregion //Methods
  
          private CMGumpParams Params;
          private List<Mobile> m_MobileList;
          private List<Item> m_ItemList;
          private List<Module> m_ModuleList;
          private Module m_Module;
  
          #region Gump
          public override void Gump(Mobile from, Gump gump, ACCGumpParams subParams)
          {
              gump.AddButton(190, 40, 2445, 2445, 101, GumpButtonType.Reply, 0);
              gump.AddLabel(204, 42, 1153, "List Mobiles");
              gump.AddButton(310, 40, 2445, 2445, 102, GumpButtonType.Reply, 0);
              gump.AddLabel(331, 42, 1153, "List Items");
              gump.AddButton(430, 40, 2445, 2445, 103, GumpButtonType.Reply, 0);
              gump.AddLabel(450, 42, 1153, "List Types");
              //			gump.AddButton( 190, 70, 2445, 2445, 104, GumpButtonType.Reply, 0 );
              //			gump.AddLabel(  208, 72, 1153, "Add Module" );
              //			gump.AddButton( 310, 70, 2445, 2445, 105, GumpButtonType.Reply, 0 );
              //			gump.AddLabel(  326, 72, 1153, "Edit Module" );
              //			gump.AddButton( 430, 70, 2445, 2445, 106, GumpButtonType.Reply, 0 );
              //			gump.AddLabel(  439, 72, 1153, "Delete Module" );
  
              if (subParams == null || !(subParams is CMGumpParams))
              {
                  gump.AddHtml(215, 15, 300, 25, "<basefont size=7 color=white><center>Central Memory</center></font>", false, false);
                  gump.AddHtml(140, 95, 450, 250, "<basefont color=white><center>Welcome to the Central Memory Admin Gump!</center><br>With this gump, you can see a list of all entries that the CM contains.  You can add new Modules or modify or delete existing Modules.<br><br>Make your selection from the top buttons, either List Mobiles or Items.  This will bring up a list of all Mobiles or Items that the CM is keeping track of.<br><br>You may then select one of the entries to list the Modules that are stored to that entry.  You can then add, modify or remove modules to that entry.</font>", false, false);
                  return;
              }
  
              Params = subParams as CMGumpParams;
  
              switch ((int)Params.PageName)
              {
                  #region ListMobiles
                  case (int)Pages.ListMobiles:
                      gump.AddLabel(120, 95, 1153, "Listing all Mobiles:");
  
                      m_MobileList = GetMobiles();
                      if (m_MobileList == null || m_MobileList.Count == 0)
                          return;
  
                      if (Params.PageIndex < 0)
                          Params.PageIndex = 0;
  
  
                      if (Params.PageIndex > 0)
                          gump.AddButton(120, 332, 4014, 4015, 104, GumpButtonType.Reply, 0);
                      if ((Params.PageIndex + 1) * 21 <= m_MobileList.Count)
                          gump.AddButton(540, 332, 4005, 4006, 105, GumpButtonType.Reply, 0);
  
                      for (int i = Params.PageIndex * 21, r = 0, c = 0; i < m_MobileList.Count; i++)
                      {
                          if (m_MobileList[i] == null)
                              continue;
                          gump.AddButton(120 + c * 155, 125 + r * 30, 2501, 2501, 1000 + i, GumpButtonType.Reply, 0);
                          gump.AddLabel(130 + c * 155, 126 + r * 30, 1153, (m_MobileList[i].Name == null ? m_MobileList[i].Serial.ToString() : m_MobileList[i].Name));
                      }
  
                      break;
                  #endregion //ListMobiles
  
                  #region ListItems
                  case (int)Pages.ListItems:
                      gump.AddLabel(120, 95, 1153, "Listing all Items:");
  
                      m_ItemList = GetItems();
                      if (m_ItemList == null || m_ItemList.Count == 0)
                          return;
  
                      if (Params.PageIndex < 0)
                          Params.PageIndex = 0;
  
                      if (Params.PageIndex > 0)
                          gump.AddButton(120, 332, 4014, 4015, 104, GumpButtonType.Reply, 0);
                      if ((Params.PageIndex + 1) * 21 <= m_ItemList.Count)
                          gump.AddButton(540, 332, 4005, 4006, 105, GumpButtonType.Reply, 0);
  
                      for (int i = Params.PageIndex * 21, r = 0, c = 0; i < m_ItemList.Count; i++)
                      {
                          if (m_ItemList[i] == null)
                              continue;
                          gump.AddButton(120 + c * 155, 125 + r * 30, 2501, 2501, 1000 + i, GumpButtonType.Reply, 0);
                          gump.AddLabel(130 + c * 155, 126 + r * 30, 1153, (m_ItemList[i].Name == null ? m_ItemList[i].Serial.ToString() : m_ItemList[i].Name));
                      }
  
                      break;
                  #endregion //ListItems
  
                  #region ListModulesFor
                  case (int)Pages.ListModulesFor:
                      if (!m_DictionaryOfModuleLists.ContainsKey(Params.SelectedSerial))
                      {
                          gump.AddLabel(120, 95, 1153, "This entity no longer exists in the Central Memory!");
                          return;
                      }
  
                      if (m_DictionaryOfModuleLists[Params.SelectedSerial] == null || m_DictionaryOfModuleLists[Params.SelectedSerial].Count == 0)
                      {
                          gump.AddLabel(120, 95, 1153, "This entity has no Modules!");
                          Remove(Params.SelectedSerial);
                          return;
                      }
  
                      string name = "";
                      if (Params.SelectedSerial.IsMobile)
                          name = World.FindMobile(Params.SelectedSerial).Name;
                      else if (Params.SelectedSerial.IsItem)
                          name = World.FindItem(Params.SelectedSerial).Name;
  
                      if (name == null || name.Length == 0)
  
gt:                         name = Params.SelectedSerial.ToString();