context: using System;
  using System.Data;
  using System.IO;
  using System.Collections;
  using Server;
  using Server.Items;
  using Server.Network;
  using Server.Gumps;
  using Server.Targeting;
  using System.Reflection;
  using Server.Commands;
  using Server.Commands.Generic;
  using CPA = Server.CommandPropertyAttribute;
  using System.Xml;
  using Server.Spells;
  using System.Text;
  using Server.Accounting;
  
  /*
  ** XmlAdd
  ** Version 1.00
  ** updated 4/19/04
  ** ArteGordon
  **
  ** version 1.04
  ** update 8/08/04
  ** - the add button now uses targeting to place spawners rather than just putting them at the location of the placer.
  **
  ** version 1.03
  ** update 8/07/04
  **
  ** - changed the selection buttons to checkboxes, and changed their gump art for space reasons.
  ** - added the smartspawning option
  **
  ** Changelog
  ** version 1.02
  ** update 7/14/04
  ** - the duration entry was not being applied to added spawners  (Thanks to BlackNova for pointing this out).
  **
  ** version 1.02
  ** update 7/14/04
  ** - added the SkillTrigger entry
  **
  ** version 1.01
  ** update 4/22/04
  ** - added a spawn entry selection list
  ** - added named save and load defaults options
  **
  */
  
  namespace Server.Mobiles
  {
  	public class XmlSpawnerDefaults
  	{
  		public class DefaultEntry
  		{
  			public string AccountName;
  			public string PlayerName;
  			public TimeSpan MinDelay = TimeSpan.FromMinutes(5);
  			public TimeSpan MaxDelay = TimeSpan.FromMinutes(10);
  			public TimeSpan RefractMin = TimeSpan.FromMinutes(0);
  			public TimeSpan RefractMax = TimeSpan.FromMinutes(0);
  			public TimeSpan TODStart = TimeSpan.FromMinutes(0);
  			public TimeSpan TODEnd = TimeSpan.FromMinutes(0);
  			public TimeSpan Duration = TimeSpan.FromMinutes(0);
  			public TimeSpan DespawnTime = TimeSpan.FromHours(0);
  			public bool Group = false;
  			public int  Team = 0;
  			public int ProximitySound = 0x1F4;
  			public string SpeechTrigger = null;
  			public string SkillTrigger = null;
  			public int SequentialSpawn = -1;
  			public bool HomeRangeIsRelative = true;
  			public int SpawnRange = 5;
  			public int HomeRange = 5;
  			public int ProximityRange = -1;
  			public XmlSpawner.TODModeType TODMode = XmlSpawner.TODModeType.Realtime;
  			public int KillReset = 1;
  			public string SpawnerName = "Spawner";
  			public bool AllowGhostTrig = false;
  			public bool AllowNPCTrig = false;
  			public bool SpawnOnTrigger = false;
  			public bool SmartSpawning = false;
  			public bool ExternalTriggering = false;
  			public string TriggerOnCarried = null;
  			public string NoTriggerOnCarried = null;
  			public string ProximityMsg = null;
  			public double TriggerProbability = 1;
  			public string PlayerTriggerProp = null;
  			public string TriggerObjectProp = null;
  			public string DefsExt;
  			public string [] NameList;
  			public bool [] SelectionList;
  			public int    AddGumpX = 440;
  			public int    AddGumpY = 0;
  			public int    SpawnerGumpX = 0;
  			public int    SpawnerGumpY = 0;
  			public int    FindGumpX = 0;
  			public int    FindGumpY = 0;
    
  			// these are additional defaults that are not set by XmlAdd but can be used by other routines such as the custom properties gump to determine 
  			// whether properties have been changed from spawner default values
  			public string ConfigFile = null;
  			public int StackAmount = 1;
  			public string MobTriggerName = null;
  			public string MobTriggerProp = null;
  			public string RegionName = null;
  			public bool Running = true;
  			public Item SetItem = null;
  			public AccessLevel TriggerAccessLevel = AccessLevel.Player;
  			public Item TriggerObject = null;
  			public WayPoint WayPoint = null;
  			public bool ShowBounds = false;
            
  			public bool AutoNumber = false;
  			public int AutoNumberValue = 0;
              
  			public XmlAddCAGCategory CurrentCategory;
  			public int CurrentCategoryPage;
  			public int CategorySelectionIndex = -1;
  
  			public XmlSpawner LastSpawner;
  			public Map StartingMap;
  			public Point3D StartingLoc;
  			public bool ShowExtension;
  
  			public bool IgnoreUpdate;
  
  
  			public DefaultEntry()
  			{
  			}
  		}
  		public static ArrayList DefaultEntryList;
  
  		public static DefaultEntry GetDefaults(string account, string name)
  		{
  			// find the default entry corresponding to the account and username
  			if(DefaultEntryList != null)
  			{
  				for(int i = 0;i < DefaultEntryList.Count;i++)
  				{
  					DefaultEntry entry = (DefaultEntry)DefaultEntryList[i];
  					if( entry != null && string.Compare( entry.PlayerName, name, true ) == 0 && string.Compare( entry.AccountName, account, true ) == 0)
  					{
  						return entry;
  					}
  				}
  			}
  			// if not found then add one
  			DefaultEntry newentry = new DefaultEntry();
  			newentry.PlayerName = name;
  			newentry.AccountName = account;
  			if(DefaultEntryList == null)
  				DefaultEntryList = new ArrayList();
  			DefaultEntryList.Add(newentry);
  			return newentry;
  		}
          
  		public static void RestoreDefs(DefaultEntry defs)
  		{
  			if(defs == null) return;
  			defs.MinDelay = TimeSpan.FromMinutes(5);
  			defs.MaxDelay = TimeSpan.FromMinutes(10);
  			defs.RefractMin = TimeSpan.FromMinutes(0);
  			defs.RefractMax = TimeSpan.FromMinutes(0);
  			defs.TODStart = TimeSpan.FromMinutes(0);
  			defs.TODEnd = TimeSpan.FromMinutes(0);
  			defs.Duration = TimeSpan.FromMinutes(0);
  			defs.DespawnTime = TimeSpan.FromHours(0);
  			defs.Group = false;
  			defs.Team = 0;
  			defs.ProximitySound = 0x1F4;
  			defs.SpeechTrigger = null;
  			defs.SkillTrigger = null;
  			defs.SequentialSpawn = -1;
  			defs.HomeRangeIsRelative = true;
  			defs.SpawnRange = 5;
  			defs.HomeRange = 5;
  			defs.ProximityRange = -1;
  			defs.TODMode = XmlSpawner.TODModeType.Realtime;
  			defs.KillReset = 1;
  			defs.SpawnerName = "Spawner";
  			defs.AllowGhostTrig = false;
  			defs.AllowNPCTrig = false;
  			defs.SpawnOnTrigger = false;
  			defs.SmartSpawning = false;
  			defs.ExternalTriggering = false;
  			defs.TriggerOnCarried = null;
  			defs.NoTriggerOnCarried = null;
  			defs.ProximityMsg = null;
  			defs.TriggerProbability = 1;
  			defs.PlayerTriggerProp = null;
  			defs.TriggerObjectProp = null;
  			defs.DefsExt = null;
  			defs.AddGumpX = 440;
  			defs.AddGumpY = 0;
  			defs.SpawnerGumpX = 0;
  			defs.SpawnerGumpY = 0;
  			defs.FindGumpX = 0;
  			defs.FindGumpY = 0;
  			defs.AutoNumber = false;
  			defs.AutoNumberValue = 0;
            
  
  			if(defs.SelectionList != null) Array.Clear(defs.SelectionList,0,defs.SelectionList.Length);
  			if(defs.NameList != null) Array.Clear(defs.NameList,0,defs.NameList.Length);
  		}
  
  	}
      
  
  
  	public class XmlAddGump : Gump
  	{
  		private const int MaxEntries = 40;
  		private const int MaxEntriesPerColumn = 20;
  		private const string DefsDataSetName = "Defs";
  		private const string DefsTablePointName = "Values";
  		private const string DefsDir = "SpawnerDefs";
  
  		private static int StartingXoffset = 440;
  		private Mobile m_From;
  
  		public XmlSpawnerDefaults.DefaultEntry defs;
  
  
  		private string NameListToString()
  		{
  			if(defs.NameList == null || defs.NameList.Length == 0)
  				return "0";
  			System.Text.StringBuilder sb = new System.Text.StringBuilder();
  			sb.AppendFormat( "{0}", defs.NameList.Length);
  			for(int i = 0; i < defs.NameList.Length;i++)
  			{
  				sb.AppendFormat( ":{0}", defs.NameList[i] );
  			}
  			return sb.ToString();
  		}
  
  		private string SelectionListToString()
  		{
  			if(defs.SelectionList == null || defs.SelectionList.Length == 0)
  				return "0";
  
gt: 			System.Text.StringBuilder sb = new System.Text.StringBuilder();