using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectPlay;
using Microsoft.DirectX.DirectInput;
using DarkStrideToolbox;
using Direct3D=Microsoft.DirectX.Direct3D;

using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;


/*ToDo For Metal Marines
--------------------
Change grid to be single color
Make it so that bulldozing a anti-mater missle costs 40 and bulldozes the entire thing
Add checkbox onto settings for "NoDPNServer"
Upgrade graphics to 1.5/.5 system
*/

namespace MetalMarines
{
	public class MetalMarines : DSWinForm
	{
		#region Properties
		private const string m_cAILIST_SEP = "[`AI]";
		private string m_cBACKGROUNDVERTEX = "Background Vertex";
		private const double m_cGAMEOVERWAITTIME = 8;

		private System.Drawing.Color m_oBeishMMColor = System.Drawing.Color.FromArgb(151,159,95);
		private DSBouncingText m_oDSLoadingText = null;
		private DSBouncingText m_oYouWinText = null;
		private DSBouncingText m_oYouLoseText = null;
		private DarkStrideIntro m_oDSIntro = null;

		#region MainMenu Tip Stuff
		private double m_nTimeTipHasBeenUp = 0;
		private double m_nTimeTillNextTip = 10;
		private Point m_oTipLocation = Point.Empty;
		private Vector2 m_vTipSize = Vector2.Empty;
		private string m_sTipShowing = "";
		private bool m_bShowingTip = false;
		private double m_nWaterTileOffset = 0;

		public static double m_cTIPBORDER_GROWTHAMT_X		= 15;
		public static double m_cTIPBORDER_GROWTHAMT_Y		= 5;
		public static long m_cTIPBORDER_MAXWIDTH			= 250;
		public static long m_cTIPBORDER_MAXHEIGHT			= 83;

		public static long m_cTIPBORDER_GRAY_LEFTWIDTH		= 15;
		public static long m_cTIPBORDER_GRAY_RIGHTWIDTH		= 16;
		public static long m_cTIPBORDER_GRAY_TOPWIDTH		= 10;
		public static long m_cTIPBORDER_GRAY_BOTTOMWIDTH	= 9;
		#endregion
		#region Main Menu Missile Stuff
		private double m_nTimeTillNextMissileLaunch = 0;
		private System.Collections.ArrayList m_oMenuMissleAttacks = new System.Collections.ArrayList();
		private System.Collections.ArrayList m_oMenuMissleExplosions = new System.Collections.ArrayList();
		private struct structMenuMissile
		{
			public int m_nColor;
			public double m_nPercSourceX;
			public double m_nPercSourceY;
			public double m_nPercSpeedX;
			public double m_nPercSpeedY;
		}
		#endregion
		#region Menu Variables
		private DateTime m_dtTimeSinceLastVolumeChangeClick = DateTime.MinValue;

		private DSForm m_oMenuSwitch_CurMenu = null;
		private DSForm m_oMenuSwitch_NewMenu = null;
		private bool m_bMenuSwitch_ShiftDown = true;
		private double m_nMenuSwitch_ElapsedTime = 0;

		private const string m_cMENU_MAIN				= "frmMainMenu";
		private const string m_cMENU_NETUSERSELECT		= "frmUserSelection";
		private const string m_cMENU_NETSRVPROVSELECT	= "frmNetServiceProviderSelectForm";
		private const string m_cMENU_NETHOSTCLIENT		= "frmNetHostClientForm";
		private const string m_cMENU_WAITINGTOCONNECT	= "frmWaitingToConnect";
		private const string m_cMENU_NETGAMEHOST		= "frmNetHostGameHostForm";
		private const string m_cMENU_NETLOBBY			= "frmChatLobby";
		private const string m_cMENU_RESUMEMENU			= "frmResume";
		private const string m_cMENU_OPTIONSMENU		= "frmOptions";
		private const string m_cMENU_INGAMETYPING		= "frmInGameTyping";
		private const string m_cMENU_MAPEDITORMAINMENU	= "frmMapEditor_Main";
		private const string m_cMENU_MAPEDITORPROPERTIES= "frmMapEditor_Properties";
		#endregion

		//These are the loading paramaters for the GOB files
		private Thread m_oLoadingThread = null;
		private bool m_bMenuGOBIsLoaded = false;
		private bool m_bGameGOBIsLoaded = false;
		private bool m_bStartMultipalyerGameOnceGOBIsLoaded = false;

		private bool m_bReceivedGameStart = false;

		//Track our groups
		private DSSortedList m_oSelectedSquares = new DSSortedList();
		private DSSortedList m_oGroupsOfSelectedSquares = new DSSortedList();

		//Windows placement storage
		//private Vector2 m_vConsolePos = new Vector2( 0,0 );
		private Vector2 m_vPurchasePos = new Vector2( 0,0 );
		private Vector2 m_vChatPos = new Vector2( 0,0 );
		private Vector2 m_vWindowPos_Mine = new Vector2( 0,0 );
		private Vector2 m_vWindowSize_Mine = new Vector2( 0,0 );
		private ArrayList m_oWindowPos = new ArrayList();
		private ArrayList m_oWindowSize = new ArrayList();

		//Map editing properties
		private long m_nNextUniqueID = 0;

		private DSGobFile m_oGameGobFile = null;
		private DSGobFile m_oMenuGobFile = null;
		private ServiceProviderInformation m_oServiceProviderForNetGame;
		private const int m_cPORT = 2502;

		private string m_sUserName = "";
		private string m_sIP = "";
		private string m_sGameName = "";
		private string m_sLastMultiMapUsed = "";
		private string m_sServiceProviderGUID = "";
		private string m_sUserFrameStats = "";
		private bool m_bDebugMode = false;
		
		private Guid m_oAppGUID = new Guid(0x876a3036, 0xffd7, 0x46bc, 0x92, 0x8, 0xb4, 0x2f, 0x61, 0x7b, 0x9b, 0xeA);

		private const string m_cMMSAVEDGAMEHEADER		= "MetalMarine Saved Game v1.0";

		private bool m_bHaveInitedMenuNetwork = false;
		private bool m_bLaunchedOptionsMenuFromMainMenu = false;

		/*private enum enumNetMessages
		{
			StartGame = 1,
			Paused = 2,
			GameUpdate = 3,
			PaddleUpdate = 4,
			GameOver = 5
		};*/

		private DSGameEngine m_oGameEngine = null;
		private enumStates m_nGameState = enumStates.WaitingToLoadMenuGOB;

		private bool m_bSinglePlayerMode = false;
		private int m_nSinglePlayerLevelToStartAtOnceGOBIsLoaded = 1;
		private Game m_oGame = null;
		private string m_sMyIslandsGlobalID = "";
		private Island m_oGiveResSelectedIsland = null;
		private double m_nFadeAmount = .7;

		//A windows list of components.  Auto-added by project.
		private System.ComponentModel.Container components = null;

		private DSSortedList m_oPreGamePlayerStatus = new DSSortedList();
		private DSSortedList m_oAIsToAdd = new DSSortedList();
		#endregion


		#region System Functions You Shoulden't Touch
		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MetalMarines));
			// 
			// MetalMarines
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(632, 453);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Name = "MetalMarines";
			this.Text = "MetalMarines";

		}
		#endregion

		[STAThread]
		static void Main() 
		{
			const string sRoutineName = "MetalMarines.frmMain.Main";	

			try
			{
				using( MetalMarines oApp = new MetalMarines() )
				{                
					oApp.DSGameEngine = new DSGameEngine( oApp,DarkStrideToolbox.RenderMode.TwoD,false );
					oApp.DSGameEngine.OneTimeSceneInitialization += new EventHandler( oApp.OneTimeSceneInitialization );
					oApp.DSGameEngine.SetDeviceStates += new EventHandler( oApp.SetDeviceStates );
					oApp.DSGameEngine.Run();
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( new System.Exception( sRoutineName + " Failed.",oEx ) );
			}
		}
		//This is the constructor of our class... so the entry point of the app (main) creates our class which calls the
		//constructor.  Then the entry point (main) starts the app by calling run.
		public MetalMarines()
		{
			//Required for Windows Form Designer support
			InitializeComponent();
		}
 
		//Erase our controls.  Disposing happens after we exit main, so if your going to error handle it you have to
		//show your errors on your own.
		protected override void Dispose( bool disposing )
		{
			const string sRoutineName = "MetalMarines.frmMain.Dispose";	

			try
			{
				if( disposing )
				{
					if (components != null) 
					{
						components.Dispose();
					}
				}
				base.Dispose( disposing );
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( new System.Exception( sRoutineName + " Failed.",oEx ) );
			}
		}

		#endregion

		#region Game Functions
		public bool ProcessCheatCode( string sMessage,bool bFromNetwork,out string sCheatMessage )
		{
			bool bIsCheat = false;
			sCheatMessage = "";


			if( sMessage == "+Nanites" )
			{
				bIsCheat = true;
				m_oGame.Debug_InstantBuild = ( !m_oGame.Debug_InstantBuild );
				sCheatMessage = "Instant build cheat " + BoolToActivated( m_oGame.Debug_InstantBuild ) + ".";
			}
			else if( sMessage == "+Grid" && bFromNetwork == false )
			{
				bIsCheat = true;
				m_oGame.Debug_RenderGrid = ( !m_oGame.Debug_RenderGrid );
				sCheatMessage = "Grid rendering cheat " + BoolToActivated( m_oGame.Debug_RenderGrid ) + ".";
			}
			else if( sMessage == "+Peace Keepers" )
			{
				bIsCheat = true;
				m_oGame.Debug_MMNeverReturnHome = ( !m_oGame.Debug_MMNeverReturnHome );
				sCheatMessage = "Metal Marines never return home cheat " + BoolToActivated( m_oGame.Debug_MMNeverReturnHome ) + ".";
			}
			else if( sMessage == "+There can be only one" )
			{
				bIsCheat = true;
				m_oGame.Debug_AutoWinForOnePlayer = ( !m_oGame.Debug_AutoWinForOnePlayer );
				sCheatMessage = "Auto win for one player cheat " + BoolToActivated( m_oGame.Debug_AutoWinForOnePlayer ) + ".";
			}
			else if( sMessage == "+Masochist" )
			{
				bIsCheat = true;
				m_oGame.Debug_CanAttackOurselves = ( !m_oGame.Debug_CanAttackOurselves );
				sCheatMessage = "Can attack yourself cheat " + BoolToActivated( m_oGame.Debug_CanAttackOurselves ) + ".";
			}
			else if( sMessage == "+EagleEye" )
			{
				bIsCheat = true;
				m_oGame.Debug_AllowZoom = ( !m_oGame.Debug_AllowZoom );
				sCheatMessage = "Allow zoom cheat " + BoolToActivated( m_oGame.Debug_AllowZoom ) + ".";
			}
			else if( sMessage == "+Pot-o-gold" )
			{
				bIsCheat = true;
				sCheatMessage = "Resource cheat activated.";
				for( int i=0 ; i<m_oGame.Islands.Count ; i++ )
				{
					((Island)m_oGame.Islands.GetByIndex( i )).Credits += 10000;
					((Island)m_oGame.Islands.GetByIndex( i )).Fuel += 10000;
				}
			}
			else if( sMessage == "+FPS" && bFromNetwork == false )
			{
				bIsCheat = true;
				m_oGame.Debug_FPS = ( !m_oGame.Debug_FPS );
				sCheatMessage = "Show stats " + BoolToActivated( m_oGame.Debug_AllowZoom ) + ".";
			}
			else if( sMessage == "+EyesOfTheWorld" )
			{
				bIsCheat = true;
				m_oGame.Debug_FullVision = ( !m_oGame.Debug_FullVision );
				sCheatMessage = "Full Vision " + BoolToActivated( m_oGame.Debug_AllowZoom ) + ".";
			}

			return( bIsCheat );
		}
		private string BoolToActivated( bool bValue )
		{
			if( bValue == true )
			{
				return( "activated" );
			}
			else
			{
				return( "deactivated" );
			}
		}
		//The Device has been created.  Resources that are not lost on Reset() can be created here -- resources in Pool.Managed,
		//Pool.Scratch, or Pool.SystemMemory.  Image surfaces created via CreateImageSurface are never lost and can be created here.  Vertex
		//shaders and pixel shaders can also be created here as they are not lost on Reset().
		public void OneTimeSceneInitialization(object sender, System.EventArgs e)
		{
			//DSMesh oLoadingMesh = null;
			const string sRoutineName = "MetalMarines.frmMain.OneTimeSceneInitialization";
			DSGobFile oGobFile = null;

			try
			{
				//Register our callback functions so we know when the engine wants us to do things... consider 
				//deligates/callbacks to be equivilant to VB events.
				m_oGameEngine.Render2DBeforeForms += new EventHandler( this.Render2DBeforeForms );
				m_oGameEngine.Render2DAfterForms += new EventHandler( this.Render2DAfterForms );
				m_oGameEngine.Render3D += new EventHandler( this.Render3D );
				m_oGameEngine.FrameMove += new EventHandler( this.Advance );
				this.Resize += new EventHandler( this.MetalMarines_Resize );

				m_oGameEngine.DirectInput.RegisterDelegate_MouseMoved( new DSInputWrapper.CallbackMouseMoved( this.DIMouseMoved ) );
				m_oGameEngine.DirectInput.RegisterDelegate_MouseUp( new DSInputWrapper.CallbackMouseUp( this.DIMouseUp ) );
				m_oGameEngine.DirectInput.RegisterDelegate_KeyboardKeyDown( new DSInputWrapper.CallbackKeyboardKeyDown( this.DIKeyboardKeyDown ) );
				m_oGameEngine.DirectInput.RegisterDelegate_KeyboardKeyUp( new DSInputWrapper.CallbackKeyboardKeyUp( this.DIKeyboardKeyUp ) );

				m_oGameEngine.MouseInExclusiveMode = false;
				//m_oGameEngine.ShowMouseCursor = false;

				//Initialize the network connections
				m_oGameEngine.DirectPlay.RegisterDelegate_DataReceived( new DSNetworkWrapper.CallbackDataReceived( this.DataReceived ) );
				m_oGameEngine.DirectPlay.RegisterDelegate_PlayerJoined( new DSNetworkWrapper.CallbackPlayerJoined( this.PlayerJoined ) );
				m_oGameEngine.DirectPlay.RegisterDelegate_PlayerQuit( new DSNetworkWrapper.CallbackPlayerQuit( this.PlayerQuit ) );
				m_oGameEngine.DirectPlay.RegisterDelegate_GameListUpdate( new DSNetworkWrapper.CallbackGameListUpdate( this.GameListUpdate ) );
				m_oGameEngine.DirectPlay.RegisterDelegate_Connection( new DSNetworkWrapper.CallbackConnection( this.Connection ) );

				//Create the background vertex
				float n = 1.5f;
				float nBack = 5;
				DSResourceManager.GetGlobalInstance().CreateVertexBuffer( m_cBACKGROUNDVERTEX,
								new Vector3(-n,-n,nBack),new Vector3( -n,n,nBack),
								new Vector3(n,-n,nBack),new Vector3(n,n,nBack) );

				//Load the DS Intro
				m_oDSLoadingText	= new DSBouncingText( m_oGameEngine,m_oBeishMMColor,"Loading..." );
				m_oYouWinText		= new DSBouncingText( m_oGameEngine,m_oBeishMMColor,"You are victorious!" );
				m_oYouLoseText		= new DSBouncingText( m_oGameEngine,m_oBeishMMColor,"You have failed!" );
				m_oDSIntro			= new DarkStrideIntro( m_oGameEngine );

				//Load in the intro thread stuff
				m_nGameState = enumStates.SplashScreen;
				oGobFile = new DSGobFile();
				oGobFile.LoadGobFile( DSMisc.GetDevelopmentAppPath() + @"DSIntro.gob" );

				//Start the loading thread
				m_oGameEngine.MaxFPS = 40;
				m_oLoadingThread = new Thread( new ThreadStart( this.LoadingIntroGOBThread ) );
				m_oLoadingThread.Priority = System.Threading.ThreadPriority.Lowest;
				m_oLoadingThread.IsBackground = true;
				m_oLoadingThread.Start();


				//Get our graphics
				/*m_oGameGobFile = new DSGobFile();
				m_oGameGobFile.LoadGobFile( DSMisc.GetDevelopmentAppPath() + @"MetalMarines.gob" );
				//Load in our menus
				m_oGameEngine.Forms.LoadFromStream( m_oGameGobFile.GetTable( Game.m_cGOB_FORMS_TABLE ).File );
				InitMenuEvents();

				//Open up the INI file and load in our settings
				LoadINIFile();

				StartMainForm( false );*/
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( new System.Exception( sRoutineName + " Failed.",oEx ) );
			}
		}
		private void LoadingIntroGOBThread()
		{
			//Get our graphics
			m_oMenuGobFile = new DSGobFile();
			m_oMenuGobFile.LoadGobFile( DSMisc.GetDevelopmentAppPath() + @"Menus.gob" );
			//Load in our menus
			m_oGameEngine.Forms.LoadFromStream( m_oMenuGobFile.GetTable( Game.m_cGOB_FORMS_TABLE ).File );
			InitMenuEvents();

			//Open up the INI file and load in our settings
			LoadINIFile();

			//StartMainForm( false );

			m_bMenuGOBIsLoaded = true;
		}
		private void LoadingMainGOBThread()
		{
			//Get our graphics
			m_oGameGobFile = new DSGobFile();
			m_oGameGobFile.LoadGobFile( DSMisc.GetDevelopmentAppPath() + @"MetalMarines.gob" );

			m_bGameGOBIsLoaded = true;
		}
		public void SetDeviceStates(object sender, System.EventArgs e)
		{
			// Create a light
			Vector3 lightDirection = new Vector3(10,-10,10);
			m_oGameEngine.Direct3DDevice.Lights[0].Type = LightType.Directional;
			m_oGameEngine.Direct3DDevice.Lights[0].DiffuseColor = new ColorValue(1.0f,1.0f,1.0f,1.0f);
			m_oGameEngine.Direct3DDevice.Lights[0].Direction = Vector3.Normalize(lightDirection);
			m_oGameEngine.Direct3DDevice.Lights[0].Enabled = true;

			//Some basic render states
			m_oGameEngine.Direct3DDevice.RenderState.ZBufferEnable = true;
			m_oGameEngine.Direct3DDevice.RenderState.DitherEnable = true;
			m_oGameEngine.Direct3DDevice.RenderState.SpecularEnable = true;
			m_oGameEngine.Direct3DDevice.RenderState.Lighting = true;
			m_oGameEngine.Direct3DDevice.RenderState.AmbientColor = unchecked((int)0x80808080);

			// Restore the states
			m_oGameEngine.Direct3DDevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
			m_oGameEngine.Direct3DDevice.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
			m_oGameEngine.Direct3DDevice.TextureState[0].ColorOperation = TextureOperation.Modulate;
			m_oGameEngine.Direct3DDevice.SamplerState[0].MinFilter = TextureFilter.Linear;
			m_oGameEngine.Direct3DDevice.SamplerState[0].MagFilter = TextureFilter.Linear;
		}

		private void MetalMarines_Resize(object sender, System.EventArgs e)
		{
			DSForm oLoopForm = null;


			for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
			{
				oLoopForm = (DSForm)m_oGameEngine.Forms.GetForm( i );

				if( m_nGameState == enumStates.InGame )
				{
					//Go through all our forms and make sure they are on screen
					MakeSureWindowIsOnScreen( oLoopForm );
				}
				else if( oLoopForm.Visible == true )
				{
					//Go through all our forms and center them
					CenterWindow( oLoopForm );
				}				
			}
		}


		public void CreateGameObject()
		{
			m_oGame = new Game();

			Game.App = this;
			Game.GobFile = m_oGameGobFile;
			Game.GameEngine = m_oGameEngine;

			if( m_bDebugMode == true )
			{
				m_oGame.Debug_AllowZoom = true;
				m_oGame.Debug_AutoWinForOnePlayer = false;
				m_oGame.Debug_CanAttackOurselves = true;
				m_oGame.Debug_InstantBuild = true;
				m_oGame.Debug_MMNeverReturnHome = false;
				m_oGame.Debug_RenderGrid = false;
				m_oGame.Debug_FPS = true;
				m_oGame.Debug_FullVision = false;
			}
		}


		private void Advance(object sender, System.EventArgs e)
		{
			const string sRoutineName = "MetalMarines.frmMain.Advance";	
			LoadedTexture oLoadedTexture = null;
			MMIslandForm oIslandForm = null;
			DSForm oLoopForm = null;


			int nFontHeight = 0;
			Microsoft.DirectX.Direct3D.Font oNewFont = null;
			nFontHeight = m_oGameEngine.GetFontSize( 10 );
			oNewFont = new Microsoft.DirectX.Direct3D.Font( m_oGameEngine.Direct3DDevice, 
				nFontHeight, 0, FontWeight.Bold, 1, false, CharacterSet.Default, 
				Precision.Default, FontQuality.Default, 
				PitchAndFamily.DefaultPitch | PitchAndFamily.FamilyDoNotCare, 
				"Arial" );
			DSResourceManager.GetGlobalInstance().AddFont( "p",oNewFont );


			try
			{
				m_oDSLoadingText.Advance( ((DSGameEngineArgs)e).ElapsedTime );
				m_oYouWinText.Advance( ((DSGameEngineArgs)e).ElapsedTime/2 );
				m_oYouLoseText.Advance( ((DSGameEngineArgs)e).ElapsedTime/2 );

				Advance_SwitchMenus( ((DSGameEngineArgs)e).ElapsedTime );

				if( m_nGameState == enumStates.SplashScreen )
				{
					m_oDSIntro.Advance( ((DSGameEngineArgs)e).ElapsedTime );

					if( m_oDSIntro.DoneWithIntro == true )
					{
						m_nGameState = enumStates.WaitingToLoadMenuGOB;
					}
				}
				else if( m_nGameState == enumStates.WaitingToLoadMenuGOB && m_bMenuGOBIsLoaded == true )
				{
					//Start our secondary load sequence
					m_oLoadingThread = new Thread( new ThreadStart( this.LoadingMainGOBThread ) );
					m_oLoadingThread.Priority = System.Threading.ThreadPriority.Lowest;
					m_oLoadingThread.IsBackground = true;
					m_oLoadingThread.Start();

					m_nGameState = enumStates.MainMenu;
					StartMainForm( false );
					m_oGameEngine.Forms.Show( m_cMENU_MAIN );
				}
				else if( m_nGameState == enumStates.MainMenu && m_oLoadingThread != null && m_bGameGOBIsLoaded == true )
				{
					m_oGameEngine.MaxFPS = 0;
					m_oLoadingThread = null;

					if( m_oGameEngine.DirectPlay.Me != null )
					{
						SendMMMsg( enumNetMsg.ReadyToStartRequest,
							m_oGameEngine.DirectPlay.Me.SocketID.ToString(),
							m_bGameGOBIsLoaded.ToString() );
					}
					if( m_bStartMultipalyerGameOnceGOBIsLoaded == true )
					{
						StartGame_ClientAndHost();
					}
				}
				else if( m_nGameState == enumStates.MapEditor || 
						( 
							( m_nGameState == enumStates.InGame || m_nGameState == enumStates.ResumeMenu ) &&
							m_oGame.GameIsOver() == false 
						)
					   )
				{
					if( m_nGameState == enumStates.MapEditor )
					{
						m_oGame.UseBuildingRot = false;

						//Advance all the islands we have that we are editing
						for( int nFormIndex=0 ; nFormIndex<m_oGameEngine.Forms.FormsInZOrder.Length ; nFormIndex++ )
						{
							oLoopForm = m_oGameEngine.Forms.FormsInZOrder[ nFormIndex ];

							if( oLoopForm != null &&
								oLoopForm.Name.Length > Game.m_cEDITISLANDFORMNAME.Length &&
								oLoopForm.Name.Substring( 0,Game.m_cEDITISLANDFORMNAME.Length ) == Game.m_cEDITISLANDFORMNAME )
							{
								oIslandForm = (MMIslandForm)oLoopForm;
								oIslandForm.Island.Advance( .01 ); 
							}
						}
					}				

					if( m_nGameState != enumStates.ResumeMenu || m_bSinglePlayerMode == false )
					{
						m_oGame.Advance( ((DSGameEngineArgs)e).ElapsedTime );
					}
				}
				else if( m_nGameState == enumStates.LoadingGOBForMapEditor &&
					m_bGameGOBIsLoaded == true )
				{
					m_oGameEngine.MaxFPS = 0;
					m_oLoadingThread = null;

					m_nGameState = enumStates.MapEditor;
					StartMapEditorForm( false );
				}
				else if( m_nGameState == enumStates.LoadingGOBForGame &&
					     m_bGameGOBIsLoaded == true )
				{
					m_oGameEngine.MaxFPS = 0;
					m_oLoadingThread = null;

					m_nGameState = enumStates.InGame;
					StartSinglePlayerGame( m_nSinglePlayerLevelToStartAtOnceGOBIsLoaded );
				}
				else if( m_nGameState == enumStates.MainMenu )
				{
					AdvanceMenuTips( ((DSGameEngineArgs)e).ElapsedTime );
					AdvanceMenuMissiles( ((DSGameEngineArgs)e).ElapsedTime );
					
					//Advance the water slide
					oLoadedTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_BACKGROUND_WATERTILE_TABLE );
					m_nWaterTileOffset += ((DSGameEngineArgs)e).ElapsedTime * 5;
					if( m_nWaterTileOffset > oLoadedTexture.Size.X )
					{
						m_nWaterTileOffset -= oLoadedTexture.Size.X;
					}
				}

				if( m_nGameState != enumStates.InGame )
				{					
					//Fade out the main menu
					if( m_nFadeAmount > .2 )
					{
						m_nFadeAmount -= .01;
					}
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( new System.Exception( sRoutineName + " Failed.",oEx ) );
			}
		}
		private void Render2DBeforeForms(object sender, System.EventArgs e)
		{
			System.Drawing.Rectangle oBackground;
			LoadedTexture oLoadedTexture = null;


			oBackground = new System.Drawing.Rectangle( 0,0,
						m_oGameEngine.ScreenWidth,m_oGameEngine.ScreenHeight );

			if( m_nGameState == enumStates.ResumeMenu ||
				(
					m_nGameState == enumStates.InGame &&
					m_bGameGOBIsLoaded == true
				)
			  )
			{
//				m_oGameEngine.Tile( oBackground,Game.m_cGOB_BACKGROUND_BLUECIRCUIT_TABLE );
			}
			else if( m_nGameState == enumStates.MainMenu )
			{
				oLoadedTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_BACKGROUND_WATERTILE_TABLE );
				oBackground.Width += (int)oLoadedTexture.Size.X;
				oBackground.Height += (int)oLoadedTexture.Size.Y;
				oBackground.X -= (int)m_nWaterTileOffset;
				oBackground.Y -= (int)m_nWaterTileOffset;
				m_oGameEngine.Tile( oBackground,Game.m_cGOB_BACKGROUND_WATERTILE_TABLE );

				RenderTextWithShadow( "Copyright DarkStride Software 2007\nby Warstrider\nv" + Application.ProductVersion,
									  m_oGameEngine.ScreenWidth - 180,m_oGameEngine.ScreenHeight - 50,
									  System.Drawing.Color.White,System.Drawing.Color.Black );

				Render2DBeforeForms_MenuMissiles();
				Render2DBeforeForms_MenuTip();
			}
		}
		private void Render2DAfterForms(object sender, System.EventArgs e)
		{
			MMIslandForm oMyIslandForm = null;
			DSForm oForm = null;
			DSNetworkPlayer oNetPlayer = null;
			long nGobBuildingToPlaceKey = -1;
			long nTerrainIndex = -1;
			System.Drawing.Rectangle oSrcRect = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oTrgRect = System.Drawing.Rectangle.Empty;
			TimeSpan oDiff;			
			string sTemp = "";
			//string sVictoryText = "";
			string sGraphicKey = "";


			try
			{
				if( m_nGameState == enumStates.WaitingToLoadMenuGOB )
				{
				}
				else if( m_nGameState == enumStates.SplashScreen )
				{
					m_oDSIntro.Render2DAfterForms();
				}
				else if( m_nGameState == enumStates.ResumeMenu ||
						(
							m_nGameState == enumStates.InGame &&
							m_bGameGOBIsLoaded == true
						)
					   )
				{

					//Check to see if their was a victory
					if( m_oGame.GameIsOver() == true )
					{
						//Is our 15 seconds over?
						oDiff = DateTime.Now - m_oGame.GameEndTime;
						if( oDiff.Seconds > m_cGAMEOVERWAITTIME )
						{
							//Now remove all the island forms
							for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
							{
								oForm = (DSForm)m_oGameEngine.Forms.GetForm( i );
								if( oForm != null && oForm.GetType() == typeof( MMIslandForm ) )
								{
									m_oGameEngine.Forms.Remove( oForm.Name );
								}
							}

							//If this is single player mode start the next game
							if( m_bSinglePlayerMode == true )
							{
								StartSinglePlayerGame( m_oGame.CurrentSinglePlayerLevelID + 1 );
							}
								//Oop... its multi-player.  Back to the lobby.
							else
							{
								m_nGameState = enumStates.MainMenu;
								/*//Hide all the islands
								for( int nFormIndex=0 ; nFormIndex<m_oGameEngine.Forms.Count ; nFormIndex++ )
								{
									//Get the form and hide it
									oForm = (DSForm)m_oGameEngine.Forms.GetForm( nFormIndex );
									oForm.Visible = false;
								}*/

								//Now make our chat room visible again
								m_oGame = null;
								//StartLobbyForm( false );
								SwitchMenus( "",m_cMENU_NETLOBBY,false );
							}
						}
							//Show them its over
						else
						{
							HideAllInGameMenus();
						}
					}
					else
					{
						m_oGame.Render2DAfterForms();	

						oMyIslandForm = GetMyIsland();

						//Render our main menu
						RenderMainMenu();
						//Render the things were dragging
						//If we are dragging something and is it not over our target?  In that case
						//draw it beneath our cursor.
						if( oMyIslandForm.BuildingIsBeingDragged( ref nGobBuildingToPlaceKey ) == true &&
							oMyIslandForm.GetWindowRenderArea().Contains( (int)m_oGameEngine.MouseCursor.X,
							(int)m_oGameEngine.MouseCursor.Y ) == false )
						{
							oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nGobBuildingToPlaceKey,0,ref sGraphicKey );
							oTrgRect = oMyIslandForm.GetScrBuildingPosFromSquare( 0,0 );
							oTrgRect.X = (int)m_oGameEngine.MouseCursor.X;
							oTrgRect.Y = (int)m_oGameEngine.MouseCursor.Y;

							//Now draw the base were dragging by the mouse cursor
							m_oGameEngine.RenderTexture2D( sGraphicKey, oSrcRect, 
								oTrgRect, new Vector2( 0,0 ), 0, 0, false, 
								System.Drawing.Color.White.ToArgb() );
						}
					}
				}
				else if( m_nGameState == enumStates.MapEditor )
				{
					if( MMPurchaseForm.IsDragingPurchase( m_oGameEngine.Forms ) == true )
					{ 
						nGobBuildingToPlaceKey = MMPurchaseForm.GetDragingPurchase( m_oGameEngine.Forms );

						if( nGobBuildingToPlaceKey != -1 )
						{
							oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nGobBuildingToPlaceKey,0,ref sGraphicKey );
							oTrgRect = new Rectangle( 0,0,0,0 );
							oTrgRect.X = (int)m_oGameEngine.MouseCursor.X;
							oTrgRect.Y = (int)m_oGameEngine.MouseCursor.Y;

							//Now draw the base were dragging by the mouse cursor
							m_oGameEngine.RenderTexture2D( sGraphicKey, oSrcRect, 
								oTrgRect, new Vector2( 0,0 ), 0, 0, false, 
								System.Drawing.Color.White.ToArgb() );
						}
					}
					else if( MMPlaceTerrainForm.IsDragingTerrain( m_oGameEngine.Forms ) == true )
					{
						nTerrainIndex = MMPlaceTerrainForm.GetDragingTerrain( m_oGameEngine.Forms );

						oSrcRect = Game.GetSrcRectForTerrainType( (int)nTerrainIndex,ref sGraphicKey );
						oTrgRect = new Rectangle( 0,0,0,0 );
						oTrgRect.X = (int)m_oGameEngine.MouseCursor.X;
						oTrgRect.Y = (int)m_oGameEngine.MouseCursor.Y;

						m_oGameEngine.RenderTexture2D( sGraphicKey, oSrcRect, oTrgRect, 
							new Vector2( 0,0 ), 0, 0, false,
							System.Drawing.Color.White.ToArgb() );
					}
				}

				//Show some stats
				if( m_oGame != null && m_oGame.Debug_FPS )
				{
					sTemp = m_sUserFrameStats;
					lock( m_oGameEngine.DirectPlay.Players )
					{
						sTemp += "\n\nNetwork Stats:";
						for( int nNetPlayerIndex=0 ; nNetPlayerIndex<m_oGameEngine.DirectPlay.Players.Count ; nNetPlayerIndex++ )
						{
							oNetPlayer = (DSNetworkPlayer)m_oGameEngine.DirectPlay.Players.GetByIndex( nNetPlayerIndex );
							sTemp += "\n     " + oNetPlayer.Name + ": " + (oNetPlayer.LastPingInSeconds*1000).ToString( "f3" ) + "ms";
						}
					}

					m_oGameEngine.UserFrameStats = sTemp;
					m_oGameEngine.RenderText( 20,200,System.Drawing.Color.White,m_oGameEngine.FrameStats  );
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}
		}
		private void Render3D(object sender, System.EventArgs e)
		{
			TimeSpan oDiff = TimeSpan.MinValue;
			Vector3 eyeLocation = new Vector3(0.0f,0*-5.0f,-20.0f);
			Vector3 lookAtPoint = new Vector3(0.2f*0, 0.0f,  0.0f);
			Matrix oRotate = Matrix.RotationY( (float)m_oGameEngine.AppTime*2 );


			if( m_nGameState == enumStates.SplashScreen && m_oDSIntro.DoneWithIntro == false )
			{
				m_oDSIntro.Render3D();
			}
			else if( m_nGameState == enumStates.WaitingToLoadMenuGOB ||
					 m_nGameState == enumStates.LoadingGOBForMapEditor ||
					 m_nGameState == enumStates.LoadingGOBForGame ||
					 (
						m_nGameState == enumStates.InGame &&
						m_bGameGOBIsLoaded == false 
					 )
				   )
			{
				m_oDSLoadingText.Render3D();
			}
				//Check to see if their was a victory
			else if( m_nGameState == enumStates.InGame && m_bGameGOBIsLoaded == true &&
					 m_oGame.GameIsOver() == true )
			{
				//Is our 15 seconds over?
				oDiff = DateTime.Now - m_oGame.GameEndTime;
				if( oDiff.Seconds > m_cGAMEOVERWAITTIME ){}
				//Show them its over
				else if( GetMyIsland().Island.ImDead == true )
				{
					m_oYouLoseText.Render3D();
				}
				else
				{
					m_oYouWinText.Render3D();
				}
			}

			//This must be done after the victory text for some reason
			if( m_nGameState == enumStates.ResumeMenu ||
				(
					m_nGameState == enumStates.InGame &&
					m_bGameGOBIsLoaded == true
				)
			  )
			{
				RenderBlueCircuts();
			}
		}
		public void RenderBlueCircuts()
		{
			int nMax = 12;
			Vector3 eyeLocation = new Vector3(0.0f,0*-5.0f,-20.0f);
			Vector3 lookAtPoint = new Vector3(0.2f*0, 0.0f,  0.0f);


			m_oGameEngine.Set3DCameraTransformView( eyeLocation,lookAtPoint,new Vector3(0,1,0 ) );
			m_oGameEngine.Direct3DDevice.Transform.Projection = Matrix.PerspectiveFovLH(.78f, 1, 1, 1000);

			for( int nX=-nMax ; nX<nMax ; nX+=3 )
			{
				for( int nY=-nMax ; nY<nMax ; nY+=3 )
				{
					m_oGameEngine.RenderVertexBuffer( m_cBACKGROUNDVERTEX,Game.m_cGOB_BACKGROUND_BLUECIRCUIT_TABLE,
													  Matrix.Translation( nX,nY,0 ) );
				}
			}
		}
		public void RenderMainMenu()
		{
			LoadedTexture oLoadedTexture = null;
			System.Drawing.Rectangle oTrgRect = System.Drawing.Rectangle.Empty;
			MMIslandForm oMyIslandForm = null;
			MMTeamForm oTeamForm = null;
			bool bMouseDown = false;
			bool bTeamWindowIsOpen = false;
			int nColor = 0;


			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBORDER_UPPERLEFT_TABLE,System.Drawing.Rectangle.Empty,
										  new System.Drawing.Rectangle( 0,0,0,0 ),new Microsoft.DirectX.Vector2( 0,0 ),
										  0,0,false,System.Drawing.Color.White.ToArgb() );

			oLoadedTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_MENUBORDER_LOWERLEFT_TABLE );
			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBORDER_LOWERLEFT_TABLE,System.Drawing.Rectangle.Empty,
										  new System.Drawing.Rectangle( 0,(int)( m_oGameEngine.ScreenHeight - oLoadedTexture.Size.Y ),0,0 ),
										  new Microsoft.DirectX.Vector2( 0,0 ),
										  0,0,false,System.Drawing.Color.White.ToArgb() );

			oLoadedTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_MENUBORDER_UPPERRIGHT_TABLE );
			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBORDER_UPPERRIGHT_TABLE,System.Drawing.Rectangle.Empty,
										  new System.Drawing.Rectangle(	(int)( m_oGameEngine.ScreenWidth - oLoadedTexture.Size.X ),0,0,0 ),
										  new Microsoft.DirectX.Vector2( 0,0 ),
										  0,0,false,System.Drawing.Color.White.ToArgb() );


			oMyIslandForm = GetMyIsland();


			//Draw our money and Fuel
			this.DSGameEngine.RenderText( m_oGameEngine.ScreenWidth - 104,13,
										  System.Drawing.Color.Black,
										  "Fuel: " + ((long)oMyIslandForm.Island.Fuel).ToString() + 
										  " (+" + ((long)oMyIslandForm.Island.FuelIncomePerSecond).ToString() + ")" );
			this.DSGameEngine.RenderText( m_oGameEngine.ScreenWidth - 104,39,
										  System.Drawing.Color.Black,
										  "Credits: " + ((long)oMyIslandForm.Island.Credits).ToString() + 
										  " (+" + ((long)oMyIslandForm.Island.CreditIncomePerSecond).ToString() + ")" );
			this.DSGameEngine.RenderText( m_oGameEngine.ScreenWidth - 104,65,
										  System.Drawing.Color.Black,
										  "Bases: " + oMyIslandForm.Island.BasesLeft.ToString() );


			//Is the team form open?
			oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
			if( oTeamForm != null )
			{
				bTeamWindowIsOpen = ( oTeamForm.Visible == true );
			}

			//Draw the buttons
			oTrgRect = new System.Drawing.Rectangle( 94,3,30,30 );
			bMouseDown = ( 
							(
								oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) &&
								this.DSGameEngine.MouseButtonState[ 0 ] == true 
							)
							||
							m_bSinglePlayerMode == true
						 );
			nColor = System.Drawing.Color.White.ToArgb();
			if( oMyIslandForm.Island.TeamChanged == true && DateTime.Now.Second % 2 == 0 &&
				bTeamWindowIsOpen == false )
			{
				nColor = System.Drawing.Color.Salmon.ToArgb();
			}
			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBUTTONS_TABLE,
												Game.GetSrcRectForMenuButton( 0,bMouseDown ),
												oTrgRect,new Microsoft.DirectX.Vector2( 0,0 ),
												0,0,false,nColor );

			oTrgRect = new System.Drawing.Rectangle( 44,5,30,30 );
			bMouseDown = ( oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) &&
						   this.DSGameEngine.MouseButtonState[ 0 ] == true );
			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBUTTONS_TABLE,
												Game.GetSrcRectForMenuButton( 1,bMouseDown ),
												oTrgRect,new Microsoft.DirectX.Vector2( 0,0 ),
												0,0,false,System.Drawing.Color.White.ToArgb() );

			oTrgRect = new System.Drawing.Rectangle( 3,27,30,30 );
			bMouseDown = ( oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) &&
						   this.DSGameEngine.MouseButtonState[ 0 ] == true );
			this.DSGameEngine.RenderTexture2D( Game.m_cGOB_MENUBUTTONS_TABLE,
												Game.GetSrcRectForMenuButton( 2,bMouseDown ),
												oTrgRect,new Microsoft.DirectX.Vector2( 0,0 ),
												0,0,false,System.Drawing.Color.White.ToArgb() );
		}

		public void RenderTextWithShadow( string sText,long nX,long nY,
												 System.Drawing.Color oTextColor,System.Drawing.Color oBackColor )
		{
			RenderTextWithShadow( sText,nX,nY,oTextColor,oBackColor,Rectangle.Empty );
		}
		public void RenderTextWithShadow( string sText,long nX,long nY,
						System.Drawing.Color oTextColor,System.Drawing.Color oBackColor,
						System.Drawing.Rectangle oClipRegion )
		{
			m_oGameEngine.RenderText( nX - 1,nY - 1,oBackColor,sText );
			m_oGameEngine.RenderText( nX + 1,nY - 1,oBackColor,sText );
			m_oGameEngine.RenderText( nX - 1,nY + 1,oBackColor,sText );
			m_oGameEngine.RenderText( nX + 1,nY + 1,oBackColor,sText );

			m_oGameEngine.RenderText( nX    ,nY - 1,oBackColor,sText );
			m_oGameEngine.RenderText( nX    ,nY + 1,oBackColor,sText );
			m_oGameEngine.RenderText( nX - 1,nY    ,oBackColor,sText );
			m_oGameEngine.RenderText( nX + 1,nY    ,oBackColor,sText );

			m_oGameEngine.RenderText( nX,nY,oTextColor,sText,oClipRegion );
		}


		#region Menu Tip Management
		public void Render2DBeforeForms_MenuTip()
		{
			DSForm oForm = null;
			System.Drawing.Rectangle oTipWindow = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oDrawRect = System.Drawing.Rectangle.Empty;


			//Advance our tip choices
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );
			if( m_nGameState == enumStates.MainMenu 
				/*oForm.Visible == true*/ && m_bShowingTip == true )
			{
				//Get our window locations
				oTipWindow = new Rectangle( m_oTipLocation.X,m_oTipLocation.Y,(int)m_vTipSize.X,(int)m_vTipSize.Y );
				oDrawRect = new Rectangle( (int)(oTipWindow.X + m_cTIPBORDER_GRAY_LEFTWIDTH),
					(int)(oTipWindow.Y + m_cTIPBORDER_GRAY_TOPWIDTH),
					(int)(oTipWindow.Width - m_cTIPBORDER_GRAY_LEFTWIDTH - m_cTIPBORDER_GRAY_RIGHTWIDTH),
					(int)(oTipWindow.Height - m_cTIPBORDER_GRAY_TOPWIDTH - m_cTIPBORDER_GRAY_BOTTOMWIDTH) );

				//Draw the black rendering area
				m_oGameEngine.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 
				
				//Draw the border
				m_oGameEngine.RenderBorder( oTipWindow, 
					Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE,
					true );

				//Draw the tip text
				if( m_bShowingTip == true && m_vTipSize.X >= m_cTIPBORDER_MAXWIDTH )
				{
					RenderTextWithShadow( m_sTipShowing,oTipWindow.X + 30,oTipWindow.Y + 20,
										  System.Drawing.Color.White,System.Drawing.Color.Black,oDrawRect );
				}
			}
		}

		private void AdvanceMenuTips( double nElapsedTime )
		{
			//DSForm oForm = null;


			//Advance our tip choices
			//oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );
			//if( m_nGameState == enumStates.MainMenu 
			//	/*oForm.Visible == false*/ && m_bShowingTip == true )
			//{
			//	m_bShowingTip = false;
			//	m_nTimeTillNextTip = DSMisc.GetRnd( 30,60 );
			//}
			/*else*/ if( m_nGameState == enumStates.MainMenu )//oForm.Visible == true )
			{
				m_nTimeTillNextTip -= nElapsedTime;
				m_nTimeTipHasBeenUp += nElapsedTime;

				if( m_bShowingTip == false && m_nTimeTillNextTip <= 0 )
				{
					if( CreateNewTip() == true )
					{
						m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TIPOPEN );
					}
				}
				else if( m_bShowingTip == true && m_nTimeTipHasBeenUp > 20 )
				{
					//Only play the close sound once
					if( m_vTipSize.X == m_cTIPBORDER_MAXWIDTH )
					{
						m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TIPCLOSE );
					}

					m_vTipSize = new Vector2(	(float)(m_vTipSize.X - m_cTIPBORDER_GROWTHAMT_X),
												(float)(m_vTipSize.Y - m_cTIPBORDER_GROWTHAMT_Y) );
					if( m_vTipSize.X <= 0 )
					{
						m_bShowingTip = false;
						m_nTimeTillNextTip = DSMisc.GetRnd( 10,30 );
					}
				}
				else if( m_bShowingTip == true && m_vTipSize.X < m_cTIPBORDER_MAXWIDTH )
				{
					m_vTipSize = new Vector2(	(float)(m_vTipSize.X + m_cTIPBORDER_GROWTHAMT_X),
												(float)(m_vTipSize.Y + m_cTIPBORDER_GROWTHAMT_Y) );
				}
			}
		}
		private bool CreateNewTip()
		{
			m_sTipShowing = GetRandomTip();
			m_nTimeTipHasBeenUp = 0;
			m_vTipSize = new Vector2( 0,0 );
			m_oTipLocation = GetRandomTipLocation();

			m_bShowingTip = ( m_oTipLocation.X != 0 );

			return( m_bShowingTip );
		}
		private string GetRandomTip()
		{
			string sTemp = string.Empty;
			string sTip = string.Empty;
			DSGobTable oGobTable = null;
			long nRow = 0;
			int nSplitLen = 40;
			int nPos = 0;


			oGobTable = m_oMenuGobFile.GetTable( "Tips" );
			nRow = DSMisc.GetRnd( 0,oGobTable.RowCount-1 );
			sTip = (string)oGobTable.GetData( "Tip Text",nRow );

			sTip = "Tip #" + nRow.ToString() + ": " + sTip;

			//Now make that tip fit
			sTemp = sTip;
			sTip = string.Empty;
			while( sTemp.Length > nSplitLen )
			{
				if( sTip.Length > 0 )
				{
					sTip += "\n";
				}

				//Ok so we are going to grab the next nSplitLen chars... go back to the last space
				nPos = sTemp.Substring( 0,nSplitLen+1 ).LastIndexOf( " " );
				sTip += sTemp.Substring( 0,nPos );
				sTemp = sTemp.Substring( nPos );
			}

			if( sTip.Length > 0 )
			{
				sTip += "\n";
			}
			sTip += sTemp;


			return( sTip );
		}
		private Point GetRandomTipLocation()
		{
			System.Drawing.Rectangle oTipSquare = System.Drawing.Rectangle.Empty;
			DSForm oForm = null;
			DSForm oLoopMenu = null;
			Point oNewLocation = Point.Empty;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );

			//You get 10 chances to generate tip
			for( int i=0 ; i<10 ; i++ )
			{
				oTipSquare = new System.Drawing.Rectangle( 
					DSMisc.GetRnd( 10,m_oGameEngine.ScreenWidth-100-10 ),
					DSMisc.GetRnd( 10,m_oGameEngine.ScreenHeight-50-10 ),
					(int)m_cTIPBORDER_MAXWIDTH,(int)m_cTIPBORDER_MAXHEIGHT );

				for( int nFormIdx=0 ; nFormIdx<m_oGameEngine.Forms.Count ; nFormIdx++ )
				{
					oLoopMenu = (DSForm)m_oGameEngine.Forms.GetForm( nFormIdx );

					if( oLoopMenu.Visible == true )
					{
						//Verify that the tip doesn't overlap any visible menu
						if( oTipSquare.Left		<=	oLoopMenu.Right &&
							oTipSquare.Right	>=	oLoopMenu.Left &&
							oTipSquare.Top		<	oLoopMenu.Bottom &&
							oTipSquare.Bottom	>	oLoopMenu.Top )
						{
						}
						else if( oTipSquare.Right < m_oGameEngine.ScreenWidth &&
							oTipSquare.Bottom < m_oGameEngine.ScreenHeight &&
							oTipSquare.Left > 0 && oTipSquare.Top > 0 )
						{
							oNewLocation = new Point( oTipSquare.X,oTipSquare.Y );
							break;
						}
					}
				}
			}

			return( oNewLocation );
		}

		#endregion
		#region Menu Missile Management
		private void AdvanceMenuMissiles( double nElapsedTime )
		{
			ArrayList oNewMissileAttacks = new ArrayList();
			structMenuMissile oMAttack;
			System.Drawing.Rectangle oMenuSquare = System.Drawing.Rectangle.Empty;
			DSForm oForm = null;
			double nX = 0, nY = 0;
			double nPreX = 0, nPreY = 0;


			//We don't do anything unless the game files are loaded
			//if( m_bGameGOBIsLoaded == true )
			{
				//Get our main form location
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );
				if( oForm != null )
				{
					oMenuSquare = new System.Drawing.Rectangle( 
									oForm.Location.X,oForm.Location.Y,
									(int)oForm.Size.X,(int)oForm.Size.Y );
				}

				m_nTimeTillNextMissileLaunch -= nElapsedTime;

				//See if we are going to fire any more missiles
				if( m_nTimeTillNextMissileLaunch <= 0 && m_nGameState == enumStates.MainMenu )
				{
					LaunchNewMissileEffect();
				}

				//Advance any missiles we have out there already 
				for( int i=0 ; i<m_oMenuMissleAttacks.Count ; i++ )
				{
					if( i > m_oMenuMissleAttacks.Count ){ break; }

					oMAttack = (structMenuMissile)m_oMenuMissleAttacks[ i ];
					nPreX = oMAttack.m_nPercSourceX * m_oGameEngine.ScreenWidth;
					nPreY = oMAttack.m_nPercSourceY * m_oGameEngine.ScreenHeight;
					oMAttack.m_nPercSourceX += oMAttack.m_nPercSpeedX * nElapsedTime * 2;
					oMAttack.m_nPercSourceY += oMAttack.m_nPercSpeedY * nElapsedTime * 2;
					nX = oMAttack.m_nPercSourceX * m_oGameEngine.ScreenWidth;
					nY = oMAttack.m_nPercSourceY * m_oGameEngine.ScreenHeight;

					m_oMenuMissleAttacks.RemoveAt( i );
					i--;

					//If the missile is still in bounds re-add it to our tracking collection
					if( ShouldMissileExplode( nPreX,nPreY,nX,nY ) == true )
					{
						AddExplosion( oMAttack.m_nPercSourceX - oMAttack.m_nPercSpeedX * nElapsedTime * 2,
									  oMAttack.m_nPercSourceY - oMAttack.m_nPercSpeedY * nElapsedTime * 2 );
					}
					else if( oMAttack.m_nPercSourceX > -.10 && oMAttack.m_nPercSourceX < 1.10 && 
							 oMAttack.m_nPercSourceY > -.10 && oMAttack.m_nPercSourceY < 1.10 )
					{
						oNewMissileAttacks.Add( oMAttack );
					}
				}

				m_oMenuMissleAttacks = oNewMissileAttacks;

				AdvanceMenuMissiles_Explosions( nElapsedTime );
			}
		}
		private bool ShouldMissileExplode( double nPreX,double nPreY,double nX,double nY )
		{
			DSForm oForm = null;
			Rectangle oTipWindow = Rectangle.Empty;


			//Go through and look for any visible forms to hit
			for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
			{
				oForm = (DSForm)m_oGameEngine.Forms.GetForm( i );
				if( oForm.Visible == true &&
					nX >= oForm.Location.X && nX <= oForm.Location.X + oForm.Size.X &&
					nY >= oForm.Location.Y && nY <= oForm.Location.Y + oForm.Size.Y &&
					(
						nPreX < oForm.Location.X || nPreX > oForm.Location.X + oForm.Size.X ||
						nPreY < oForm.Location.Y || nPreY > oForm.Location.Y + oForm.Size.Y 
					)
				  )
				{
					return( true );
				}
			}

			//Check the tooltip if its open
			if( m_bShowingTip == true && m_vTipSize.X >= m_cTIPBORDER_MAXWIDTH )
			{
				//Get our window locations
				oTipWindow = new Rectangle( (int)(m_oTipLocation.X + m_cTIPBORDER_GRAY_LEFTWIDTH),
										    (int)(m_oTipLocation.Y + m_cTIPBORDER_GRAY_TOPWIDTH),
										    (int)(m_vTipSize.X - m_cTIPBORDER_GRAY_LEFTWIDTH - m_cTIPBORDER_GRAY_RIGHTWIDTH),
										    (int)(m_vTipSize.Y - m_cTIPBORDER_GRAY_TOPWIDTH - m_cTIPBORDER_GRAY_BOTTOMWIDTH) );

				if( nX >= oTipWindow.Left && nX <= oTipWindow.Right &&
					nY >= oTipWindow.Top && nY <= oTipWindow.Bottom &&
					(
						nPreX < oTipWindow.Left || nPreX > oTipWindow.Right ||
						nPreY < oTipWindow.Top || nPreY > oTipWindow.Bottom 
					)
				  )
				{
					return( true );
				}
			}

			return( false );
		}
		private void AdvanceMenuMissiles_Explosions( double nElapsedTime )
		{
			Explosion oLoopExplosion = null;


			//Walk through all our attacks in progress
			for( int nLoopExploIndex=0 ; nLoopExploIndex<m_oMenuMissleExplosions.Count ; nLoopExploIndex++ )
			{
				oLoopExplosion = (Explosion)m_oMenuMissleExplosions[ nLoopExploIndex ];
				oLoopExplosion.Advance( nElapsedTime,null,null );
			}
		}
		private void Render2DBeforeForms_MenuMissiles()
		{
			System.Drawing.Rectangle oMissleTargetPos = System.Drawing.Rectangle.Empty;
			structMenuMissile oMAttack;
			double nAngle = 0;


			//Advance any missiles we have out there already 
			for( int i=0 ; i<m_oMenuMissleAttacks.Count ; i++ )
			{
				if( i > m_oMenuMissleAttacks.Count ){ break; }

				oMAttack = (structMenuMissile)m_oMenuMissleAttacks[ i ];
				nAngle = DSMath.CalculateRadAngle( 0,0,oMAttack.m_nPercSpeedX,oMAttack.m_nPercSpeedY ) + Math.PI / 2.0;
				oMissleTargetPos = new System.Drawing.Rectangle( 
							(int)( oMAttack.m_nPercSourceX * m_oGameEngine.ScreenWidth),
							(int)( oMAttack.m_nPercSourceY * m_oGameEngine.ScreenHeight ),0,0 );

				Game.RenderMissile( m_oGameEngine,oMissleTargetPos,nAngle,oMAttack.m_nColor );
				/*m_oGameEngine.RenderTexture2D( Game.m_cGOB_MISSLEIMG_TABLE,System.Drawing.Rectangle.Empty,
								oMissleTargetPos,new Vector2(),nAngle,0,false,
								System.Drawing.Color.White.ToArgb() ); */

				Render2DBeforeForms_SmokeTrail( oMAttack,nAngle + Math.PI / 2.0 );
			}

			Render2DBeforeForms_Explosions();
		}
		private void Render2DBeforeForms_SmokeTrail( structMenuMissile oMAttack,double nAngle )
		{
			System.Drawing.Rectangle oSmokeTargetPos = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oSrcRect = System.Drawing.Rectangle.Empty;
			long nPos = 0;
			double nSmokeAngle = 0;


			for( int i=0 ; i<8 ; i++ )
			{
				nSmokeAngle = DSMisc.GetRnd() * Math.PI*2;
				if( i == 0 )	 { nPos = 0; }
				else if( i == 1 ){ nPos = 1; }
				else			 { nPos = 2; }

				oSrcRect = new System.Drawing.Rectangle( 1,(int)( 1+nPos*31 ),
														 Game.m_cSQRW_SMOKE,Game.m_cSQRH_SMOKE );

				oSmokeTargetPos = new Rectangle( 
					(int)( oMAttack.m_nPercSourceX * m_oGameEngine.ScreenWidth + Math.Cos( nAngle ) * ( i + 4 ) * 10 ),
					(int)( oMAttack.m_nPercSourceY * m_oGameEngine.ScreenHeight + Math.Sin( nAngle ) * ( i + 4 )  * 10 ),
					Game.m_cSQRW_SMOKE,Game.m_cSQRH_SMOKE );

				//Adjust it to line up with the missle
				oSmokeTargetPos.X -= Game.m_cSQRW_SMOKE / 2;
				oSmokeTargetPos.Y -= Game.m_cSQRH_SMOKE / 2;

				m_oGameEngine.RenderTexture2D( Game.m_cGOB_SMOKEPARTICLES_TABLE,oSrcRect,oSmokeTargetPos,
					new Vector2( Game.m_cSQRW_SMOKE/2,Game.m_cSQRH_SMOKE/2 ),
					nSmokeAngle,0,false,System.Drawing.Color.White.ToArgb() ); 
			}
		}
		private void Render2DBeforeForms_Explosions()
		{
			long nFrame = 0;
			string sImage = "";
			System.Drawing.Rectangle oPos = new Rectangle();
			System.Drawing.Rectangle oClipRegion = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oExploSrc = new Rectangle();
			Explosion oLoopExplosion = null;


			//Walk through all our attacks in progress
			for( int nLoopExploIndex=0 ; nLoopExploIndex<m_oMenuMissleExplosions.Count ; nLoopExploIndex++ )
			{
				oLoopExplosion = (Explosion)m_oMenuMissleExplosions[ nLoopExploIndex ];

				nFrame = (long)( oLoopExplosion.TimeIntoExplosion / Game.m_cAAEXPLO_TIMEPERFRAMES );
				sImage = Game.m_cGOB_AAEXPLOSIONS_TABLE;
				//Get our graphic source size
				oExploSrc = Game.GetSrcRectForAAExplosion( nFrame );


				//Get our explosion pos
				oPos = new Rectangle( (int)( oLoopExplosion.MenuPercX * m_oGameEngine.ScreenWidth - oExploSrc.Width / 2),
									  (int)( oLoopExplosion.MenuPercY * m_oGameEngine.ScreenHeight - oExploSrc.Height / 2 ), 0, 0 );

				//Adjust for our location
				oPos.Width = oExploSrc.Width;
				oPos.Height = oExploSrc.Height;

				//Now draw the explosion
				m_oGameEngine.RenderTexture2D( sImage, oExploSrc, 
												oPos, new Vector2( 0,0 ), 0, 0, false, 
												System.Drawing.Color.White.ToArgb() );
			}		
		}
		public string AddExplosion( double nPercScreenX,double nPercScreenY )
		{
			Explosion oExplosion = new Explosion();

			oExplosion.DelayTillThisExploIsDone = "";
			oExplosion.IslandGlobalID = "";
			oExplosion.MenuPercX = nPercScreenX;
			oExplosion.MenuPercY = nPercScreenY;
			oExplosion.ExplosionType = enumExplosionType.AAShot;
			oExplosion.IsAntiMatter = false;
			oExplosion.PlaySound = false;

			m_oMenuMissleExplosions.Add( oExplosion );

			return( oExplosion.GlobalID );
		}
		private void LaunchNewMissileEffect()
		{
			long nRnd = 0;
			double nAngle = 0;
			double nX = 0;
			double nY = 0;
			double nSpeed = 0;


			//Now which types of missiles do we want to launch?
			nRnd = DSMisc.GetRnd( 0,10 );
 			//Randomly from top row
			if( nRnd == 0 )
			{
				nRnd = DSMisc.GetRnd( 1,20 );
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 1,nRnd/2 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					AddMenuMissile( DSMisc.GetRnd( 0.0,1.0 ),-.05,
									DSMisc.GetRnd( -.05,.05 ),DSMisc.GetRnd( .05,.1 ) );
				}
			}
				//Randomly from Right side
			else if( nRnd == 1 )
			{
				nRnd = DSMisc.GetRnd( 1,20 );
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 1,nRnd/2 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					AddMenuMissile( 1.05,DSMisc.GetRnd( .1,.9 ),
									DSMisc.GetRnd( -.1,-.05 ),DSMisc.GetRnd( -.05,.05 ) );
				}
			}
				//Randomly from bottom
			else if( nRnd == 2 )
			{
				nRnd = DSMisc.GetRnd( 1,20 );
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 1,nRnd/2 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					AddMenuMissile( DSMisc.GetRnd( .1,.9 ),1.05,
									DSMisc.GetRnd( -.05,.05 ),DSMisc.GetRnd( -.1,-.05 ) );
				}
			}
				//Randomly from left side
			else if( nRnd == 3 )
			{
				nRnd = DSMisc.GetRnd( 1,20 );
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 1,nRnd/2 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					AddMenuMissile( -.05,DSMisc.GetRnd( .1,.9 ),
									DSMisc.GetRnd( .1,.05 ),DSMisc.GetRnd( -.05,.05 ) );
				}
			}
				//Randomly fan from top row
			else if( nRnd == 4 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				for( int i=0 ; i<10 ; i++ )
				{
					AddMenuMissile( .5,-0.05,
						DSMisc.GetRnd( -.05,.05 ),DSMisc.GetRnd( .05,.1 ) );
				}
			}
				//Randomly fan from Right side
			else if( nRnd == 5 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				for( int i=0 ; i<10 ; i++ )
				{
					AddMenuMissile( 1.05,.5,
						DSMisc.GetRnd( -.1,-.05 ),DSMisc.GetRnd( -.05,.05 ) );
				}
			}
				//Randomly fan from bottom
			else if( nRnd == 6 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				for( int i=0 ; i<10 ; i++ )
				{
					AddMenuMissile( .5,1.05,
						DSMisc.GetRnd( -.05,.05 ),DSMisc.GetRnd( -.1,-.05 ) );
				}
			}
				//Randomly fan from left side
			else if( nRnd == 7 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				for( int i=0 ; i<10 ; i++ )
				{
					AddMenuMissile( -.05,.5,
						DSMisc.GetRnd( .1,.05 ),DSMisc.GetRnd( -.05,.05 ) );
				}
			}
				//Randomly fan from center
			else if( nRnd == 8 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				nAngle = 0;
				nSpeed = DSMisc.GetRnd( .01,.05 );
				for( int i=0 ; i<30 ; i++ )
				{
					AddMenuMissile( .5,.5,	Math.Cos( nAngle ) * nSpeed,
											Math.Sin( nAngle ) * nSpeed );
					nAngle += ( Math.PI * 2 ) / 29;
				}
			}
			//Constant fan from center
			else if( nRnd == 9 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				nRnd = DSMisc.GetRnd( 10,50 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					//nAngle = DSMisc.GetRnd( 0,Math.PI*2 );
					nAngle = ( ( Math.PI * 2 ) / nRnd ) * i;
					AddMenuMissile( .5,.5,	Math.Cos( nAngle ) * ( nAngle/100 + .05 ),
											Math.Sin( nAngle ) * ( nAngle/100 + .05 ) );
				}
			}
			//Constant fan from random point
			else if( nRnd == 10 )
			{
				m_nTimeTillNextMissileLaunch = DSMisc.GetRnd( 10,15 );

				nRnd = DSMisc.GetRnd( 10,30 );
				nX = DSMisc.GetRnd( .1,.9 );
				nY = DSMisc.GetRnd( .1,.9 );
				for( int i=0 ; i<nRnd ; i++ )
				{
					//nAngle = DSMisc.GetRnd( 0,Math.PI*2 );
					nAngle = ( ( Math.PI * 2 ) / nRnd ) * i;
					AddMenuMissile( nX,nY,	Math.Cos( nAngle ) * ( nAngle/100 + .05 ),
											Math.Sin( nAngle ) * ( nAngle/100 + .05 ) );
				}
			}


			m_nTimeTillNextMissileLaunch = 3.5;

			//m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_MISLAUNCH );
		}
		private void AddMenuMissile( double nPercX,double nPercY,double nPercVelX,double nPercVelY )
		{
			structMenuMissile oNewMissile;

			if( m_bMenuGOBIsLoaded == false || m_bGameGOBIsLoaded == false )
			{
				oNewMissile.m_nColor = System.Drawing.Color.Red.ToArgb();
			}
			else
			{
				oNewMissile.m_nColor = Game.GetIndexedColor( 1 );
			}

			oNewMissile.m_nPercSourceX = nPercX;
			oNewMissile.m_nPercSourceY = nPercY;
			oNewMissile.m_nPercSpeedX = nPercVelX;
			oNewMissile.m_nPercSpeedY = nPercVelY;

			m_oMenuMissleAttacks.Add( oNewMissile );
		}
		#endregion

		private void StartSinglePlayerGame( int nLevelID )
		{
			AI oAI = null;
			Island oIsland = null;
			string sIsland = "";
			string sAIName = "";
			string sFileName = "";


			if( nLevelID == 21 )
			{
				MessageBox.Show( "You have completed level 20, congratulations!" );

				m_nGameState = enumStates.MainMenu;
				if( m_oGameEngine.DirectPlay.Peer != null )
				{
					m_oGameEngine.DirectPlay.Peer.TerminateSession( null );
				}

				HideAllInGameMenus();
				m_oGame = null;
				SwitchMenus( "",m_cMENU_MAIN,false );
				StartMainForm( false );

				return;
			}
			else
			{
				CreateGameObject();
				m_oGame.IslandFileName = "";
				m_oGame.UseBuildingRot = true;
				Game.GobFile = m_oGameGobFile;
				Game.GameEngine = m_oGameEngine;
				Game.CurrentSinglePlayerLevelID = nLevelID;
				m_nGameState = enumStates.InGame;

				//Spit off an island for Me
				try
				{
					oIsland = new Island( m_oGame );
					sFileName = DSMisc.GetDevelopmentAppPath() + @"Campaign\" + (string)Game.GetCmpgnStat( nLevelID,Game.m_cGOB_CMPGSTATS_PLAYERISLANDNAME_CLMN );
					sIsland = DSMisc.GetFile( sFileName );
					oIsland.DeSerialize( sIsland );
					oIsland.Color = m_oGame.GetNewIslandColor();
				}
				catch( System.Exception oEx )
				{
					DSMisc.ShowErrors( oEx );
				}

				oIsland.GenerateNewGUID();
				oIsland.RotateIsland( 0 );

				//This must be zero, it identifies our island
				oIsland.OwnerSocketID = 0;
				oIsland.OwnerName = "Player";
				oIsland.ImDead = false;
				oIsland.BasesPlaced = false;
				m_oGame.AddIsland( oIsland );

				//Spit off 1 island for the AI
				sAIName = (string)Game.GetCmpgnStat( nLevelID,Game.m_cGOB_CMPGSTATS_AINAME_CLMN );
				oAI = new AI();
				//Get he level from the data of the AI collection
				oAI.AILevel = (enumAILevels)Game.GetCmpgnStat( nLevelID,Game.m_cGOB_CMPGSTATS_AILEVEL_CLMN );
				oAI.Name = sAIName;
				oAI.App = this;
				oAI.Game = m_oGame;
				//Leave this blank for now, we don't know what our GlobalID will be
				oAI.ManagerGlobalID = "";
				m_oGame.AIs.Add( oAI.GlobalID,oAI );
				//Make the AI's Island
				oIsland = new Island( m_oGame );
				sFileName = DSMisc.GetDevelopmentAppPath() + @"Campaign\" + (string)Game.GetCmpgnStat( nLevelID,Game.m_cGOB_CMPGSTATS_COMPISLANDNAME_CLMN );
				sIsland = DSMisc.GetFile( sFileName );
				oIsland.DeSerialize( sIsland );
				oIsland.GenerateNewGUID();
				oIsland.RotateIsland( 2 );
				oIsland.OwnerName = sAIName;
				//This must be -1, 0 identifies our island
				oIsland.OwnerSocketID = -1;
				oIsland.AIOwnerGlobalID = oAI.GlobalID;
				oIsland.ImDead = false;
				oIsland.BasesPlaced = false;
				oIsland.Color = m_oGame.GetNewIslandColor();
				m_oGame.AddIsland( oIsland );


				UpdateForms( false,null );
				StartGame_ClientAndHost();
			}
		}
		//Works in progress...
		private void GameHasStarted_Host( string sStartingMapFileName,bool bUseBuildingRot )
		{
			AI oAI = null;
			Island oIsland = null;
			string sIsland = "";
			string sAIName = "";
			DSNetworkPlayer oLoopPlayer = null;


			try
			{
				CreateGameObject();

				m_oGame.IslandFileName = sStartingMapFileName;
				m_oGame.UseBuildingRot = bUseBuildingRot;
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}

			try
			{
				sIsland = DSMisc.GetFile( sStartingMapFileName );

				//Spit off an island for each player
				for( int nLoopPlayerIndex=0 ; nLoopPlayerIndex<m_oGameEngine.DirectPlay.Players.Count ; nLoopPlayerIndex++ )
				{
					oLoopPlayer = (DSNetworkPlayer)m_oGameEngine.DirectPlay.Players.GetByIndex( nLoopPlayerIndex );

					oIsland = new Island( m_oGame );
					oIsland.DeSerialize( sIsland );
					oIsland.GenerateNewGUID();
					oIsland.OwnerSocketID = oLoopPlayer.SocketID;
					oIsland.OwnerName = oLoopPlayer.Name;
					oIsland.ImDead = false;
					oIsland.BasesPlaced = false;
					oIsland.Color = m_oGame.GetNewIslandColor();
					m_oGame.AddIsland( oIsland );
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}

			try
			{
				//Spit off an island for each AI
				for( int nLoopAI=0 ; nLoopAI<m_oAIsToAdd.Count ; nLoopAI++ )
				{
					sAIName = (string)m_oAIsToAdd.GetKey( nLoopAI );
					oAI = new AI();
					//Get he level from the data of the AI collection
					oAI.AILevel = (enumAILevels)m_oAIsToAdd.GetByIndex( nLoopAI );
					oAI.Name = sAIName;
					oAI.App = this;
					oAI.Game = m_oGame;
					//Leave this blank for now, we don't know what our GlobalID will be
					oAI.ManagerGlobalID = "";
					m_oGame.AIs.Add( oAI.GlobalID,oAI );

					oIsland = new Island( m_oGame );
					oIsland.DeSerialize( sIsland );
					oIsland.GenerateNewGUID();
					oIsland.OwnerName = sAIName;
					oIsland.OwnerSocketID = 0;
					oIsland.AIOwnerGlobalID = oAI.GlobalID;
					oIsland.ImDead = false;
					oIsland.BasesPlaced = false;
					oIsland.Color = m_oGame.GetNewIslandColor();
					m_oGame.AddIsland( oIsland );
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}

			try
			{
				UpdateForms( true,null );

				StartGame_ClientAndHost();
				SendGameUpdate();
				SendMMMsg( enumNetMsg.StartGame );
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}

			m_nGameState = enumStates.InGame;
		}
		private void StartGame_ClientAndHost()
		{
			//MMForm oCForm = null;
			MMPlaceBaseForm oPlaceBaseForm = null;


			//Make sure we don't have anything selected 
			m_oSelectedSquares = new DSSortedList();

			m_nGameState = enumStates.InGame;
			m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY ).Visible = false;

			//Launch the base placement window, if we need it
			oPlaceBaseForm = (MMPlaceBaseForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_BASEPLACE );
			if( oPlaceBaseForm == null )
			{
				oPlaceBaseForm = new MMPlaceBaseForm( null );
				oPlaceBaseForm.Name = Game.m_cFRM_BASEPLACE;
				m_oGameEngine.Forms.Add( oPlaceBaseForm );
			}

			//You MUST set base count before you set the size or it will be the wrong size for the location.
			oPlaceBaseForm.MaxBasesToPlace = GetMyIsland().Island.MaxBasesToPlace;
			oPlaceBaseForm.BasesToPlace = oPlaceBaseForm.MaxBasesToPlace;
			oPlaceBaseForm.Visible = true;
			oPlaceBaseForm.Size = new Vector2( 200,200 );
			oPlaceBaseForm.Location = new Point( (int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferWidth - 20 - oPlaceBaseForm.Size.X ),
												 (int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferHeight - 20 - oPlaceBaseForm.Size.Y ) );
			MakeSureWindowIsOnScreen( oPlaceBaseForm );

			if( GetMyIsland().Island.BasesPlaced == true )
			{
				DonePlacingBases_ClientAndHost();
			}
			
			//Reset the list of groups
			m_oGroupsOfSelectedSquares = new DSSortedList();

			//Update the status
			UpdateStatus( Game.m_cALERT_INFO + "Place your bases" );
			UpdateForms( false,null );
		}

		public void UpdateStatus( string sNewStatus )
		{
			//MMConsoleForm oConsole = null;
			//oConsole = (MMConsoleForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_CONSOLE );
			//oConsole.Status = sNewStatus;

			m_oGame.AlertManager.AddMessage( sNewStatus );
		}

		//This function walks the forms and the game and creates any island forms that are missing
		public void UpdateForms( bool bRotateIslands,Island oIslandToAdjustOnly )
		{
			bool bHaveFoundMyIsland = false;
			int nCornerNumber = 0;
			int nIslandCount = 0;
			MMIslandForm oIForm = null;
			Island oLoopIsland = null;
			Island oLoopIslandToSeeMe = null;

 
			for( int nLoopIslandIndex=0 ; nLoopIslandIndex<m_oGame.Islands.Count ; nLoopIslandIndex++ )
			{
				oLoopIsland = (Island)m_oGame.Islands.GetByIndex( nLoopIslandIndex );

				//Set every other island to be able to see my terrain
				for( int nLoopToSeeMeIndex=0 ; nLoopToSeeMeIndex<m_oGame.Islands.Count ; nLoopToSeeMeIndex++ )
				{
					oLoopIslandToSeeMe = (Island)m_oGame.Islands.GetByIndex( nLoopToSeeMeIndex );
					oLoopIsland.RevealAllTerrainTo( oLoopIslandToSeeMe );
				}

				//Now rotate appropreately
				if( bRotateIslands == true || 
					(
						oIslandToAdjustOnly != null &&
						oIslandToAdjustOnly.GlobalID == oLoopIsland.GlobalID
					)
				  )
				{
					//Pick our direction
					//0=UpperRight, 1=UpperLeft, 2=LowerLeft, 3=LowerRight
					if( oLoopIsland.Direction == 0 )
					{
						oLoopIsland.Direction = ( ( 3 + m_oGame.Islands.Count - nLoopIslandIndex - 1 ) % 4 );
						oLoopIsland.RotateIsland( oLoopIsland.Direction );
					}
				}


				//Create the form
				oIForm = AttachNewIslandToMenu( oLoopIsland,oLoopIsland.OwnerName,Game.m_cISLANDFORMNAME + oLoopIsland.GlobalID,null );
				nCornerNumber = (int)Math.Floor( (double)nLoopIslandIndex / 4.0 );
				oIForm.Island.ResetMMPositions();

				//Log if we have hit our island... that way we can get our count
				if( oIForm.Island.IsMyIsland() == true )
				{
					m_sMyIslandsGlobalID = oIForm.Island.GlobalID;
					bHaveFoundMyIsland = true;
				}

				if( oIForm.FormHasBeenPositioned == false )
				{
					oIForm.FormHasBeenPositioned = true;
					oIForm.Size = new Vector2( (float)m_oGameEngine.ScreenWidth * .45f,(float)m_oGameEngine.ScreenHeight * .45f );

					//Attacks come from upper right
					if( oLoopIsland.Direction == 0 )
					{
						oIForm.Location = new Point( 10 + nCornerNumber * 20,
													(int)( m_oGameEngine.ScreenHeight - oIForm.Size.Y - ( nCornerNumber * 10 ) - 10 ) );
					}
					//Attacks come from upper left
					else if( oLoopIsland.Direction == 1 )
					{
						oIForm.Location = new Point( (int)( m_oGameEngine.ScreenWidth - oIForm.Size.X - ( nCornerNumber * 10 ) - 10 ),
													(int)( m_oGameEngine.ScreenHeight - oIForm.Size.Y - ( nCornerNumber * 10 ) - 10 ) );
					}
					//Attacks come from lower left
					else if( oLoopIsland.Direction == 2 )
					{
						oIForm.Location = new Point( (int)( m_oGameEngine.ScreenWidth - oIForm.Size.X - ( nCornerNumber * 10 ) - 10 ),
													10 + nCornerNumber * 20 );
					}
					//Attacks come from lower right
					else if( oLoopIsland.Direction == 3 )
					{
						oIForm.Location = new Point( 20 + nCornerNumber * 20,20 + nCornerNumber * 20 );
					}

					//Now overright that default position with the saved one
					if( oIForm.Island.IsMyIsland() == true )
					{
						if( m_vWindowPos_Mine.X !=0 || m_vWindowPos_Mine.Y != 0 )
						{
							oIForm.Location = new Point( (int)m_vWindowPos_Mine.X,(int)m_vWindowPos_Mine.Y );
						}
						if( m_vWindowSize_Mine.X !=0 || m_vWindowSize_Mine.Y != 0 )
						{
							oIForm.Size = m_vWindowSize_Mine;
						}
					}
					else
					{
						//Find out which island were going to load to
						nIslandCount = nLoopIslandIndex;
						if( bHaveFoundMyIsland == true )
						{
							nIslandCount--;
						}

						//Ok now load our position if we have it
						if( m_oWindowPos.Count > nIslandCount )
						{
							if( ((Vector2)m_oWindowPos[ nIslandCount ]).X != 0 || ((Vector2)m_oWindowPos[ nIslandCount ]).Y != 0 )
							{
								oIForm.Location = new Point( (int)((Vector2)m_oWindowPos[ nIslandCount ]).X,(int)((Vector2)m_oWindowPos[ nIslandCount ]).Y );
							}
							if( ((Vector2)m_oWindowSize[ nIslandCount ]).X != 0 || ((Vector2)m_oWindowSize[ nIslandCount ]).Y != 0 )
							{
								oIForm.Size = (Vector2)m_oWindowSize[ nIslandCount ];
							}
						}
					}

					MakeSureWindowIsOnScreen( oIForm );
				}
			}
		}
		private MMIslandForm AttachNewIslandToMenu( Island oIsland,string sFormTitle,string sFormName,DSNetworkPlayer oNetOwner )
		{
			MMIslandForm oIForm = null;

			//Create our island form
			oIForm = (MMIslandForm)m_oGameEngine.Forms.GetForm( sFormName );
			if( oIForm == null )
			{
				oIForm = new MMIslandForm( null );
				oIForm.Name = sFormName;
				m_oGameEngine.Forms.Add( oIForm );
			}
			oIForm.Island = oIsland;
			//oIForm.Size = new Vector2( 400,300 );
			//oIForm.Location = new Point( 150,150 );
			oIForm.Text = sFormTitle;
			oIForm.App = this;
			oIForm.GameEngine = m_oGameEngine;
			oIForm.Game = m_oGame;
			oIForm.Visible = true;

			return( oIForm );
		}
		public void DonePlacingBases_ClientAndHost()
		{
			MMPurchaseForm oPurchaseForm = null;
			MMPlaceBaseForm oBPlaceForm = null;
			Island oIsland = null;


			//Mark the purchase phase as done
			oIsland = GetMyIsland().Island;
			oIsland.BasesPlaced = true;
			SendIslandUpdate( oIsland );
			m_oGame.AddIsland( oIsland );

			//Find the form and drop the count of bases to place
			oBPlaceForm = (MMPlaceBaseForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_BASEPLACE );
			oBPlaceForm.BasesToPlace--;
			oBPlaceForm.Visible = false;

			//Open the purchase form
			oPurchaseForm = (MMPurchaseForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_PURCHASE );
			if( oPurchaseForm == null )
			{
				oPurchaseForm = new MMPurchaseForm( null );
				oPurchaseForm.Name = Game.m_cFRM_PURCHASE;
				oPurchaseForm.App = this;
				oPurchaseForm.Size = new Vector2( 200,200 );
				m_oGameEngine.Forms.Add( oPurchaseForm );
			}
			else
			{
				oPurchaseForm.Visible = true;
			}

			//Default the position and then overright it
			oPurchaseForm.Location = new Point( (int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferWidth - 20 - oPurchaseForm.Size.X ),
												(int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferHeight - 20 - oPurchaseForm.Size.Y ) );
			if( m_vPurchasePos.X != 0 || m_vPurchasePos.Y != 0 )
			{
				oPurchaseForm.Location = new Point( (int)m_vPurchasePos.X,(int)m_vPurchasePos.Y );
			}
			MakeSureWindowIsOnScreen( oPurchaseForm );

			//Update the status
			UpdateStatus( Game.m_cALERT_INFO + "You may begin play!" );
		}

		public void LoadINIFile()
		{
			Vector2 vPos = new Vector2( 0,0 );
			Vector2 vSize = new Vector2( 0,0 );
			DSINIFile oINIFile = new DSINIFile();
			bool bMuted = false;
			bool bFound = true;
			int nVolume = 0;
			int nIndex = 0;


			oINIFile.OpenINIFile( DSMisc.GetDevelopmentAppPath() + @"MetalMarines.INI",true );

			m_sUserName				= oINIFile.GetValueForKey( "PlayerName","Player" );
			m_sIP					= oINIFile.GetValueForKey( "LastUsedIP","" );
			m_sGameName				= oINIFile.GetValueForKey( "GameName","New Game" );
			m_sLastMultiMapUsed		= oINIFile.GetValueForKey( "LastMultiMapUsed","" );
			m_sServiceProviderGUID	= oINIFile.GetValueForKey( "ServiceProviderGUID","" );
			m_bDebugMode			= Convert.ToBoolean( oINIFile.GetValueForKey( "DebugMode","false" ) );

			//m_vConsolePos.X			= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vConsolePos.X","0" ) );
			//m_vConsolePos.Y			= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vConsolePos.Y","0" ) );
			m_vPurchasePos.X		= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vPurchasePos.X","0" ) );
			m_vPurchasePos.Y		= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vPurchasePos.Y","0" ) );
			m_vChatPos.X			= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vChatPos.X","0" ) );
			m_vChatPos.Y			= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vChatPos.Y","0" ) );
			m_vWindowPos_Mine.X		= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowPos_Mine.X","0" ) );
			m_vWindowPos_Mine.Y		= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowPos_Mine.Y","0" ) );
			m_vWindowSize_Mine.X	= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowSize_Mine.X","0" ) );
			m_vWindowSize_Mine.Y	= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowSize_Mine.Y","0" ) );

			while( bFound == true )
			{
				vPos.X	= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowPos_Other" + nIndex.ToString() + ".X","0" ) );
				vPos.Y	= (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowPos_Other" + nIndex.ToString() + ".Y","0" ) );
				vSize.X = (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowSize_Other" + nIndex.ToString() + ".X","0" ) );
				vSize.Y = (float)Convert.ToDouble( oINIFile.GetValueForKey( "m_vWindowSize_Other" + nIndex.ToString() + ".Y","0" ) );

				bFound = ( vPos.X != 0 || vPos.Y != 0 || vSize.X != 0 || vSize.Y != 0 );
				if( bFound == true )
				{
					m_oWindowPos.Add( vPos );
					m_oWindowSize.Add( vSize );
				}
				nIndex++;
			}

			bMuted = Convert.ToBoolean( oINIFile.GetValueForKey( "Muted",false.ToString() ) );
			nVolume = Convert.ToInt32( oINIFile.GetValueForKey( "Volume","94" ) );
			m_oGameEngine.DirectSound.Muted = bMuted;
			m_oGameEngine.DirectSound.Volume = (double)nVolume / 100.0;
		}
		public void SaveINIFile()
		{
			//MMConsoleForm oConsoleForm = null;
			MMPurchaseForm oPurchaseForm = null;
			MMIslandForm oIslandForm = null;
			Island oLoopIsland = null;
			DSINIFile oINIFile = new DSINIFile();
			ArrayList oWindowPos = new ArrayList();
			ArrayList oWindowSize = new ArrayList();
			int nIslandCount = 0;


			oINIFile.OpenINIFile( DSMisc.GetDevelopmentAppPath() + @"MetalMarines.INI",true );
			oINIFile.AddKey( "PlayerName",m_sUserName );
			oINIFile.AddKey( "LastUsedIP",m_sIP );
			oINIFile.AddKey( "GameName",m_sGameName );
			oINIFile.AddKey( "Muted",m_oGameEngine.DirectSound.Muted.ToString() );
			oINIFile.AddKey( "Volume",(m_oGameEngine.DirectSound.Volume*100).ToString() );
			oINIFile.AddKey( "LastMultiMapUsed",m_sLastMultiMapUsed );
			oINIFile.AddKey( "ServiceProviderGUID",m_sServiceProviderGUID );

			//Update our locations if we can
			oIslandForm = GetMyIsland();
			if( oIslandForm != null && oIslandForm.Minimized == false )
			{
				m_vWindowPos_Mine = new Vector2( oIslandForm.Location.X,oIslandForm.Location.Y );
				m_vWindowSize_Mine = oIslandForm.Size;
			}

			/*oConsoleForm = (MMConsoleForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_CONSOLE );
			if( oConsoleForm != null )
			{
				m_vConsolePos = new Vector2( oConsoleForm.Location.X,oConsoleForm.Location.Y );
			}*/

			oPurchaseForm = (MMPurchaseForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_PURCHASE );
			if( oPurchaseForm != null )
			{
				m_vPurchasePos = new Vector2( oPurchaseForm.Location.X,oPurchaseForm.Location.Y );
			}

			/*oConsoleForm = (MMConsoleForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_CONSOLE );
			if( oConsoleForm != null )
			{
				m_vConsolePos = new Vector2( oConsoleForm.Location.X,oConsoleForm.Location.Y );
			}*/

			//Find our islands count
			if( m_oGame != null )
			{
				for( int nLoopIslandIndex=0 ; nLoopIslandIndex<m_oGame.Islands.Count ; nLoopIslandIndex++ )
				{
					oLoopIsland = (Island)m_oGame.Islands.GetByIndex( nLoopIslandIndex );
					oIslandForm = GetIsland( oLoopIsland.GlobalID );

					if( oLoopIsland.IsMyIsland() == false )
					{
						if( nIslandCount+1 > m_oWindowPos.Count )
						{
							m_oWindowPos.Add( new Vector2( oIslandForm.Location.X,oIslandForm.Location.Y ) );
							m_oWindowSize.Add( oIslandForm.Size );

							if( oIslandForm.Minimized == true )
							{
								m_oWindowPos[ nIslandCount ]	= new Vector2( 0,0 );
								m_oWindowSize[ nIslandCount ]	= new Vector2( 0,0 );
							}
						}
						else if( oIslandForm.Minimized == false )
						{
							m_oWindowPos[ nIslandCount ]	= new Vector2( oIslandForm.Location.X,oIslandForm.Location.Y );
							m_oWindowSize[ nIslandCount ]	= oIslandForm.Size;
						}

						nIslandCount++;
					}
				}
			}

			//oINIFile.AddKey( "m_vConsolePos.X",m_vConsolePos.X.ToString() );
			//oINIFile.AddKey( "m_vConsolePos.Y",m_vConsolePos.Y.ToString() );
			oINIFile.AddKey( "m_vPurchasePos.X",m_vPurchasePos.X.ToString() );
			oINIFile.AddKey( "m_vPurchasePos.Y",m_vPurchasePos.Y.ToString() );
			oINIFile.AddKey( "m_vChatPos.X",m_vChatPos.X.ToString() );
			oINIFile.AddKey( "m_vChatPos.Y",m_vChatPos.Y.ToString() );
			oINIFile.AddKey( "m_vWindowPos_Mine.X",m_vWindowPos_Mine.X.ToString() );
			oINIFile.AddKey( "m_vWindowPos_Mine.Y",m_vWindowPos_Mine.Y.ToString() );
			oINIFile.AddKey( "m_vWindowSize_Mine.X",m_vWindowSize_Mine.X.ToString() );
			oINIFile.AddKey( "m_vWindowSize_Mine.Y",m_vWindowSize_Mine.Y.ToString() );

			for( int nIndex=0 ; nIndex<m_oWindowPos.Count ; nIndex++ )
			{
				if( (Vector2)m_oWindowPos[ nIndex ] != Vector2.Empty )
				{
					oINIFile.AddKey( "m_vWindowPos_Other" + nIndex.ToString() + ".X",((Vector2)m_oWindowPos[ nIndex ]).X.ToString() );
					oINIFile.AddKey( "m_vWindowPos_Other" + nIndex.ToString() + ".Y",((Vector2)m_oWindowPos[ nIndex ]).Y.ToString() );
					oINIFile.AddKey( "m_vWindowSize_Other" + nIndex.ToString() + ".X",((Vector2)m_oWindowSize[ nIndex ]).X.ToString() );
					oINIFile.AddKey( "m_vWindowSize_Other" + nIndex.ToString() + ".Y",((Vector2)m_oWindowSize[ nIndex ]).Y.ToString() );
				}
			}

			oINIFile.SaveINIFile();
		}

		public MMIslandForm GetIsland( string sIslandGlobalID )
		{
			DSForm oForm = null;
			MMIslandForm oIsland = null;
			MMIslandForm oRetVal = null;


			for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
			{
				oForm = m_oGameEngine.Forms.GetForm( i );

				if( oForm.GetType().FullName.ToString() == "MetalMarines.MMIslandForm" )
				{
					oIsland = (MMIslandForm)oForm;
					if( oIsland.Island.GlobalID == sIslandGlobalID )
					{
						oRetVal = oIsland;
						break;
					}
				}
			}

			return( oRetVal );
		}

		public MMIslandForm GetMyIsland()
		{
			MMIslandForm oIslandForm = null;

			oIslandForm = GetIsland( m_sMyIslandsGlobalID );

			return( oIslandForm );
		}

		private void HideAllInGameMenus()
		{
			DSForm oForm = null;


			m_oGame.AlertManager.Clear();

			//Hide the forms were done with
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING );
			if( oForm != null )
			{
				oForm.Visible = false;
			}
			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_CONSOLE );
			if( oForm != null )
			{
				oForm.Visible = false;
			}
			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_PURCHASE );
			if( oForm != null )
			{
				oForm.Visible = false;
			}
			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_BASEPLACE );
			if( oForm != null )
			{
				oForm.Visible = false;
			}
			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_POPUP );
			if( oForm != null )
			{
				oForm.Visible = false;
			}
						
			//oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM );
			//oForm.Visible = false;
			//Now remove all the island forms
			for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
			{
				oForm = (DSForm)m_oGameEngine.Forms.GetForm( i );
				if( oForm != null && oForm.GetType() == typeof( MMIslandForm ) )
				{
					oForm.Visible = false;
				}
			}
		}


		private void MakeSureWindowIsOnScreen( DSForm oForm )
		{
			int nTemp = 0;


			if( oForm.Left < 0 )
			{
				oForm.Left = 0;
			}
			if( oForm.Top < 0 )
			{
				oForm.Top = 0;
			}

			if( oForm.Right > m_oGameEngine.ScreenWidth )
			{
				nTemp = oForm.Right - m_oGameEngine.ScreenWidth;
				if( oForm.Left - nTemp < 0 )
				{
					oForm.Left = 0;
					oForm.Size = new Vector2( m_oGameEngine.ScreenWidth,oForm.Size.Y );
				}
				else
				{
					oForm.Left -= nTemp;
				}
			}
			if( oForm.Bottom > m_oGameEngine.ScreenHeight )
			{
				nTemp = oForm.Bottom - m_oGameEngine.ScreenHeight;
				if( oForm.Top - nTemp < 0 )
				{
					oForm.Top = 0;
					oForm.Size = new Vector2( oForm.Size.X,m_oGameEngine.ScreenHeight );
				}
				else
				{
					oForm.Top -= nTemp;
				}
			}
		}
		private void CenterWindow( DSForm oForm )
		{
			oForm.Left = (int)( m_oGameEngine.ScreenWidth / 2.0 - oForm.Size.X / 2.0 );
			oForm.Top = (int)( m_oGameEngine.ScreenHeight / 2.0 - oForm.Size.Y / 2.0 );
		}
		#endregion

		#region DirectPlay Functions
		private void DataReceived( DSNetworkPlayer oSendingPlayer,DSNetworkPacket oPacket )
		{
			DSForm oForm = null;
			DSEditBox oEditBox = null;
			DSNetworkPlayer oPlayer = null;
			MMTeamForm oTeamForm = null;
			DSCheckBox oCheckBox = null;
			Island oIsland = null;
			Island oSourceIsland = null;
			MissleAttack oMissleAttack = null;
			Explosion oExplosion = null;
			MMAttack oMMAttack = null;
			DSListBox oListBox = null;
			int nOldColor = 0;
			enumAILevels nLevel = enumAILevels.Hard;
			double nAmountTaken = 0;
			string sTemp = "";
			string sName = "";
			string sMessage = "";
			string[] saAIs = null;

try
{
			if( oPacket.MsgType == (long)enumNetMsg.ReadyToStartRequest )
			{
				if( m_oPreGamePlayerStatus.ContainsKey( oPacket.GetParamater( 0 ) ) == true )
				{
					m_oPreGamePlayerStatus.Remove( oPacket.GetParamater( 0 ) );
				}
				m_oPreGamePlayerStatus.Add( oPacket.GetParamater( 0 ),Convert.ToBoolean( oPacket.GetParamater( 1 ) ) );

				UpdatePreGameStatus();
			}
			else if( oPacket.MsgType == (long)enumNetMsg.LobbyBuildingRotChecked )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
				if( oForm != null )
				{
					oCheckBox = (DSCheckBox)oForm.GetControl( "chkDestroyedBuildingsRot" );
					oCheckBox.IsChecked = Convert.ToBoolean( oPacket.GetParamater( 0 ) );					
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.LobbyMessage )
			{
				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TYPING );

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
				if( oForm != null )
				{
					oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
					oListBox.AddItem( oPacket.GetParamater( 0 ) + ": " + oPacket.GetParamater( 1 ),null );
					oListBox.SelectItem( oListBox.GetItemCount()-1 );
				}

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING );
				if( oForm != null )
				{
					if( ProcessCheatCode( oPacket.GetParamater( 1 ),true,out sMessage ) == true )
					{
						sMessage += " (" + oPacket.GetParamater( 0 ) + ")";
					}
					else
					{
						sMessage = oPacket.GetParamater( 0 ) + ": " + oPacket.GetParamater( 1 );
					}

					oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
					oListBox.AddItem( sMessage,null );
					oListBox.SelectItem( oListBox.GetItemCount()-1 );

					if( m_nGameState == enumStates.InGame && oForm.Visible == false )
					{
						StartTypingForm( false );
					}
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.StartGame )
			{
				m_bReceivedGameStart = true;

				if( m_oGame != null && m_nGameState != enumStates.InGame && m_nGameState != enumStates.ResumeMenu )
				{
					if( m_bGameGOBIsLoaded == false )
					{
						m_bStartMultipalyerGameOnceGOBIsLoaded = true;
					}
					else
					{
						StartGame_ClientAndHost();
					}
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.FullGameRefresh )
			{
				if( m_oGame == null )
				{
					CreateGameObject();
				}

				lock( m_oGame )
				{
					m_oGame.DeSerialize( oPacket.GetParamater( 0 ) );
					UpdateForms( false,null );
				}

				if( m_bReceivedGameStart == true && m_nGameState == enumStates.MainMenu )
				{
					StartGame_ClientAndHost();
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.IslandRefresh && m_oGame != null )
			{
				oIsland = m_oGame.GetIsland( oPacket.GetParamater( 0 ) );

				lock( m_oGame )
				{
					if( oIsland == null )
					{
						//If someone sent us a new island we need to make sure they get our island
						oIsland = GetMyIsland().Island;
						oIsland.NeedToSendWholeIsland = true;
						SendIslandUpdate( oIsland );

						//Now get there island back down
						oIsland = new Island( m_oGame );
						oIsland.DeSerialize( oPacket.GetParamater( 1 ) );
						nOldColor = oIsland.Color;

						m_oGame.AddIsland( oIsland );
						oIsland.Color = nOldColor;
					}
					else
					{
						oIsland.DeSerialize( oPacket.GetParamater( 1 ) );
					}

					//If the update of the island was caused by a missle attack, there may be squares
					//that need to be refreshed.
					if( oPacket.ParamaterCount == 3 )
					{
						if( oPacket.GetParamater( 2 ).Length > 0 )
						{
							oMissleAttack = new MissleAttack();
							oMissleAttack.DeSerialize( oPacket.GetParamater( 2 ) );

							//Did we prompt this attack?
							oSourceIsland = GetIsland( oMissleAttack.SourceIslandGlobalID ).Island;
							if( m_oGame.HaveSharedVision( oSourceIsland,GetMyIsland().Island ) == true )
							//if( oMissleAttack.SourceIslandGlobalID == GetMyIsland().Island.GlobalID )
							{
								//Tell the island to update what we can view based upon this information.
								oIsland.UpdateSquaresICanSeeFromRefresh( oMissleAttack,GetMyIsland().Island );
							}
						}
					}
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.MissleAttack && m_oGame != null )
			{
				oMissleAttack = new MissleAttack();
				oMissleAttack.DeSerialize( oPacket.GetParamater( 0 ) );

				//Add the attack to the game
				lock( m_oGame )
				{
					if( m_oGame.MissleAttacks.ContainsKey( oMissleAttack.GlobalID ) == true )
					{
						m_oGame.MissleAttacks.Remove( oMissleAttack.GlobalID );
					}
					m_oGame.MissleAttacks.Add( oMissleAttack.GlobalID,oMissleAttack );
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.MMAttack && m_oGame != null )
			{
				//If it already exists then update it
				lock( m_oGame )
				{
					if( m_oGame.MetalMarineAttacks.IndexOfKey( (string)oPacket.GetParamater( 0 ) ) != -1 )
					{
						oMMAttack = (MMAttack)m_oGame.MetalMarineAttacks.GetByKey( (string)oPacket.GetParamater( 0 ) );
						oMMAttack.DeSerialize( oPacket.GetParamater( 1 ) );
					}
					else
					{
						oMMAttack = new MMAttack();
						oMMAttack.Game = m_oGame;
						oMMAttack.GameEngine = m_oGameEngine;
						oMMAttack.DeSerialize( oPacket.GetParamater( 1 ) );

						//Add the attack to the game
						m_oGame.MetalMarineAttacks.Add( oMMAttack.GlobalID,oMMAttack );
					}
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.Explosion && m_oGame != null )
			{
				oExplosion = new Explosion();
				oExplosion.DeSerialize( (string)oPacket.GetParamater( 1 ) );

				lock( m_oGame )
				{
					m_oGame.Explosions.Add( oExplosion.GlobalID,oExplosion );
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_EXPLOSION );
				}
			}
			else if( oPacket.MsgType == (long)enumNetMsg.MMReturnHome && m_oGame != null )
			{
				lock( m_oGame )
				{
					//This means the MMAttack is over so we need to find the square.  It will need to
					//be told that the MM has returned home.  Start by finding the attack.
					m_oGame.MMAttackIsOver( oPacket.GetParamater( 0 ),Convert.ToBoolean( oPacket.GetParamater( 1 ) ) );
				}
			}
			//This means a team was disbanded, make sure were not in it
			else if( oPacket.MsgType == (long)enumNetMsg.DisbandTeam && m_oGame != null )
			{
				oIsland = GetMyIsland().Island;
				lock( oIsland )
				{
					//If were in this team set us to un-allied
					if( oIsland.GlobalIDOfPlayerWhoseTeamImOn == oPacket.GetParamater( 0 ) )
					{
						oIsland.GlobalIDOfPlayerWhoseTeamImOn = "";
						SendIslandUpdate( GetMyIsland().Island );
					}

					oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
					if( oTeamForm != null )
					{
						oTeamForm.SetupButtons();
					}
				}
			}
			//This means someone was kicked from a team, make sure its not us
			else if( oPacket.MsgType == (long)enumNetMsg.KickFromTeam && m_oGame != null )
			{
				//If we were kicked set us to un-allied
				oIsland = GetMyIsland().Island;
				lock( oIsland )
				{
					if( oIsland.GlobalID == oPacket.GetParamater( 0 ) )
					{
						oIsland.GlobalIDOfPlayerWhoseTeamImOn = "";
						SendIslandUpdate( GetMyIsland().Island );
					}

					oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
					if( oTeamForm != null )
					{
						oTeamForm.SetupButtons();
					}
				}
			}
			//Someone just got approved on our team
			else if( oPacket.MsgType == (long)enumNetMsg.ApprovePlayer && m_oGame != null )
			{
				//If we were kicked set us to un-allied
				oIsland = GetMyIsland().Island;
				lock( oIsland )
				{
					if( oIsland.GlobalID == oPacket.GetParamater( 0 ) )
					{
						//Are we joining or quiting a team?
						if( oIsland.TeamJoinApproved == false )
						{
							oIsland.TeamJoinApproved = true;
						}
						else if( GetMyIsland().Island.TeamQuitPending == true )
						{
							oIsland.TeamQuitPending = false;
							oIsland.GlobalIDOfPlayerWhoseTeamImOn = "";
						}
					
						SendIslandUpdate( oIsland );
					}
				}

				oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
				if( oTeamForm != null )
				{
					oTeamForm.SetupButtons();
				}
			}
			//Someone was just given money
			else if( oPacket.MsgType == (long)enumNetMsg.SendingResources && m_oGame != null )
			{
				//This is the sender
				oIsland = GetIsland( oPacket.GetParamater( 2 ) ).Island;
				lock( oIsland )
				{
					oIsland.Credits -= Convert.ToInt64( oPacket.GetParamater( 0 ) );
					oIsland.Fuel -= Convert.ToInt64( oPacket.GetParamater( 1 ) );
				}
				oPlayer = m_oGameEngine.DirectPlay.GetPlayer( oIsland.OwnerSocketID );

				//This might be me... its the receiver
				oIsland = GetIsland( oPacket.GetParamater( 3 ) ).Island;
				lock( oIsland )
				{
					oIsland.Credits += Convert.ToInt64( oPacket.GetParamater( 0 ) );
					oIsland.Fuel += Convert.ToInt64( oPacket.GetParamater( 1 ) );
				}

				//Is this going to me?
				if( GetMyIsland().Island.GlobalID == oIsland.GlobalID )
				{
					//Update the player
					sTemp = "";
					if( Convert.ToInt64( oPacket.GetParamater( 0 ) ) > 0 )
					{
						sTemp = ((long)Convert.ToDouble( oPacket.GetParamater( 0 ) ) ).ToString() + " credits";
					}
					if( Convert.ToInt64( oPacket.GetParamater( 1 ) ) > 0 )
					{
						if( sTemp.Length > 0 ){ sTemp += " and "; }
						sTemp += ((long)Convert.ToDouble( oPacket.GetParamater( 1 ) ) ).ToString() + " fuel";
					}

					UpdateStatus( Game.m_cALERT_MONEY + oPlayer.Name + " has just gaven you " + sTemp + " credits." );
				}
			}
			//Someone has just taken money
			else if( oPacket.MsgType == (long)enumNetMsg.TakingResources && m_oGame != null )
			{
				oIsland = GetIsland( oPacket.GetParamater( 3 ) ).Island;
				lock( oIsland )
				{
					oPlayer = m_oGameEngine.DirectPlay.GetPlayer( oIsland.OwnerSocketID );
					oIsland.Credits += Convert.ToDouble( oPacket.GetParamater( 0 ) );
					oIsland.Fuel += Convert.ToDouble( oPacket.GetParamater( 1 ) );
 
					oIsland = GetIsland( oPacket.GetParamater( 2 ) ).Island;
					oIsland.Credits -= Convert.ToDouble( oPacket.GetParamater( 0 ) );
					oIsland.Fuel -= Convert.ToDouble( oPacket.GetParamater( 1 ) );

					//Is this going to me?
					if( GetMyIsland().Island.GlobalID == oIsland.GlobalID )
					{						
						//Update the player
						nAmountTaken = Convert.ToDouble( oPacket.GetParamater( 0 ) );
						if( nAmountTaken > 0 )
						{
							UpdateStatus( Game.m_cALERT_MONEY + oPlayer.Name + " just took " + ((long)Math.Ceiling( nAmountTaken ) ).ToString() + " credits" );
						}

						nAmountTaken = Convert.ToDouble( oPacket.GetParamater( 1 ) );
						if( nAmountTaken > 0 )
						{
							UpdateStatus( Game.m_cALERT_MONEY + oPlayer.Name + " just took " + ((long)Math.Ceiling( nAmountTaken ) ).ToString() + " fuel" );
						}
					}
				}
			}
			//Sync up our AI listing
			else if( oPacket.MsgType == (long)enumNetMsg.AddAI )
			{
				//Get the AI list with the new import
				m_oAIsToAdd = new DSSortedList();
				saAIs = DSMisc.Split( oPacket.GetParamater( 0 ),m_cAILIST_SEP );
				for( int i=0 ; i<saAIs.Length-1 ; i+=2 )
				{
					sName = saAIs[ i ];
					nLevel = (enumAILevels)Convert.ToInt64( saAIs[ i+1 ] );
					m_oAIsToAdd.Add( sName,nLevel );
				}

				//Update our list
				UpdatePreGameStatus();
			}			
			//Sync up our selected map in the lobby
			else if( oPacket.MsgType == (long)enumNetMsg.LobbyMapFileChanged )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
				if( oForm != null && m_oGameEngine.DirectPlay.IAmTheHost == false )
				{
					oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );
					oEditBox.Text = (string)oPacket.GetParamater( 0 );
				}
			}

}catch( System.Exception oEx )
{
	System.Exception oExNew = new System.Exception( oPacket.MsgType.ToString() + ": Packet recieve error",oEx );
	DSMisc.ShowErrors( oExNew );
}
		}
		private void PlayerJoined( DSNetworkPlayer oNewPlayer,bool bUs )
		{
			bool bFound = false;
			string sIsland = "";
			Island oIsland = null;
			MMIslandForm oMMIslandForm = null;
			DSListBox oListBox = null;
			DSForm oForm = null;


			try
			{
				UpdatePreGameStatus();

				//Send them any AI's we have if we are host
				if( m_oGameEngine.DirectPlay.Me.IAmHost == true )
				{	
					//These two calls are smart enough to only send if I am the host and we are in the lobby
					SendAIList();
					SendLobbyMapFile();
				}

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
				if( oForm != null && bUs == false )
				{
					//Send the message that he joined
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TYPING );
					oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
					oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
					oListBox.AddItem( "Player " + oNewPlayer.Name + " joined.",null );
					oListBox.SelectItem( oListBox.GetItemCount()-1 );
				}

				//If we are in game then they need to know to place bases and we need to add them
				if( m_nGameState == enumStates.InGame )
				{
					if( m_oGameEngine.DirectPlay.IAmTheHost == true )
					{
						//Does this player already have an island?
						for( int i=0 ; i<m_oGameEngine.Forms.Count ; i++ )
						{
							oForm = (DSForm)m_oGameEngine.Forms.GetForm( i );
							if( oForm.GetType() == typeof( MMIslandForm ) )
							{
								oMMIslandForm = (MMIslandForm)oForm;
								if( oMMIslandForm.Visible == false &&
									oMMIslandForm.Text == oNewPlayer.Name )
								{
									bFound = true;
									break;
								}
							}
						}

						//Did we find an island for them?  Kewl!
						if( bFound == false )
						{
							oIsland = new Island( m_oGame );
							sIsland = DSMisc.GetFile( m_oGame.IslandFileName );
							oIsland.DeSerialize( sIsland );

							oIsland.GenerateNewGUID();
							oIsland.OwnerSocketID = oNewPlayer.SocketID;
							oIsland.OwnerName = oNewPlayer.Name;
							oIsland.Color = m_oGame.GetNewIslandColor();
							oIsland.ImDead = false;
							oIsland.BasesPlaced = false;
						}
						else
						{
							oIsland = oMMIslandForm.Island;
							oMMIslandForm.Visible = true;
						}

						oIsland.OwnerName = oNewPlayer.Name;
						oIsland.OwnerSocketID = oNewPlayer.SocketID;
						m_oGame.AddIsland( oIsland );

						UpdateForms( true,oIsland );
						SendGameUpdate();
						SendMMMsg( enumNetMsg.StartGame );
					}

					//Tell everyone they joined
					if( bUs == false )
					{
						m_oGame.AlertManager.AddMessage( "Player " + oNewPlayer.Name + " joined." );
					}
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}
		}

		private void PlayerQuit( DSNetworkPlayer oNewPlayer )
		{
			Island oIsland = null;
			DSListBox oListBox = null;
			DSForm oForm = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			if( oForm != null )
			{
				oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );
				oListBox.Remove( oNewPlayer.SocketID.ToString() );

				//Post a message that he quit
				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TYPING );
				oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
				oListBox.AddItem( "Player " + oNewPlayer.Name + " quit.",null );
				oListBox.SelectItem( oListBox.GetItemCount()-1 );
			}

			//If we are in game then they need to know to place bases and we need to add them
			if( m_nGameState == enumStates.InGame )
			{
				oIsland = m_oGame.GetIslandBySocketID( oNewPlayer.SocketID );
				m_oGame.RemoveIsland( oIsland.GlobalID );
				//m_oGameEngine.Forms.Remove( Game.m_cISLANDFORMNAME + oIsland.GlobalID );
				m_oGameEngine.Forms.GetForm( Game.m_cISLANDFORMNAME + oIsland.GlobalID ).Visible = false;

				//Tell everyone they joined
				m_oGame.AlertManager.AddMessage( "Player " + oNewPlayer.Name + " quit." );
			}

			UpdatePreGameStatus();
		}

		private void Connection( Microsoft.DirectX.DirectPlay.ResultCode oCode,string sDescription,bool bConnectionSuccessful )
		{
			DSForm oForm = null;


			if( bConnectionSuccessful == true )
			{				
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );
				oForm.Visible = false;
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_WAITINGTOCONNECT );
				oForm.Visible = false;

				StartLobbyForm( false );

				SwitchMenus( "",m_cMENU_NETLOBBY,true );
				
				SendMMMsg( enumNetMsg.ReadyToStartRequest,
						   m_oGameEngine.DirectPlay.Me.SocketID.ToString(),
						   m_bGameGOBIsLoaded.ToString() );
			}
			else
			{
				MessageBox.Show( sDescription );
				SwitchMenus( m_cMENU_WAITINGTOCONNECT,m_cMENU_MAIN,false );
				StartMainForm( false );
			}
		}
		private void GameListUpdate( FindHostsResponseInformation dpGameInfo )
		{
			int nSelIndex = -1;
			DSForm oForm = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );
			oListBox = (DSListBox)oForm.GetControl( "lstGames" );

			//Remove the old entry
			nSelIndex = oListBox.GetSelectedIndex();
			oListBox.Remove( dpGameInfo.ApplicationDesc.SessionName );

			//Add the new entry
			oListBox.AddItem( dpGameInfo.ApplicationDesc.SessionName,dpGameInfo );

			//Reselect the old entry
			if( nSelIndex != -1 )
			{
				oListBox.SelectItem( nSelIndex );
			}
		}


		public void SendIslandUpdate( Island oIsland )
		{
			SendMMMsg( enumNetMsg.IslandRefresh,oIsland.GlobalID,oIsland.Serialize( true ),"" );
		}
		public void SendIslandUpdate( Island oIsland,MissleAttack oAttack )
		{
			SendMMMsg( enumNetMsg.IslandRefresh,oIsland.GlobalID,oIsland.Serialize( true ),oAttack.Serialize() );
		}
		public void SendGameUpdate()
		{
			SendMMMsg( enumNetMsg.FullGameRefresh,m_oGame.Serialize() );
		}
		public void SendMMAttackUpdate( MMAttack oMMAttack )
		{
			SendMMMsg( enumNetMsg.MMAttack,oMMAttack.GlobalID,oMMAttack.Serialize() );
		}
		/*public void SendExplosion( Explosion oExplosion )
		{
			SendMMMsg( enumNetMsg.Explosion,oExplosion.GlobalID,oExplosion.Serialize() );
		}*/
		public void SendMMHome( MMAttack oMMAttack,bool bMMIsStillALive )
		{
			SendMMMsg( enumNetMsg.MMReturnHome,oMMAttack.GlobalID,bMMIsStillALive.ToString() );
		}

		public void SendTeamDisband( Island oIslandOfTeamDisbanded )
		{
			SendMMMsg( enumNetMsg.DisbandTeam,oIslandOfTeamDisbanded.GlobalID );
		}
		public void SendTeamKick( Island oIslandOfGuyKicked )
		{
			SendMMMsg( enumNetMsg.KickFromTeam,oIslandOfGuyKicked.GlobalID );
		}
		public void SendPlayerApprove( Island oIslandOfPlayer )
		{
			SendMMMsg( enumNetMsg.ApprovePlayer,oIslandOfPlayer.GlobalID );
		}
		public void SendMoneyUpdate( long nCredits,long nFuel,Island oSendToIsland )
		{
			SendMMMsg( enumNetMsg.SendingResources,
								nCredits.ToString(),
								nFuel.ToString(),
								GetMyIsland().Island.GlobalID,
								oSendToIsland.GlobalID );
		}
		public void SendTakingResources( Island oIslandToShare,double nMoneyToContribute,double nFuelToContribute )
		{
			SendMMMsg( enumNetMsg.TakingResources,
						nMoneyToContribute.ToString(),
						nFuelToContribute.ToString(),
						oIslandToShare.GlobalID,
						GetMyIsland().Island.GlobalID );
		}
		public void SendAIList()
		{
			string sAIList = "";
			string sName = "";
			enumAILevels nLevel = enumAILevels.Hard;


			//Serialize the AI list
			for( int i=0 ; i<m_oAIsToAdd.Count ; i++ )
			{
				sName = (string)m_oAIsToAdd.GetKey( i );
				nLevel = (enumAILevels)m_oAIsToAdd.GetByIndex( i );
				sAIList += sName + m_cAILIST_SEP +
						   Convert.ToInt64( nLevel ).ToString() + m_cAILIST_SEP;
			}

			SendMMMsg( enumNetMsg.AddAI,sAIList );
		}

		public void SendLobbyMapFile()
		{
			DSForm oForm = null;
			DSEditBox oEditBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			if( oForm != null )
			{
				oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );

				SendMMMsg( enumNetMsg.LobbyMapFileChanged,
						   System.IO.Path.GetFileName( oEditBox.Text ) );
			}
		}


		public void SendMMMsg( enumNetMsg nMsgType )
		{
			if( m_oGameEngine.DirectPlay.Me != null )
			{
				m_oGameEngine.DirectPlay.SendMsg( (long)nMsgType );
			}
		}
		public void SendMMMsg( enumNetMsg nMsgType,string sVal1 )
		{
			if( m_oGameEngine.DirectPlay.Me != null )
			{
				m_oGameEngine.DirectPlay.SendMsg( (long)nMsgType,sVal1 );
			}
		}
		public void SendMMMsg( enumNetMsg nMsgType,string sVal1,string sVal2 )
		{
			if( m_oGameEngine.DirectPlay.Me != null )
			{
				m_oGameEngine.DirectPlay.SendMsg( (long)nMsgType,sVal1, sVal2 );
			}
		}
		public void SendMMMsg( enumNetMsg nMsgType,string sVal1,string sVal2,string sVal3 )
		{
			if( m_oGameEngine.DirectPlay.Me != null )
			{
				m_oGameEngine.DirectPlay.SendMsg( (long)nMsgType,sVal1,sVal2,sVal3 );
			}
		}
		public void SendMMMsg( enumNetMsg nMsgType,string sVal1,string sVal2,string sVal3,string sVal4 )
		{
			if( m_oGameEngine.DirectPlay.Me != null )
			{
				m_oGameEngine.DirectPlay.SendMsg( (long)nMsgType,sVal1,sVal2,sVal3,sVal4 );
			}
		}
		#endregion

		#region DirectInput Functions
		private bool DIMouseMoved( Vector2 vCurPos,MouseState oMouseStateData,bool[] baButtons )
		{
			return( false );
		}

		private bool DIMouseUp( Vector2 vCurPos,long nButton )
		{
			DSForm oForm = null;
			System.Drawing.Rectangle oTrgRect = System.Drawing.Rectangle.Empty;


			m_oDSIntro.UserHitKey();

			//Team button
			oTrgRect = new System.Drawing.Rectangle( 94,3,30,30 );
			if( oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) && nButton == 0 && m_bSinglePlayerMode == false )
			{
				oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
				if( oForm == null || oForm.Visible == false )
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
					StartTeamForm( false );
					SwitchMenus( "",Game.m_cFRM_TEAMDERIVED,true );
				}
			}
			//Comm button
			oTrgRect = new System.Drawing.Rectangle( 44,5,30,30 );
			if( oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) && nButton == 0 )
			{
				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
				//SwitchMenus( "",m_cMENU_INGAMETYPING,true );
				StartTypingForm( false );
			}
			//Menu button
			oTrgRect = new System.Drawing.Rectangle( 3,27,30,30 );
			if( oTrgRect.Contains( (int)this.DSGameEngine.MouseCursor.X,(int)this.DSGameEngine.MouseCursor.Y ) && nButton == 0 )
			{
				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
				SwitchMenus( "",m_cMENU_RESUMEMENU,true );
				StartResumeForm( false );
			}

			return( false );
		}
		private bool DIKeyboardKeyDown( Key oKey,bool[] oState )
		{
			DSForm oForm = null;
			DSSortedList oGroup = null;


			m_oDSIntro.UserHitKey();

			if( m_nGameState == enumStates.InGame )
			{
				if( oKey == Key.Return || oKey == Key.NumPadEnter || oKey == Key.Tab || oKey == Key.Space )
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
					//SwitchMenus( "",m_cMENU_INGAMETYPING,true );
					StartTypingForm( false );
				}
				else if( oKey == Key.Escape || oKey == Key.M || oKey == Key.R )
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
					SwitchMenus( "",m_cMENU_RESUMEMENU,true );
					StartResumeForm( false );
				}
				else if( oKey == Key.T && m_bSinglePlayerMode == false )
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
					oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
					if( oForm == null || oForm.Visible == false )
					{
						StartTeamForm( false );
						SwitchMenus( "",Game.m_cFRM_TEAMDERIVED,true );
					}
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.D1 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D2 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D3 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D4 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D5 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D6 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D7 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D8 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D9 ||
					oKey == Microsoft.DirectX.DirectInput.Key.D0 )
				{
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true ||
						oState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true )
					{
						oGroup = this.SelectedSquares.Clone();

						if( this.GroupsOfSelectedSquares.ContainsKey( oKey.ToString() ) == true )
						{
							this.GroupsOfSelectedSquares.Remove( oKey.ToString() );
						}
						this.GroupsOfSelectedSquares.Add( oKey.ToString(),oGroup );
					}
					else if( this.GroupsOfSelectedSquares.ContainsKey( oKey.ToString() ) == true )
					{
						this.SelectedSquares = (DSSortedList)this.GroupsOfSelectedSquares.GetByKey( oKey.ToString() );
					}
				}
			}
			else if( m_nGameState == enumStates.ResumeMenu )
			{
				if( oKey == Key.Escape )
				{
					cmdResume_Click( null,null );
				}
			}
			else if( m_nGameState == enumStates.MapEditor )
			{
				if( oKey == Key.Escape )
				{
					if( m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORMAINMENU ).Visible == true )
					{
						cmdMapEditDone_Click( null,null );
					}
				}
			}
			else if( m_nGameState == enumStates.MainMenu )
			{
				if( oKey == Key.Escape )
				{
					if( m_oGameEngine.Forms.GetForm( m_cMENU_MAIN ).Visible == true )
					{
						cmdExit_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_NETUSERSELECT ).Visible == true )
					{
						cmdCancelNetGame_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_NETSRVPROVSELECT ).Visible == true )
					{
						cmdCancelServProvSelect_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT ).Visible == true )
					{
						cmdCancelHostClient_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_NETGAMEHOST ).Visible == true )
					{
						cmdCancelHostGame_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_WAITINGTOCONNECT ).Visible == true )
					{
						cmdCancelConnecting_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY ).Visible == true )
					{
						cmdCancelLobby_Click( null,null );
					}
					else if( m_oGameEngine.Forms.GetForm( m_cMENU_OPTIONSMENU ).Visible == true )
					{
						cmdOptionsCancel_Click( null,null );
					}
				}
			}

			return( false );
		}
		private bool DIKeyboardKeyUp( Key oKey,bool[] oState )
		{
			return( false );
		}

		#endregion

		#region Menu Functions
		//This has to all be done together to avoid duplicating the events
		private void InitMenuEvents()
		{
			StartMainForm( true );
			StartNetUserSelectForm( true );
			StartNetServiceProviderPickForm( true );
			StartNetHostClientForm( true );
			StartNetGameCreationForm( true );
			StartWaitingToConnectForm( true );
			this.StartLobbyForm( true );
			StartResumeForm( true );
			StartTypingForm( true );
			StartGiveResourcesForm( true,null );
			StartCreateTeamForm( true );
			StartOptionsForm( true );
			StartMapEditorForm( true );
			StartMapEditorPropertiesForm( true );
			StartTeamForm( true );
		}
		public void SwitchMenus( string sCurMenuKey,string sNewMenuKey,bool bShiftDown )
		{
			m_nMenuSwitch_ElapsedTime = 0;
			m_bMenuSwitch_ShiftDown = bShiftDown;
			m_oMenuSwitch_CurMenu = m_oGameEngine.Forms.GetForm( sCurMenuKey );
			m_oMenuSwitch_NewMenu = m_oGameEngine.Forms.GetForm( sNewMenuKey );

			if( m_oMenuSwitch_NewMenu != null )
			{
				if( m_bMenuSwitch_ShiftDown == true)
				{
					m_oMenuSwitch_NewMenu.Location = new Point( (int)( m_oGameEngine.ScreenWidth / 2 - m_oMenuSwitch_NewMenu.Size.X / 2 ),
																(int)-m_oMenuSwitch_NewMenu.Size.Y );
				}
				else
				{
					m_oMenuSwitch_NewMenu.Location = new Point( (int)( m_oGameEngine.ScreenWidth / 2 - m_oMenuSwitch_NewMenu.Size.X / 2 ),
																m_oGameEngine.ScreenHeight );
				}
				m_oMenuSwitch_NewMenu.Visible = true;
				m_oGameEngine.Forms.MoveFormToTop( m_oMenuSwitch_NewMenu.Name );
			}
		}
		private void Advance_SwitchMenus( double nElapsedTime )
		{
			double nChange = nElapsedTime + m_nMenuSwitch_ElapsedTime;

			try
			{
				m_nMenuSwitch_ElapsedTime += nElapsedTime * 100;

				if( nChange < 1 ){ nChange = 1; }
				if( m_bMenuSwitch_ShiftDown == false )
				{				
					nChange *= -1;
				}
				
				if( m_oMenuSwitch_CurMenu != null )
				{
					m_oMenuSwitch_CurMenu.Location = new Point( m_oMenuSwitch_CurMenu.Location.X,
																(int)( m_oMenuSwitch_CurMenu.Location.Y + nChange ) );

					if( m_oMenuSwitch_CurMenu.Location.Y >= m_oGameEngine.ScreenHeight ||
						m_oMenuSwitch_CurMenu.Location.Y + m_oMenuSwitch_CurMenu.Size.Y < 0 )
					{
						m_oMenuSwitch_CurMenu.Visible = false;
						m_oMenuSwitch_CurMenu = null;
					}
				}
				if( m_oMenuSwitch_NewMenu != null )
				{
					m_oMenuSwitch_NewMenu.Location = new Point( m_oMenuSwitch_NewMenu.Location.X,
																(int)( m_oMenuSwitch_NewMenu.Location.Y + nChange ) );

					if(
						(
							m_bMenuSwitch_ShiftDown == true &&
							m_oMenuSwitch_NewMenu.Location.Y >= m_oGameEngine.ScreenHeight / 2.0 
																- m_oMenuSwitch_NewMenu.Size.Y / 2
						)
						||
						(
							m_bMenuSwitch_ShiftDown == false &&
							m_oMenuSwitch_NewMenu.Location.Y <= m_oGameEngine.ScreenHeight / 2.0 
																- m_oMenuSwitch_NewMenu.Size.Y / 2
						)
					)
					{
						m_oMenuSwitch_NewMenu.Location = new Point( m_oMenuSwitch_NewMenu.Location.X,
																	(int)( m_oGameEngine.ScreenHeight / 2 - m_oMenuSwitch_NewMenu.Size.Y / 2 ) );
						m_oMenuSwitch_NewMenu = null;
					}
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}
		}


		//This function launches the main DSForm for the app
		private void StartMainForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;


			if( bInitEvents == true )
			{
				//m_nGameState = enumStates.MainMenu;
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );

				oButton = (DSButton)oForm.GetControl( "cmdStartCampaign" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdStartCampaign_Click );

				oButton = (DSButton)oForm.GetControl( "cmdOptions" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdMainMenuOptions_Click );

				oButton = (DSButton)oForm.GetControl( "cmdLoadGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdLoadGame_Click );

				oButton = (DSButton)oForm.GetControl( "cmdMultiplayer" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMultiplayer_Click );

				oButton = (DSButton)oForm.GetControl( "cmdMapEditor" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMainMenuMapEditor_Click );
 
				oButton = (DSButton)oForm.GetControl( "cmdExit" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdExit_Click );
			}
			else
			{
				m_oGameEngine.Forms.GetForm( m_cMENU_MAIN );
			}
		}
		private void cmdStartCampaign_Click( object sender, EventArgs e )
		{
			m_bSinglePlayerMode = true;
			SwitchMenus( m_cMENU_MAIN,"",true );
			m_nSinglePlayerLevelToStartAtOnceGOBIsLoaded = 1;

			if( m_bGameGOBIsLoaded == false )
			{
				m_nGameState = enumStates.LoadingGOBForGame;
			}
			else
			{
				StartSinglePlayerGame( 1 );
			}
		}
		private void cmdLoadGame_Click( object sender, EventArgs e )
		{
			System.Windows.Forms.OpenFileDialog oFileDialog = null;
			string sFile = "";
			string sLevelID = "";


			m_bSinglePlayerMode = true;

			//Display the OpenFileName dialog. Then, try to load the specified file
			oFileDialog = new OpenFileDialog();
			oFileDialog.Filter = "MM Saved Game (*.MMS)|*.MMS";
			oFileDialog.FileName = "*.MMS";
			oFileDialog.InitialDirectory = Environment.CurrentDirectory + @"\Saves";
			oFileDialog.Title = "Load Saved Game";
			oFileDialog.CheckFileExists = true;
			oFileDialog.Multiselect = false;
			oFileDialog.ShowReadOnly = false;

			if( oFileDialog.ShowDialog() == DialogResult.OK )
			{
				//Open the file they selected
				sFile = DSMisc.GetFile( oFileDialog.FileName );
				if( sFile.IndexOf( m_cMMSAVEDGAMEHEADER ) == 0 )
				{
					SwitchMenus( m_cMENU_MAIN,"",true );
					sLevelID = sFile.Substring( m_cMMSAVEDGAMEHEADER.Length + 1 );
					m_nSinglePlayerLevelToStartAtOnceGOBIsLoaded = Convert.ToInt32( sLevelID );

					m_bSinglePlayerMode = true;
					SwitchMenus( m_cMENU_MAIN,"",true );
					if( m_bGameGOBIsLoaded == false )
					{
						m_nGameState = enumStates.LoadingGOBForGame;
					}
					else
					{
						StartSinglePlayerGame( m_nSinglePlayerLevelToStartAtOnceGOBIsLoaded );
					}
					
				}
				else
				{
					MessageBox.Show( "This is not a valid Metal Marines saved game." );
				}
			}
		}
		private void cmdMultiplayer_Click( object sender, EventArgs e )
		{
			m_bSinglePlayerMode = false;

			SwitchMenus( m_cMENU_MAIN,m_cMENU_NETUSERSELECT,true );
			StartNetUserSelectForm( false );
		}
		private void cmdMainMenuOptions_Click( object sender, EventArgs e )
		{
			m_bLaunchedOptionsMenuFromMainMenu = true;

			SwitchMenus( m_cMENU_MAIN,m_cMENU_OPTIONSMENU,true );
			StartOptionsForm( false );
		}
		private void cmdMainMenuMapEditor_Click( object sender, EventArgs e )
		{
			SwitchMenus( m_cMENU_MAIN,"",true );

			if( m_bGameGOBIsLoaded == false )
			{
				m_nGameState = enumStates.LoadingGOBForMapEditor;
			}
			else
			{
				m_nGameState = enumStates.MapEditor;
				StartMapEditorForm( false );
			}
		}
		private void cmdExit_Click( object sender, EventArgs e )
		{
			this.Close();
		}


		private void StartNetUserSelectForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSEditBox oTextBox = null;
			DSButton oButton = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETUSERSELECT );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdCancelNetGame_Click );

				oButton = (DSButton)oForm.GetControl( "cmdOk" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdStartServiceProviderPick_Click );

				oTextBox	= (DSEditBox)oForm.GetControl( "txtPlayerName" );
				//oTextBox.Changed += new EventHandler( txtPlayerName_Changed );
			}
			else
			{
				oForm		= m_oGameEngine.Forms.GetForm( m_cMENU_NETUSERSELECT );
				oTextBox	= (DSEditBox)oForm.GetControl( "txtPlayerName" );
				oButton		= (DSButton)oForm.GetControl( "cmdOk" );

				//Now enter our default name
				oTextBox.Text = m_sUserName;
				//Can we use this name?
				oButton.Enabled = ( oTextBox.Text.Length > 0 );
			}
		}
		private void cmdCancelNetGame_Click( object sender, EventArgs e )
		{
			SwitchMenus( m_cMENU_NETUSERSELECT,m_cMENU_MAIN,false );
			StartMainForm( false );
		}
		private void txtPlayerName_Changed( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSEditBox oTextBox = null;
			DSButton oButton = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETUSERSELECT );
			oTextBox	= (DSEditBox)oForm.GetControl( "txtPlayerName" );
			oButton		= (DSButton)oForm.GetControl( "cmdOk" );

			//Can we use this name?
			oButton.Enabled = ( oTextBox.Text.Length > 0 );
		}		
		private void cmdStartServiceProviderPick_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETUSERSELECT );
			m_sUserName = ((DSEditBox)oForm.GetControl( "txtPlayerName" )).Text;
			SaveINIFile();

			SwitchMenus( m_cMENU_NETUSERSELECT,m_cMENU_NETSRVPROVSELECT,true );
			StartNetServiceProviderPickForm( false );
		}


		private void StartNetServiceProviderPickForm( bool bInitEvents )
		{
			int nCurIndex = 0;
			DSForm oForm = null;
			DSButton oButton = null;
			DSListBox oListBox = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETSRVPROVSELECT );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCancelServProvSelect_Click );

				oButton = (DSButton)oForm.GetControl( "cmdOk" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdStartHostClientSelect_Click );

				oListBox = (DSListBox)oForm.GetControl( "lstServices" );
				oListBox.Selection += new EventHandler( this.lstServices_Selection );
			}
			else
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETSRVPROVSELECT );

				if( m_bHaveInitedMenuNetwork == false )
				{
					oListBox = (DSListBox)oForm.GetControl( "lstServices" );

					//Now go through and show all the services available
					if( m_oGameEngine.DirectPlay.Initialize( m_oAppGUID,false ) == true )
					{
						m_bHaveInitedMenuNetwork = true;
						oListBox.Clear();
						nCurIndex = 0;
						foreach( ServiceProviderInformation oSPInfo in m_oGameEngine.DirectPlay.GetServiceProviders() )
						{
							oListBox.AddItem( oSPInfo.ToString(),oSPInfo.Guid.ToString() );

							if( oSPInfo.Guid.ToString() == m_sServiceProviderGUID )
							{
								oListBox.SelectItem( nCurIndex );
							}

							nCurIndex++;
						}
					}
					//This means we were unable to init the network
					else
					{
						//Throw an error here since the network woulden't start...
						throw new System.Exception( "Failed to initialize network" );
					}
				}
			}
		}
		private void cmdCancelServProvSelect_Click( object sender, EventArgs e )
		{
			SwitchMenus( m_cMENU_NETSRVPROVSELECT,m_cMENU_MAIN,false );
			StartMainForm( false );
		}
		private void cmdStartHostClientSelect_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSListBox oListBox = null;
			string sServProvGUID = "";


			//Get our list box
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETSRVPROVSELECT );
			oListBox = (DSListBox)oForm.GetControl( "lstServices" );
			sServProvGUID = (string)oListBox.GetSelectedItem().ItemData;
			//Now get our service provider
			m_oServiceProviderForNetGame = m_oGameEngine.DirectPlay.FindServiceProvider( sServProvGUID );

			m_sServiceProviderGUID = sServProvGUID;
			SaveINIFile();

			//Ok launch the next menu
			SwitchMenus( m_cMENU_NETSRVPROVSELECT,m_cMENU_NETHOSTCLIENT,true );
			StartNetHostClientForm( false );
		}

		private void lstServices_Selection(object sender, EventArgs e)
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETSRVPROVSELECT );
			oButton = (DSButton)oForm.GetControl( "cmdOk" );
			oListBox = (DSListBox)oForm.GetControl( "lstServices" );

			oButton.Enabled = ( oListBox.GetSelectedIndex() != -1 );
		}

		
		private void StartNetHostClientForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oEditBox = null;
			DSListBox oListBox = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCancelHostClient_Click );

				oButton = (DSButton)oForm.GetControl( "cmdCreateGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCreateGame_Click );			

				oButton = (DSButton)oForm.GetControl( "cmdJoinGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdJoinGame_Click );						
	
				oEditBox = (DSEditBox)oForm.GetControl( "txtIP" );
				oEditBox.Changed += new EventHandler( this.txtIP_Changed );

				oButton = (DSButton)oForm.GetControl( "cmdSearch" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdSearchForGame_Click );

				oListBox = (DSListBox)oForm.GetControl( "lstGames" );
				oListBox.Selection += new EventHandler( this.lstGames_Selection );
			}
			else
			{
				oForm		= m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );

				oEditBox = (DSEditBox)oForm.GetControl( "txtIP" );
				//Setup our default IP
				oEditBox.Text = m_sIP;

				oButton = (DSButton)oForm.GetControl( "cmdSearch" );
				oButton.Enabled = ( oEditBox.Text.Length > 0 );
				((DSButton)oForm.GetControl( "cmdSearch" )).Label = "Search";
				m_oGameEngine.DirectPlay.CancelGameSearch();

				oListBox = (DSListBox)oForm.GetControl( "lstGames" );
				oListBox.Clear();
			}
		}
		private void cmdCancelHostClient_Click( object sender, EventArgs e )
		{
			m_oGameEngine.DirectPlay.CancelGameSearch();

			SwitchMenus( m_cMENU_NETHOSTCLIENT,m_cMENU_MAIN,false );
			StartMainForm( false );
		}
		private void cmdSearchForGame_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;


			//Find our menu first.
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );

			//Are we searching for a game already?
			if( m_oGameEngine.DirectPlay.SearchingForGames == false )
			{
				m_sIP = ((DSEditBox)oForm.GetControl( "txtIP" )).Text;
				m_oGameEngine.DirectPlay.SearchFormGames( m_oServiceProviderForNetGame,m_oAppGUID,m_sIP,m_cPORT );
 
				SaveINIFile();
				((DSButton)oForm.GetControl( "cmdSearch" )).Label = "Stop Searching...";
			}
			else
			{
				((DSButton)oForm.GetControl( "cmdSearch" )).Label = "Search";
				m_oGameEngine.DirectPlay.CancelGameSearch();
			}
		}
		private void txtIP_Changed( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oEditBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );
			oEditBox = (DSEditBox)oForm.GetControl( "txtIP" );

			oButton = (DSButton)oForm.GetControl( "cmdSearch" );
			oButton.Enabled = ( oEditBox.Text.Length > 0 );
		}
		private void cmdJoinGame_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSListBox oListBox = null;
			FindHostsResponseInformation oGame;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );
			oListBox = (DSListBox)oForm.GetControl( "lstGames" );
			oGame = ((FindHostsResponseInformation)oListBox.GetSelectedItem().ItemData );

			SwitchMenus( m_cMENU_NETHOSTCLIENT,"",true );
			StartWaitingToConnectForm( false );

			//Start the connection
			m_oGameEngine.DirectPlay.JoinGame( oGame,m_sUserName );
		}
		private void cmdCreateGame_Click( object sender, EventArgs e )
		{
			SwitchMenus( m_cMENU_NETHOSTCLIENT,m_cMENU_NETGAMEHOST,true );
			StartNetGameCreationForm( false );
		}		

		private void lstGames_Selection( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSListBox oListBox = null;

			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETHOSTCLIENT );
			oButton = (DSButton)oForm.GetControl( "cmdJoinGame" );
			oListBox = (DSListBox)oForm.GetControl( "lstGames" );

			oButton.Enabled = ( oListBox.GetSelectedIndex() != -1 );
		}		


		private void StartNetGameCreationForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oTextBox = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETGAMEHOST );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCancelHostGame_Click );

				oButton = (DSButton)oForm.GetControl( "cmdCreateGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdHostGame_Click );

				oTextBox = (DSEditBox)oForm.GetControl( "txtSessionName" );
				oTextBox.Changed += new EventHandler(txtSessionName_Changed);
			}
			else
			{
				oForm		= m_oGameEngine.Forms.GetForm( m_cMENU_NETGAMEHOST );
				oTextBox = (DSEditBox)oForm.GetControl( "txtSessionName" );
				oButton = (DSButton)oForm.GetControl( "cmdCreateGame" );

				//Set our default game name
				oTextBox.Text = m_sGameName;
				//Can we use this name?
				oButton.Enabled = ( oTextBox.Text.Length > 0 );
			}
		}
		private void cmdHostGame_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSListBox oListBox = null;


			//Find our menu first.
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETGAMEHOST );
			m_sGameName = ((DSEditBox)oForm.GetControl( "txtSessionName" ) ).Text;

			//Clear our list of players.  THis has to be done before otherwise we clear out ourselves.
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );
			oListBox.Clear();

			m_oGameEngine.DirectPlay.HostGame( m_oServiceProviderForNetGame,m_oAppGUID,m_sGameName,m_sUserName,m_cPORT );

			SwitchMenus( m_cMENU_NETGAMEHOST,m_cMENU_NETLOBBY,true );
			StartLobbyForm( false );
		}

		private void txtSessionName_Changed( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oTextBox = null;


			//Find our menu first.
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETGAMEHOST );
			oTextBox = (DSEditBox)oForm.GetControl( "txtSessionName" );
			oButton = (DSButton)oForm.GetControl( "cmdCreateGame" );

			oButton.Enabled = ( oTextBox.Text.Length > 0 );
		}
		private void cmdCancelHostGame_Click( object sender, EventArgs e )
		{
			SwitchMenus( m_cMENU_NETGAMEHOST,m_cMENU_MAIN,false );
			StartMainForm( false );
		}


		private void StartWaitingToConnectForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_WAITINGTOCONNECT );

			if( bInitEvents == true )
			{
				//oForm = m_oGameEngine.Forms.GetForm( m_cMENU_WAITINGTOCONNECT );

				oButton = (DSButton)oForm.GetControl( "cmdCancelConnect" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCancelConnecting_Click );
			}
			else
			{
				m_oGameEngine.Forms.Show( m_cMENU_WAITINGTOCONNECT,false );
			}
		}
		private void cmdCancelConnecting_Click( object sender, EventArgs e )
		{
			m_oGameEngine.DirectPlay.CancelGameJoin();
			SwitchMenus( m_cMENU_WAITINGTOCONNECT,m_cMENU_MAIN,false );
			StartNetHostClientForm( false );
		}


		private void StartLobbyForm( bool bInitEvents )
		{
			DSCheckBox oCheckBox = null;
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oEditBox = null;
			DSListBox oAIListBox = null;
			DSListBox oListBox = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCancelLobby_Click );

				oButton = (DSButton)oForm.GetControl( "cmdSend" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdSendMessage_Click );

				oButton = (DSButton)oForm.GetControl( "cmdKick" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdKickPlayer_Click );

				oButton = (DSButton)oForm.GetControl( "cmdAddComputer" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdAddComputer_Click );

				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oEditBox.Changed += new EventHandler( this.txtMessage_Changed );
				oEditBox.Enter += new EventHandler( this.txtMessage_EnterClicked );

				oButton = (DSButton)oForm.GetControl( "cmdBrowse" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdBrowseMultiMaps_Click );

				oButton = (DSButton)oForm.GetControl( "cmdStartGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdStartGame_Click );

				oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );
				oEditBox.Changed += new EventHandler( this.txtMessage_Changed );

				oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );
				oListBox.Selection += new EventHandler( lstPlayerListBox_Selection );

				oCheckBox = (DSCheckBox)oForm.GetControl( "chkDestroyedBuildingsRot" );
				oCheckBox.Changed += new EventHandler( this.chkLobbyDestroyedBuildingsRot_Changed );
			}
			else
			{
				m_bReceivedGameStart = false;

				m_oAIsToAdd = new DSSortedList();

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );

				oButton = (DSButton)oForm.GetControl( "cmdSend" );
				oButton.Enabled = false;

				oButton = (DSButton)oForm.GetControl( "cmdKick" );
				oButton.Visible = m_oGameEngine.DirectPlay.IAmTheHost;
				oButton.Enabled = false;

				oButton = (DSButton)oForm.GetControl( "cmdAddComputer" );
				oButton.Visible = m_oGameEngine.DirectPlay.IAmTheHost;

				oButton = (DSButton)oForm.GetControl( "cmdBrowse" );
				oButton.Enabled = m_oGameEngine.DirectPlay.IAmTheHost;

				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oEditBox.SetFocus();

				oCheckBox = (DSCheckBox)oForm.GetControl( "chkDestroyedBuildingsRot" );
				oCheckBox.Enabled = m_oGameEngine.DirectPlay.IAmTheHost;
				oCheckBox.IsChecked = true;

				oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );
				if( m_oGameEngine.DirectPlay.IAmTheHost == false )
				{					
					oEditBox.Text = "";
				}
				else
				{
					oEditBox.Text = m_sLastMultiMapUsed;
					SendLobbyMapFile();

					oButton = (DSButton)oForm.GetControl( "cmdStartGame" );
					oButton.Enabled = ( m_sLastMultiMapUsed.Length > 0 );
				}

				oAIListBox = (DSListBox)oForm.GetControl( "lstAIAddList" );
				if( oAIListBox != null )
				{
					oForm.RemoveControl( oAIListBox.Name );
				}

				//We can't start the game if we aren't ready
				oButton = (DSButton)oForm.GetControl( "cmdStartGame" );
				oButton.Visible = m_oGameEngine.DirectPlay.IAmTheHost;
				UpdatePreGameStatus();
			}
		}
		private void chkLobbyDestroyedBuildingsRot_Changed( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSCheckBox oCheckBox = null;

			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oCheckBox = (DSCheckBox)oForm.GetControl( "chkDestroyedBuildingsRot" );

			SendMMMsg( enumNetMsg.LobbyBuildingRotChecked,oCheckBox.IsChecked.ToString() );
		}
		private void cmdCancelLobby_Click( object sender, EventArgs e )
		{
			m_oGameEngine.DirectPlay.Peer.TerminateSession( null );
			SwitchMenus( m_cMENU_NETLOBBY,m_cMENU_MAIN,false );
			StartMainForm( false );
		}

		private void cmdStartGame_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSEditBox oEditBox = null;
			DSCheckBox oCheckBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oCheckBox = (DSCheckBox)oForm.GetControl( "chkDestroyedBuildingsRot" );
			oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );

			if( DSMisc.FileExists( oEditBox.Text ) == false )
			{
				MessageBox.Show( "Unable to find the map specified.  Please pick another map." );
			}
			else
			{
				SwitchMenus( "",m_cMENU_NETLOBBY,true );
				GameHasStarted_Host( oEditBox.Text,oCheckBox.IsChecked );
			}
		}
		private void cmdSendMessage_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSEditBox oEditBox = null;
			DSButton oButton = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
			oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
			oButton = (DSButton)oForm.GetControl( "cmdSend" );
				
			if( oEditBox.Text.Length > 0 )
			{
				SendMMMsg( enumNetMsg.LobbyMessage,m_sUserName,oEditBox.Text );

				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TYPING );

				oListBox.AddItem( m_sUserName + ": " + oEditBox.Text,null );
				oListBox.SelectItem( oListBox.GetItemCount()-1 );

				oEditBox.Text = "";
				oButton.Enabled = false;
			}
		}
		private void cmdKickPlayer_Click( object sender, EventArgs e )
		{
			ListBoxItem oListBoxItem;
			DSButton oButton = null;
			DSForm oForm = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );			
			oListBoxItem = oListBox.GetSelectedItem();

			oButton = (DSButton)oForm.GetControl( "cmdKick" );
			oButton.Enabled = false;

			m_oAIsToAdd.Remove( oListBoxItem.ItemText );


			UpdatePreGameStatus();
			SendAIList();
		}
		private void lstPlayerListBox_Selection( object sender, EventArgs e )
		{
			ListBoxItem oListBoxItem;
			DSButton oButton = null;
			DSForm oForm = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );			
			oButton = (DSButton)oForm.GetControl( "cmdKick" );

			oListBoxItem = oListBox.GetSelectedItem();
			oButton.Enabled = ( oListBoxItem.ItemData.GetType() == typeof( enumAILevels ) );
		}
		private void cmdAddComputer_Click( object sender, EventArgs e )
		{
			DSButton oButton = null;
			DSForm oForm = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oButton = (DSButton)oForm.GetControl( "cmdAddComputer" );

			oButton.Visible = false;

			//Add the difficulty box
			oListBox = oForm.AddControl_ListBox( "lstAIAddList",oButton.Location,new Vector2( 150,100 ),
												DarkStrideToolbox.ListBoxStyle.SingleSelection );
			oListBox.Visible = true;
			oListBox.AddItem( enumAILevels.Obscene.ToString(),null );
			oListBox.AddItem( enumAILevels.Hard.ToString(),null );
			oListBox.AddItem( enumAILevels.Average.ToString(),null );
			oListBox.AddItem( enumAILevels.Neophite.ToString(),null );
			oListBox.AddItem( enumAILevels.Noob.ToString(),null );
			oListBox.AddItem( "<Cancel>",null );
			oListBox.Selection += new EventHandler( AILevelBox_Changed );
		}
		private void cmdBrowseMultiMaps_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSEditBox oEditBox = null;
			System.Windows.Forms.OpenFileDialog oFileDialog = null;


			//Display the OpenFileName dialog. Then, try to load the specified file
			oFileDialog = new OpenFileDialog();

			oFileDialog.Filter = "Islands (*.MMI)|*.MMI";
			oFileDialog.FileName = "*.MMI";
			oFileDialog.InitialDirectory = Environment.CurrentDirectory + @"\Maps\Multiplayer";
			oFileDialog.Title = "Load Map";
			oFileDialog.CheckFileExists = true;
			oFileDialog.Multiselect = false;
			oFileDialog.ShowReadOnly = false;

			if( oFileDialog.ShowDialog() == DialogResult.OK )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
				oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );
				oEditBox.Text = oFileDialog.FileName;

				UpdatePreGameStatus();
				SendLobbyMapFile();

				m_sLastMultiMapUsed = oFileDialog.FileName;
				SaveINIFile();
			}
		}
		private void txtMessage_Changed( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oEditBox = null;

			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );

			oButton = (DSButton)oForm.GetControl( "cmdSend" );
			oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );

			oButton.Enabled = ( oEditBox.Text.Length > 0 );
		}
		private void txtMessage_EnterClicked( object sender, EventArgs e )
		{
			cmdSendMessage_Click( null,null );
		}

		private void UpdatePreGameStatus()
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSNetworkPlayer oNetPlayer = null;
			DSListBox oListBox = null;
			DSEditBox oEditBox = null;
			string sName = "";
			bool bReady = true;
			bool bTempReady = false;


			//Repopulate the list of players while we are at it
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oListBox = (DSListBox)oForm.GetControl( "lstPlayers" );
			oListBox.Clear();


			//First find out if all the players are ready
			lock( m_oGameEngine.DirectPlay.Players )
			{
				for( int nNetPlayerIndex=0 ; nNetPlayerIndex<m_oGameEngine.DirectPlay.Players.Count ; nNetPlayerIndex++ )
				{
					oNetPlayer = (DSNetworkPlayer)m_oGameEngine.DirectPlay.Players.GetByIndex( nNetPlayerIndex );
				
					//First of all, are we ready?
					bTempReady = false;
					if( oNetPlayer.IsMe == true && m_bGameGOBIsLoaded == true )
					{
						bTempReady = true;
					}
					else if( m_oPreGamePlayerStatus.ContainsKey( oNetPlayer.SocketID.ToString() ) == true )
					{
						bTempReady = (bool)m_oPreGamePlayerStatus.GetByKey( oNetPlayer.SocketID.ToString() );
					}
					if( bTempReady == false )
					{
						bReady = false;
					}

					//Now add the name to the list
					sName = oNetPlayer.Name;
					if( oNetPlayer.IAmHost == true )
					{
						sName += " (Host)";
					}
					if( bTempReady == false && m_oGameEngine.DirectPlay.Me.IAmHost == true )
					{
						sName += " (Loading)";
					}
					oListBox.AddItem( sName,oNetPlayer.SocketID.ToString() );
				}

				//Add in the new AIs
				for( int i=0 ; i<m_oAIsToAdd.Count ; i++ )
				{
					oListBox.AddItem( (string)m_oAIsToAdd.GetKey( i ),
						(enumAILevels)m_oAIsToAdd.GetByIndex( i ) );
				}
			}


			//Update the button
			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oEditBox = (DSEditBox)oForm.GetControl( "txtMap" );
			oButton = (DSButton)oForm.GetControl( "cmdStartGame" );

			oButton.Enabled = ( bReady == true && oEditBox.Text.Length > 0 );
		}

		private void AILevelBox_Changed( object sender, EventArgs e )
		{
			DSButton oButton = null;
			DSListBox oAIListBox = null;
			DSListBox oPlayersListBox = null;
			DSForm oForm = null;
			enumAILevels nAILevel = enumAILevels.Noob;
			bool bAddAI = true;
			string sName = "";
			ListBoxItem oListBoxItem;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			oAIListBox = (DSListBox)oForm.GetControl( "lstAIAddList" );

			if( oAIListBox != null )
			{
				oPlayersListBox = (DSListBox)oForm.GetControl( "lstPlayers" );
				oButton = (DSButton)oForm.GetControl( "cmdAddComputer" );
			
				oListBoxItem = oAIListBox.GetSelectedItem();
				if( oListBoxItem.ItemText == enumAILevels.Noob.ToString() )
				{
					nAILevel = enumAILevels.Noob;				
				}
				else if( oListBoxItem.ItemText == enumAILevels.Neophite.ToString() )
				{
					nAILevel = enumAILevels.Neophite;				
				}
				else if( oListBoxItem.ItemText == enumAILevels.Average.ToString() )
				{
					nAILevel = enumAILevels.Average;				
				}
				else if( oListBoxItem.ItemText == enumAILevels.Hard.ToString() )
				{
					nAILevel = enumAILevels.Hard;				
				}
				else if( oListBoxItem.ItemText == enumAILevels.Obscene.ToString() )
				{
					nAILevel = enumAILevels.Obscene;
				}
				else
				{
					bAddAI = false;
				}

				if( bAddAI == true )
				{
					sName = nAILevel.ToString() + " A.I. (#" + ( m_oAIsToAdd.Count + 1 ).ToString() + ")";
					m_oAIsToAdd.Add( sName,nAILevel );

					//Send a network message to anyone else who is connected
					SendAIList();
					UpdatePreGameStatus();
				}

				oButton.Visible = true;
				oForm.RemoveControl( oAIListBox.Name );
			}
		}


		private void StartResumeForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_RESUMEMENU );

				oButton = (DSButton)oForm.GetControl( "cmdExit" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdExitResume_Click );

				oButton = (DSButton)oForm.GetControl( "cmdOptions" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdResumeOptions_Click );

				oButton = (DSButton)oForm.GetControl( "cmdResume" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdResume_Click );

				oButton = (DSButton)oForm.GetControl( "cmdSaveGame" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdSaveGame_Click );
			}
			else
			{
				m_nGameState = enumStates.ResumeMenu;
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_RESUMEMENU );
				oForm.IsModal = true;

				oButton = (DSButton)oForm.GetControl( "cmdSaveGame" );
				oButton.Enabled = ( m_bSinglePlayerMode == true );				
			}
		}
		private void cmdExitResume_Click( object sender, EventArgs e )
		{
			m_nGameState = enumStates.MainMenu;
			if( m_oGameEngine.DirectPlay.Peer != null )
			{
				m_oGameEngine.DirectPlay.Peer.TerminateSession( null );
			}

			HideAllInGameMenus();
			m_oGame = null;
			SwitchMenus( m_cMENU_RESUMEMENU,m_cMENU_MAIN,false );
			StartMainForm( false );
		}
		private void cmdResume_Click( object sender, EventArgs e )
		{
			m_nGameState = enumStates.InGame;
			SwitchMenus( m_cMENU_RESUMEMENU,"",false );
		}

		private void cmdResumeOptions_Click( object sender, EventArgs e )
		{
			m_bLaunchedOptionsMenuFromMainMenu = false;

			SwitchMenus( m_cMENU_RESUMEMENU,m_cMENU_OPTIONSMENU,true );
			StartOptionsForm( false );
		}

		private void cmdSaveGame_Click( object sender, EventArgs e )
		{
			System.Windows.Forms.SaveFileDialog oFileDialog = null;
			StreamWriter oStream = null;


			oFileDialog = new SaveFileDialog();
			oFileDialog.Filter = "MM Saved Game (*.MMS)|*.MMS";
			oFileDialog.FileName = "MM Save Game - " + 
								   "Level " + Game.CurrentSinglePlayerLevelID.ToString() + " - " + 
									DateTime.Now.ToString( "yyyyMMdd hhss" ) + 
									".MMS";
			oFileDialog.InitialDirectory = Environment.CurrentDirectory + @"\Saves";
			oFileDialog.Title = "Save Game";


			if( oFileDialog.ShowDialog() == DialogResult.OK )
			{
				oStream = new StreamWriter( oFileDialog.FileName,false );
				oStream.Write( m_cMMSAVEDGAMEHEADER );
				oStream.Write( "\n" + Game.CurrentSinglePlayerLevelID.ToString() );
				oStream.Close();

				MessageBox.Show( "Game Saved" );
			}
		}


		private void StartOptionsForm( bool bInitEvents )
		{
			DSSlider oSlider = null;
			DSForm oForm = null;
			DSCheckBox oCheckBox = null;
			DSButton oButton = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_OPTIONSMENU );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdOptionsCancel_Click );

				oButton = (DSButton)oForm.GetControl( "cmdApply" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdOptionsApply_Click );

				oSlider = (DSSlider)oForm.GetControl( "sldVolume" );
				oSlider.ValueChanged += new EventHandler( sldSlider_ValueChanged );
			}
			else
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_OPTIONSMENU );

				oCheckBox = (DSCheckBox)oForm.GetControl( "chkMute" );
				oCheckBox.IsChecked = ( m_oGameEngine.DirectSound.Muted == true );

				oSlider = (DSSlider)oForm.GetControl( "sldVolume" );
				oSlider.Value = 0;
				oSlider.SetRange( 80,100 );
				oSlider.Value = (int)(m_oGameEngine.DirectSound.Volume*100);
			}
		}
		private void cmdOptionsCancel_Click( object sender, EventArgs e )
		{
			if( m_bLaunchedOptionsMenuFromMainMenu == true )
			{
				SwitchMenus( m_cMENU_OPTIONSMENU,m_cMENU_MAIN,false );
				StartMainForm( false );
			}
			else
			{
				SwitchMenus( m_cMENU_OPTIONSMENU,m_cMENU_RESUMEMENU,false );
				m_nGameState = enumStates.InGame;
			}
		}
		private void cmdOptionsApply_Click( object sender, EventArgs e )
		{
			DSSlider oSlider = null;
			DSForm oForm = null;
			DSCheckBox oCheckBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_OPTIONSMENU );

			oCheckBox = (DSCheckBox)oForm.GetControl( "chkMute" );
			m_oGameEngine.DirectSound.Muted = oCheckBox.IsChecked;

			oSlider = (DSSlider)oForm.GetControl( "sldVolume" );
			m_oGameEngine.DirectSound.Volume = (double)oSlider.Value / 100.0;

			SaveINIFile();

			if( m_bLaunchedOptionsMenuFromMainMenu == true )
			{
				SwitchMenus( m_cMENU_OPTIONSMENU,m_cMENU_MAIN,false );
				StartMainForm( false );
			}
			else
			{
				SwitchMenus( m_cMENU_OPTIONSMENU,"",false );
				m_nGameState = enumStates.InGame;
			}
		}
		
		private void sldSlider_ValueChanged( object sender, EventArgs e )
		{
			TimeSpan oSpan = TimeSpan.MinValue;
			DSSlider oSlider = null;
			DSForm oForm = null;


			oSpan = DateTime.Now - m_dtTimeSinceLastVolumeChangeClick;
			if( oSpan.TotalSeconds > .1 )
			{
				m_dtTimeSinceLastVolumeChangeClick = DateTime.Now;

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_OPTIONSMENU );

				oSlider = (DSSlider)oForm.GetControl( "sldVolume" );
				m_oGameEngine.DirectSound.Volume = (double)oSlider.Value / 100.0;

				cmdAll_Click( null,null );
			}
		}
		
		
		private void StartTypingForm( bool bInitEvents )
		{
			DSEditBox oEditBox = null;
			DSForm oForm = null;
			DSButton oButton = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING );

				oButton = (DSButton)oForm.GetControl( "cmdClose" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdCloseTyping_Click );

				oButton = (DSButton)oForm.GetControl( "cmdSend" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdSend_Click );

				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oEditBox.Enter += new EventHandler( this.txtInGameTypingMessage_EnterClicked );
				oEditBox.Esc += new EventHandler( this.txtInGameTypingMessage_EscClicked );
			}
			else
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING );
				oForm.Visible = true;

				//Set the default position for the chat form
				if( m_vChatPos.X != 0 || m_vChatPos.Y != 0 )
				{
					oForm.Location = new Point( (int)m_vChatPos.X,(int)m_vChatPos.Y );
				}

				oForm.SetFocus();
				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oEditBox.SetFocus();				
			}
		}
		private void cmdCloseTyping_Click( object sender, EventArgs e )
		{
			m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING ).Visible = false;
		}
		private void cmdSend_Click( object sender, EventArgs e )
		{
			string sMessage = "";
			DSForm oForm = null;
			DSEditBox oEditBox = null;
			DSListBox oListBox = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_NETLOBBY );
			if( oForm != null )
			{
				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
			}

			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_INGAMETYPING );
			if( oForm != null )
			{
				oEditBox = (DSEditBox)oForm.GetControl( "txtMessage" );
				oListBox = (DSListBox)oForm.GetControl( "lstMessages" );
			}

			if( oEditBox.Text.Length > 0 )
			{
				SendMMMsg( enumNetMsg.LobbyMessage,m_sUserName,oEditBox.Text );

				//Now, was this a cheat code?
				if( ProcessCheatCode( oEditBox.Text,false,out sMessage ) == false )
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_TYPING );
					sMessage = m_sUserName + ": " + oEditBox.Text;
				}
				else
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CHEATING );
					sMessage += " (" + m_sUserName + ")";
				}

				oListBox.AddItem( sMessage,null );
				oListBox.SelectItem( oListBox.GetItemCount()-1 );
				oEditBox.Text = "";
			}
		}

		private void txtInGameTypingMessage_EnterClicked( object sender, EventArgs e )
		{
			cmdSend_Click( null,null );
		}

		private void txtInGameTypingMessage_EscClicked( object sender, EventArgs e )
		{
			cmdCloseTyping_Click( null,null );
		}


		public void StartCreateTeamForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSEditBox oTextBox = null;


			if( bInitEvents == true )
			{
				//Check to see if there is already a create team window open first
				oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_CREATETEAM );
				oForm.RenderPreEvent += new EventHandler( CreateTeamForm_Render );

				//Link to our button events
				oButton = (DSButton)oForm.GetControl( "cmdCreate" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdCreateTeam_Click );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdCancelCreateTeam_Click );
			}
			else
			{
				oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_CREATETEAM );

				//Setup our defaults
				oTextBox = (DSEditBox)oForm.GetControl( "txtTeamName" );
				oTextBox.Text = m_oGameEngine.DirectPlay.Me.Name + "'s Team";
			}
		}
		private void CreateTeamForm_Render( object sender, EventArgs e )
		{
			System.Drawing.Rectangle oDrawRect;
			DSForm oForm = null;


			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_CREATETEAM );

			//Draw the black rendering area
			oDrawRect = new Rectangle( (int)(oForm.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
				(int)(oForm.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
				(int)(oForm.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
				(int)(oForm.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
			oForm.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 

			oForm.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
				Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
				Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
		}
		private void cmdCreateTeam_Click( object sender, EventArgs e )
		{
			Island oIsland = GetMyIsland().Island;
			MMTeamForm oTeamForm = null;
			DSForm oForm = null;
			DSEditBox oTextBox = null;
			DSCheckBox oCheckBox = null;
			TeamSetup oNewTeam = new TeamSetup();


			//Ok now hide the form and update everyone with our new team
			oForm = m_oGameEngine.Forms.Show( Game.m_cFRM_CREATETEAM,false );
            
			//Save our team info
			oTextBox = (DSEditBox)oForm.GetControl( "txtFuelPerMinute" );
			oNewTeam.MinFuelSharedPerMinute = 0;
			if( DSMisc.IsNumericLong( oTextBox.Text ) == true )
			{
				oNewTeam.MinFuelSharedPerMinute = Convert.ToInt64( oTextBox.Text );
			}

			oTextBox = (DSEditBox)oForm.GetControl( "txtGoldPerMinute" );
			oNewTeam.MinCreditsSharedPerMinute = 0;
			if( DSMisc.IsNumericLong( oTextBox.Text ) == true )
			{
				oNewTeam.MinCreditsSharedPerMinute = Convert.ToInt64( oTextBox.Text );
			}

			oCheckBox = (DSCheckBox)oForm.GetControl( "chkMutualTeamQuits" );
			oNewTeam.MutualTeamDeparturesRequired = oCheckBox.IsChecked;

			oCheckBox = (DSCheckBox)oForm.GetControl( "chkSharedVision" );
			oNewTeam.SharedVision = oCheckBox.IsChecked;

			oTextBox = (DSEditBox)oForm.GetControl( "txtTeamName" );
			oNewTeam.Name = oTextBox.Text;

			oIsland.GlobalIDOfPlayerWhoseTeamImOn = "";
			oIsland.TeamJoinApproved = true;

			//Make sure we meat our own teams minimums
			if( oNewTeam.MinCreditsSharedPerMinute > oIsland.CreditsSharedPerMinute )
			{
				oIsland.CreditsSharedPerMinute = oNewTeam.MinCreditsSharedPerMinute;
			}
			if( oNewTeam.MinFuelSharedPerMinute > oIsland.FuelSharedPerMinute )
			{
				oIsland.FuelSharedPerMinute = oNewTeam.MinFuelSharedPerMinute;
			}


			//Send the update
			GetMyIsland().Island.TeamSetup = oNewTeam;
			SendIslandUpdate( GetMyIsland().Island );

			//Then update the team screen if its still open
			oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
			if( oTeamForm != null )
			{
				oTextBox = (DSEditBox)oTeamForm.GetControl( "txtSharedGold" );
				oTextBox.Text = oIsland.CreditsSharedPerMinute.ToString();

				oTextBox = (DSEditBox)oTeamForm.GetControl( "txtSharedFuel" );
				oTextBox.Text = oIsland.FuelSharedPerMinute.ToString();
			}

			SwitchMenus( Game.m_cFRM_CREATETEAM,Game.m_cFRM_TEAMDERIVED,false );
		}
		private void cmdCancelCreateTeam_Click( object sender, EventArgs e )
		{
			SwitchMenus( Game.m_cFRM_CREATETEAM,Game.m_cFRM_TEAMDERIVED,false );
		}


		public void StartGiveResourcesForm( bool bInitEvents,Island oGiveResTo )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			DSSlider oSlider = null;
			DSLabel oLabel = null;
			long nTemp = 0;


			m_oGiveResSelectedIsland = oGiveResTo;

			if( bInitEvents == true )
			{
				//Check to see if there is already a create team window open first
				oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_GIVERES );
				oForm.RenderPreEvent += new EventHandler( CreateGiveResForm_Render );

				//Link to our button events
				oButton = (DSButton)oForm.GetControl( "cmdGive" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdGiveRes_Click );

				oButton = (DSButton)oForm.GetControl( "cmdCancel" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdCancelGiveRes_Click );

				oLabel = (DSLabel)oForm.GetControl( "lblFuelToGive" );
				oLabel.Label = "Fuel To Give: 0";

				oLabel = (DSLabel)oForm.GetControl( "lblCreditsToGive" );
				oLabel.Label = "Credits To Give: 0";
			}
			else
			{
				oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_GIVERES );

				//Setup our defaults
				oSlider = (DSSlider)oForm.GetControl( "sldGoldToGive" );
				oSlider.SetRange( 0,(int)GetMyIsland().Island.Credits );
				oSlider.Value = 0;

				oSlider = (DSSlider)oForm.GetControl( "sldFuelToGive" );
				oSlider.SetRange( 0,(int)GetMyIsland().Island.Fuel );
				oSlider.Value = 0;

				//Set the labels
				oLabel = (DSLabel)oForm.GetControl( "lblMaxFuel" );
				nTemp = (long)GetMyIsland().Island.Fuel;
				oLabel.Label = nTemp.ToString();

				oLabel = (DSLabel)oForm.GetControl( "lblMaxCredits" );
				nTemp = (long)GetMyIsland().Island.Credits;
				oLabel.Label = nTemp.ToString();
			}
		}
		private void CreateGiveResForm_Render( object sender, EventArgs e )
		{
			System.Drawing.Rectangle oDrawRect;
			DSForm oForm = null;
			DSLabel oLabel = null;
			DSSlider oSlider = null;


			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_GIVERES );

			//Draw the black rendering area
			oDrawRect = new Rectangle( (int)(oForm.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
				(int)(oForm.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
				(int)(oForm.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
				(int)(oForm.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
			oForm.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 

			oForm.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
				Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
				Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );


			//Set the controls descriptions
			oSlider = (DSSlider)oForm.GetControl( "sldGoldToGive" );
			oLabel = (DSLabel)oForm.GetControl( "lblCreditsToGive" );
			oLabel.Label = "Credits To Give: " + oSlider.Value.ToString();

			oSlider = (DSSlider)oForm.GetControl( "sldFuelToGive" );
			oLabel = (DSLabel)oForm.GetControl( "lblFuelToGive" );
			oLabel.Label = "Fuel To Give: " + oSlider.Value.ToString();

			//Find our team form and update our min specs to meet the minimum
		}
		private void cmdGiveRes_Click( object sender, EventArgs e )
		{
			DSSlider oSlider = null;
			DSForm oForm = null;
			TeamSetup oNewTeam = new TeamSetup();
			int nCredit = 0;
			int nFuel = 0;


			//Ok now hide the form and update everyone with our new team
			oForm = m_oGameEngine.Forms.GetForm( Game.m_cFRM_GIVERES );
			//oForm.Visible = false;
            
			//Give the resources
			oSlider = (DSSlider)oForm.GetControl( "sldGoldToGive" );
			nCredit = oSlider.Value;

			oSlider = (DSSlider)oForm.GetControl( "sldFuelToGive" );
			nFuel = oSlider.Value;


			//Can we aford that amount?
			if( nCredit > GetMyIsland().Island.Credits )
			{
				nCredit = (int)GetMyIsland().Island.Credits;
			}
			GetMyIsland().Island.Credits -= nCredit;

			if( nFuel > GetMyIsland().Island.Fuel )
			{
				nFuel = (int)GetMyIsland().Island.Fuel;
			}
			GetMyIsland().Island.Fuel -= nFuel;


			//Send the update to people
			SendMoneyUpdate( nCredit,nFuel,m_oGiveResSelectedIsland );

			StartTeamForm( false );
			SwitchMenus( Game.m_cFRM_GIVERES,Game.m_cFRM_TEAMDERIVED,false );
		}
		private void cmdCancelGiveRes_Click( object sender, EventArgs e )
		{
			StartTeamForm( false );
			SwitchMenus( Game.m_cFRM_GIVERES,Game.m_cFRM_TEAMDERIVED,false );
		}


		private void StartMapEditorForm( bool bInitEvents )
		{
			DSForm oForm = null;
			DSButton oButton = null;
			MMPurchaseForm oPurchaseForm = null;
			MMPlaceTerrainForm oTerrainForm = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORMAINMENU );

				oButton = (DSButton)oForm.GetControl( "cmdLoadIsland" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdMapEditLoadIsland_Click );

				oButton = (DSButton)oForm.GetControl( "cmdSaveIsland" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdMapEditSaveIsland_Click );

				oButton = (DSButton)oForm.GetControl( "cmdNewIsland" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdMapEditNewIsland_Click );

				oButton = (DSButton)oForm.GetControl( "cmdBuildings" );
				oButton.Click += new EventHandler( cmdAll_Click );
				//oButton.Click += new EventHandler( cmdOptionsCancel_Click );

				oButton = (DSButton)oForm.GetControl( "cmdTerrain" );
				oButton.Click += new EventHandler( cmdAll_Click );
				//oButton.Click += new EventHandler( cmdOptionsCancel_Click );

				oButton = (DSButton)oForm.GetControl( "cmdProperties" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditProperties_Click );

				oButton = (DSButton)oForm.GetControl( "cmdDone" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditDone_Click );

				oButton = (DSButton)oForm.GetControl( "cmdMoveLeft" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditMoveLeft );

				oButton = (DSButton)oForm.GetControl( "cmdMoveUp" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditMoveUp );

				oButton = (DSButton)oForm.GetControl( "cmdMoveRight" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditMoveRight );

				oButton = (DSButton)oForm.GetControl( "cmdMoveDown" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdMapEditMoveDown );
				
				oButton = (DSButton)oForm.GetControl( "cmdRotateLeft" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdRotateLeft );
				
				oButton = (DSButton)oForm.GetControl( "cmdRotateRight" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( cmdRotateRight );
			}
			else
			{
				CreateGameObject();

				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORMAINMENU );
				oForm.Location = new Point( 0,0 );

				//Open the purchase form
				oPurchaseForm = new MMPurchaseForm( null );
				oPurchaseForm.Name = Game.m_cFRM_PURCHASE;
				oPurchaseForm.App = this;
				oPurchaseForm.Size = new Vector2( 200,200 );
				oPurchaseForm.Location = new Point( (int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferWidth - oPurchaseForm.Size.X ),0 );
				m_oGameEngine.Forms.Add( oPurchaseForm );

				//Open the terrain form
				oTerrainForm = new MMPlaceTerrainForm( null );
				oTerrainForm.Name = Game.m_cFRM_TERRAIN;
				oTerrainForm.App = this;
				oTerrainForm.Size = new Vector2( 200,200 );
				oTerrainForm.Location = new Point( (int)( m_oGameEngine.Direct3DDevice.PresentationParameters.BackBufferWidth - oTerrainForm.Size.X ),214 );
				m_oGameEngine.Forms.Add( oTerrainForm );

				//Open the properties form
				StartMapEditorPropertiesForm( false );
			}
		}
		private void cmdMapEditLoadIsland_Click( object sender, EventArgs e )
		{
			System.Windows.Forms.OpenFileDialog oFileDialog = null;
			string sIsland = "";
			Island oIsland = null;
			MMIslandForm oIForm = null;


			//Display the OpenFileName dialog. Then, try to load the specified file
			oFileDialog = new OpenFileDialog();

			oFileDialog.Filter = "Islands (*.MMI)|*.MMI";
			oFileDialog.FileName = "*.MMI";
			oFileDialog.InitialDirectory = Environment.CurrentDirectory;
			oFileDialog.Title = "Load Island";
			oFileDialog.CheckFileExists = true;
			oFileDialog.Multiselect = false;
			oFileDialog.ShowReadOnly = false;

			if( oFileDialog.ShowDialog() == DialogResult.OK )
			{
				//Open the file they selected
				oIsland = new Island( m_oGame );
				sIsland = DSMisc.GetFile( oFileDialog.FileName );
				oIsland.DeSerialize( sIsland );

				//Pick a UniqueID
				m_nNextUniqueID++;
				//Create our island form
				oIForm = AttachNewIslandToMenu( oIsland,oFileDialog.FileName,Game.m_cEDITISLANDFORMNAME + m_nNextUniqueID.ToString(),null );
				oIForm.Size = new Vector2( (float)m_oGameEngine.ScreenWidth * .65f,(float)m_oGameEngine.ScreenHeight * .65f );
				oIForm.Location = new Point( 120 + ( (int)m_nNextUniqueID % 6 ) * 10,30 + ( (int)m_nNextUniqueID % 6 ) * 10 );
			}
		}
		
		private void cmdMapEditNewIsland_Click( object sender, EventArgs e )
		{
			Island oIsland = null;
			MMIslandForm oIForm = null;

			//Create a new island
			oIsland = new Island( m_oGame );
			//Pick a UniqueID
			m_nNextUniqueID++;
			//Create our island form
			oIForm = AttachNewIslandToMenu( oIsland,"New " + m_nNextUniqueID.ToString(),Game.m_cEDITISLANDFORMNAME + m_nNextUniqueID.ToString(),null );
			oIForm.Size = new Vector2( (float)m_oGameEngine.ScreenWidth * .65f,(float)m_oGameEngine.ScreenHeight * .65f );
			oIForm.Location = new Point( 120 + ( (int)m_nNextUniqueID % 6 ) * 10,30 + ( (int)m_nNextUniqueID % 6 ) * 10 );
		}
		private void cmdMapEditSaveIsland_Click( object sender, EventArgs e )
		{
			System.Windows.Forms.SaveFileDialog oFileDialog = null;
			StreamWriter oStream = null;
			MMIslandForm oIslandForm = null;


			//Find the last form we clicked on by walking the z order list
			oIslandForm = GetLastMapEditedForm();

			//Did we find any forms of value?
			if( oIslandForm != null )
			{
				//Display the OpenFileName dialog. Then, try to load the specified file
				oFileDialog = new SaveFileDialog();

				oFileDialog.Filter = "Islands (*.MMI)|*.MMI";
				oFileDialog.FileName = oIslandForm.Text;
				oFileDialog.InitialDirectory = Environment.CurrentDirectory;
				oFileDialog.Title = "Load Island";

				if( oFileDialog.ShowDialog() == DialogResult.OK )
				{
					oStream = new StreamWriter( oFileDialog.FileName,false );
					oStream.Write( oIslandForm.Island.Serialize( false ) );
					oStream.Close();
				}
			}
			else
			{
				//Throw an error, no window selected
				MessageBox.Show( "No island window found to save." );
			}
		}
		private void cmdMapEditProperties_Click( object sender, EventArgs e )
		{
			StartMapEditorPropertiesForm( false );
		}
		private void cmdMapEditMoveLeft( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.ShiftTerrain( 0 );
		}
		private void cmdMapEditMoveUp( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.ShiftTerrain( 1 );
		}
		private void cmdMapEditMoveRight( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.ShiftTerrain( 2 );
		}
		private void cmdMapEditMoveDown( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.ShiftTerrain( 3 );
		}
		private MMIslandForm GetLastMapEditedForm()
		{
			MMIslandForm oIslandForm = null;
			DSForm oLoopForm = null;


			//Find the last form we clicked on by walking the z order list
			for( int nFormIndex=0 ; nFormIndex<m_oGameEngine.Forms.FormsInZOrder.Length ; nFormIndex++ )
			{
				oLoopForm = m_oGameEngine.Forms.FormsInZOrder[ nFormIndex ];

				if( oLoopForm != null &&
					oLoopForm.Name.Length > Game.m_cEDITISLANDFORMNAME.Length &&
					oLoopForm.Name.Substring( 0,Game.m_cEDITISLANDFORMNAME.Length ) == Game.m_cEDITISLANDFORMNAME )
				{
					oIslandForm = (MMIslandForm)oLoopForm;
				}
			}


			return( oIslandForm );
		}
		private void cmdMapEditDone_Click( object sender, EventArgs e )
		{
			m_nGameState = enumStates.MainMenu;
			m_oGameEngine.Forms.Show( m_cMENU_MAPEDITORMAINMENU,true );
			SwitchMenus( m_cMENU_MAPEDITORMAINMENU,m_cMENU_MAIN,false );
		}

		private void StartMapEditorPropertiesForm( bool bInitEvents )
		{
			DSForm oMapEditForm = null;
			DSForm oForm = null;
			DSButton oButton = null;
			DSSlider oSlider = null;
			DSEditBox oEditBox = null;
			MMIslandForm oIslandForm = null;


			if( bInitEvents == true )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORPROPERTIES );

				oButton = (DSButton)oForm.GetControl( "cmdDone" );
				oButton.Click += new EventHandler( cmdAll_Click );
				oButton.Click += new EventHandler( this.cmdMapEditPropertiesDone_Click );

				oSlider = (DSSlider)oForm.GetControl( "sldWidth" );
				oSlider.ValueChanged += new EventHandler( sldSlider_Change );

				oSlider = (DSSlider)oForm.GetControl( "sldHeight" );
				oSlider.ValueChanged += new EventHandler( sldSlider_Change );

				oSlider = (DSSlider)oForm.GetControl( "sldBases" );
				oSlider.ValueChanged += new EventHandler( sldSlider_Change );
			}
			else
			{
				oMapEditForm = m_oGameEngine.Forms.Show( m_cMENU_MAPEDITORMAINMENU,false );
				oIslandForm = GetLastMapEditedForm();

				if( oIslandForm != null )
				{
					oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORPROPERTIES );
					oForm.IsModal = true;
					oForm.Visible = true;

					oSlider = (DSSlider)oForm.GetControl( "sldWidth" );
					oSlider.SetRange( 10,100 );
					oSlider.Value = oIslandForm.Island.Width;				

					oSlider = (DSSlider)oForm.GetControl( "sldHeight" );
					oSlider.SetRange( 10,100 );
					oSlider.Value = oIslandForm.Island.Height;

					oEditBox = (DSEditBox)oForm.GetControl( "txtStartingCredits" );
					oEditBox.Text = oIslandForm.Island.Credits.ToString();

					oEditBox = (DSEditBox)oForm.GetControl( "txtStartingFuel" );
					oEditBox.Text = oIslandForm.Island.Fuel.ToString();

					oSlider = (DSSlider)oForm.GetControl( "sldBases" );
					oSlider.SetRange( 1,5 );
					oSlider.Value = (int)oIslandForm.Island.MaxBasesToPlace;					

					sldSlider_Change( null,null );
				}
			}
		}
		private void cmdMapEditPropertiesDone_Click( object sender, EventArgs e )
		{
			DSForm oForm = null;
			DSSlider oSlider = null;
			DSEditBox oEditBox = null;
			int nWidth = 0;
			int nHeight = 0;
			MMIslandForm oIslandForm = null;


			oIslandForm = GetLastMapEditedForm();

			if( oIslandForm != null )
			{
				oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORPROPERTIES );
				oForm.IsModal = false;
				oForm.Visible = false;

				oSlider = (DSSlider)oForm.GetControl( "sldWidth" );
				nWidth = oSlider.Value;
				oSlider = (DSSlider)oForm.GetControl( "sldHeight" );
				nHeight = oSlider.Value;
				oIslandForm.Island.Resize( nWidth,nHeight );

				oEditBox = (DSEditBox)oForm.GetControl( "txtStartingCredits" );
				if( DSMisc.IsNumericDouble( oEditBox.Text ) == true )
				{
					oIslandForm.Island.Credits = Convert.ToDouble( oEditBox.Text );
				}
				else
				{
					//oIslandForm.Island.Credits = (long)oEditBox.Text );
				}

				oEditBox = (DSEditBox)oForm.GetControl( "txtStartingFuel" );
				if( DSMisc.IsNumericDouble( oEditBox.Text ) == true )
				{
					oIslandForm.Island.Fuel = Convert.ToDouble( oEditBox.Text );
				}
				else
				{
					//oIslandForm.Island.Fuel = Convert.ToInt64( oEditBox.Text );
				}

				oSlider = (DSSlider)oForm.GetControl( "sldBases" );
				oIslandForm.Island.MaxBasesToPlace = oSlider.Value;

				oIslandForm.CheckScrollBarSizes();
			}
		}

		private void sldSlider_Change( object sender, EventArgs e )
		{
			DSLabel oLabel = null;
			DSForm oForm = null;
			DSSlider oSlider = null;


			oForm = m_oGameEngine.Forms.GetForm( m_cMENU_MAPEDITORPROPERTIES );

			oSlider = (DSSlider)oForm.GetControl( "sldWidth" );
			oLabel = (DSLabel)oForm.GetControl( "lblWidth" );
			oLabel.Label = oSlider.Value.ToString();

			oSlider = (DSSlider)oForm.GetControl( "sldHeight" );
			oLabel = (DSLabel)oForm.GetControl( "lblHeight" );
			oLabel.Label = oSlider.Value.ToString();

			oSlider = (DSSlider)oForm.GetControl( "sldBases" );
			oLabel = (DSLabel)oForm.GetControl( "lblBases" );
			oLabel.Label = oSlider.Value.ToString();
		}

		private void cmdRotateLeft( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.RotateIsland( 1 );
		}
		private void cmdRotateRight( object sender, EventArgs e )
		{
			MMIslandForm oIslandForm = GetLastMapEditedForm();
			oIslandForm.Island.RotateIsland( 3 );
		}


		public void StartTeamForm( bool bInitEvents )
		{
			MMTeamForm oTeamForm = null;
			DSEditBox oTextBox = null;


			if( bInitEvents == true )
			{
			}
			else
			{
				oTeamForm = (MMTeamForm)m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAMDERIVED );
				if( oTeamForm == null )
				{
					oTeamForm = new MMTeamForm( null );
					oTeamForm.Name = Game.m_cFRM_TEAMDERIVED;
					oTeamForm.App = this;
					oTeamForm.Location = new Point( 20,20 );
					oTeamForm.ImplimentsForm( m_oGameEngine.Forms.GetForm( Game.m_cFRM_TEAM ) );

					m_oGameEngine.Forms.Add( oTeamForm );
				}

				//Update the min share amounts
				oTextBox = (DSEditBox)oTeamForm.GetControl( "txtSharedGold" );
				oTextBox.Text = GetMyIsland().Island.CreditsSharedPerMinute.ToString();

				oTextBox = (DSEditBox)oTeamForm.GetControl( "txtSharedFuel" );
				oTextBox.Text = GetMyIsland().Island.FuelSharedPerMinute.ToString();
			}
		}



		private void cmdAll_Click( object sender, EventArgs e )
		{
			m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );
		}
		#endregion


		#region Properties
		public DSSortedList SelectedSquares
		{
			get
			{
				return( m_oSelectedSquares );
			}
			set
			{
				m_oSelectedSquares = value;
			}
		}
		public DSSortedList GroupsOfSelectedSquares
		{
			get
			{
				return( m_oGroupsOfSelectedSquares );
			}
			set
			{
				m_oGroupsOfSelectedSquares = value;
			}
		}
		public DSGameEngine DSGameEngine
		{
			set
			{
				m_oGameEngine = value;
			}
			get
			{
				return( m_oGameEngine );
			}
		}
		public Game Game
		{
			get
			{
				return( m_oGame );
			}
			set
			{
				m_oGame = value;
			}
		}
		public enumStates GameState
		{
			get
			{
				return( m_nGameState );
			}
		}
		public string UserFrameStats
		{
			get
			{
				return( m_sUserFrameStats );
			}
			set
			{
				m_sUserFrameStats = value;
			}
		}
		public string MyIslandsGlobalID
		{
			get
			{
				return( m_sMyIslandsGlobalID );
			}
		}
		public bool SinglePlayerMode
		{
			get
			{
				return( m_bSinglePlayerMode );
			}
			set
			{
				m_bSinglePlayerMode = value;
			}
		}
		#endregion
	}


	//The form has to be the first class in the file or the icons don't get generated properly.
	//You'll get the following error: System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture (or the neutral culture) in the given assembly. Make sure "Form1.resources" was correctly embedded or linked into assembly "MyTestApp".
	public enum enumNetMsg
	{
		LobbyMessage,
		FullGameRefresh,
		StartGame,
		IslandRefresh,
		MissleAttack,
		MMAttack,
		Explosion,
		MMReturnHome,
		DisbandTeam,
		KickFromTeam,
		ApprovePlayer,
		SendingResources,
		TakingResources,
		AddAI,
		LobbyBuildingRotChecked,
		ReadyToStartRequest,
		LobbyMapFileChanged
	};
	public enum enumStates
	{
		SplashScreen,
		WaitingToLoadMenuGOB,
		MainMenu,
		LoadingGOBForMapEditor,
		LoadingGOBForGame,
		MapEditor,
		InGame,
		ResumeMenu
	};


	#region MMIslandForm Form
	public class MMIslandForm : DSForm 
	{
		#region Properties
		//Double click variables
		private DateTime m_dtLastMouseDown = DateTime.MinValue;
		private long m_dtLastMouseDownX = 0;
		private long m_dtLastMouseDownY = 0;

		private bool m_bFormHasBeenPositioned = false;

		private bool m_bDraggingIsland = false;
		private Vector2 m_vDragMouseDown = new Vector2( 0,0 );

		private const long m_cGROWSIZE = 20;

		private long m_nUpperLeftX = 0;
		private long m_nUpperLeftY = 0;

		private const long m_cScrewLeft_DistFromRight = 31;
		private const long m_cScrewTop_DistFromTop = 8;
		private const long m_cScrewWidth = 17;
		private const long m_cScrewHeight = 17;

		private const long m_cBorder_LeftWidth = 10;
		private const long m_cBorder_RightWidth = 48;
		private const long m_cBorder_TopWidth = 10;
		private const long m_cBorder_BottomWidth = 10;
		private const long m_cScrollWidth = 15;
		protected DSHorzScrollBar m_oHorzScrollBarControl = null;
		protected DSVertScrollBar m_oVertScrollBarControl = null;
		
		private Island m_oIsland = null;
		private DSGameEngine m_oGameEngine = null;
		private Game m_oGame = null;
		private MetalMarines m_oApp = null;

		private long m_nDragSourceX = 0;
		private long m_nDragSourceY = 0;

		//Island redraw stuff
		private double m_nZoomFactor = 1;
		private const long m_cISLANDMINWIDTH = 149;
		private const long m_cISLANDMINHEIGHT = 96;
		private bool m_bShrinking = false;
		private bool m_bGrowing = false;
		private double m_nScrewAngle = 0;
		private Microsoft.DirectX.Vector2 m_oOrigSize = Microsoft.DirectX.Vector2.Empty;
		#endregion


		public MMIslandForm( DSForms oForms ) : base( oForms )
		{
		}


		public override void Render()
		{
			LoadedTexture oBulletTexture = null;
			System.Drawing.Rectangle oSourceRect = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oTrgRect = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oFlashyRect = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oClipRegion = System.Drawing.Rectangle.Empty;
			float nTemp = 0;
			long nScreenX = 0;
			long nScreenY = 0;
			bool[] oKeyboardState = null;

long n1 =0 ;
long n2 = 0;
long n3 = 0;
long n4 = 0;
long n5 = 0;
long nStopTime = 0;
long nStartTime = 0;
string sMsg = "";

n1 = DSMisc.GetQueryPerformanceCounter();
try
{
			
			//Hide us if we are dead and exit in that case
			if( m_oIsland.ImDead == true )
			{
				this.Visible = false;
			}
			if( this.Visible == false || 
				( m_oApp.GameState != enumStates.MapEditor && m_oApp.GameState != enumStates.InGame && m_oApp.GameState != enumStates.ResumeMenu ) )
			{
				return;
			}

			//Lets update our size if were changing it
			if( m_bShrinking == true )
			{
				if( this.Size.Y > m_cISLANDMINHEIGHT )
				{
					nTemp = DSMisc.Max( this.Size.Y-m_cGROWSIZE,m_cISLANDMINHEIGHT );
					this.Size = new Vector2( this.Size.X,nTemp );
					m_nScrewAngle += .2;
				}
				else if( this.Size.X > m_cISLANDMINWIDTH )
				{
					nTemp = DSMisc.Max( this.Size.X-m_cGROWSIZE,m_cISLANDMINWIDTH );
					this.Size = new Vector2( nTemp,this.Size.Y );
					m_nScrewAngle += .2;
				}
				else
				{
					m_bShrinking = false;
					if( m_oApp.GameState == enumStates.MapEditor )
					{
						m_oGameEngine.Forms.Remove( this.Name );
					}
				}
			}
			else if( m_bGrowing == true )
			{
				if( this.Size.X < m_oOrigSize.X )
				{
					nTemp = DSMisc.Min( this.Size.X+m_cGROWSIZE,m_oOrigSize.X );
					this.Size = new Vector2( nTemp,this.Size.Y );
					m_nScrewAngle -= .2;
				}
				else if( this.Size.Y < m_oOrigSize.Y )
				{
					nTemp = DSMisc.Min( this.Size.Y+m_cGROWSIZE,m_oOrigSize.Y );
					this.Size = new Vector2( this.Size.X,nTemp );
					m_nScrewAngle -= .2;
				}
				else
				{
					m_bGrowing = false;
					m_oOrigSize = Vector2.Empty;
				}
			}



			base.Render();

			//Did we click on the screw?
			if( m_oApp.DSGameEngine.MouseCursor.X >= this.Right - m_cScrewLeft_DistFromRight &&
				m_oApp.DSGameEngine.MouseCursor.X <= this.Right - m_cScrewLeft_DistFromRight + m_cScrewWidth &&
				m_oApp.DSGameEngine.MouseCursor.Y >= this.Top + m_cScrewTop_DistFromTop &&
				m_oApp.DSGameEngine.MouseCursor.Y <= this.Top + m_cScrewTop_DistFromTop + m_cScrewHeight &&
				m_oGame.Debug_AllowZoom == true )
			{					 
				m_oApp.DSGameEngine.DirectInput.GetKeyboardState( ref oKeyboardState );
				if( oKeyboardState != null &&
					(
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftAlt ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightAlt ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true 
					) )
				{
					if( m_nZoomFactor > .25 && m_oApp.DSGameEngine.MouseButtonState[0] == true )
					{
						m_nZoomFactor -= .01;
					}
					else if( m_nZoomFactor < 2 && m_oApp.DSGameEngine.MouseButtonState[1] == true )
					{
						m_nZoomFactor += .01;
					}
				}
			}

			m_oHorzScrollBarControl.Render();
			m_oVertScrollBarControl.Render();

			//Are we minimized?
			if( m_oOrigSize != Vector2.Empty && m_bShrinking == false )
			{
				base.DSGraphicsWrapper.RenderRect2D( GetWindowRenderArea(),
													System.Drawing.Color.Gray.ToArgb() ); 
			}
			//Are we still placing bases?
			else if( ( m_oApp.GameState == enumStates.InGame || m_oApp.GameState == enumStates.ResumeMenu ) && 
				m_oIsland.IsMyIsland() == false && m_oIsland.BasesPlaced == false )
			{
				base.DSGraphicsWrapper.RenderRect2D( GetWindowRenderArea(),
														System.Drawing.Color.Gray.ToArgb() ); 

				base.DSGraphicsWrapper.RenderText( this.Location.X+15+20,this.Location.Y+3+20,
					System.Drawing.Color.White,
					"Player still placing bases" );
			}
			else
			{
nStartTime = DSMisc.GetQueryPerformanceCounter();
				sMsg = RenderTerrainAndBuildings();
n3 = DSMisc.GetQueryPerformanceCounter();
				RenderMetalMarines();
n4 = DSMisc.GetQueryPerformanceCounter();
				RenderExplosions();
n5 = DSMisc.GetQueryPerformanceCounter();
				RenderDragingItem();
nStopTime = DSMisc.GetQueryPerformanceCounter();
			}

			base.DrawBorder( Game.m_cGOB_BAISHBORDER_UPPERLEFT_TABLE, Game.m_cGOB_BAISHBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_BAISHBORDER_UPPERRIGHT_TABLE,
								Game.m_cGOB_BAISHBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_BAISHBORDER_MIDDLERIGHT_TABLE,
								Game.m_cGOB_BAISHBORDER_LOWERLEFT_TABLE, Game.m_cGOB_BAISHBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_BAISHBORDER_LOWERRIGHT_TABLE );

			//Now draw our flashy border thing
			oClipRegion = new Rectangle( (int)( base.Location.X + Game.m_cBORDER_BEISH_COLORSTRIP_LEFT ),
										 (int)( base.Location.Y + Game.m_cBORDER_BEISH_COLORSTRIP_TOP ),
										 (int)( Game.m_cBORDER_BEISH_COLORSTRIP_WIDTH ),
										 (int)( base.Size.Y - Game.m_cBORDER_BEISH_COLORSTRIP_TOP - Game.m_cBORDER_BEISH_COLORSTRIP_BOTTOM ) );

			oFlashyRect = new Rectangle( oClipRegion.X,oClipRegion.Y,oClipRegion.Width,oClipRegion.Height );
			if( m_oIsland.BarInDefaultPos == false )
			{
				oFlashyRect.Y -= 18;
				oFlashyRect.Height += 18;
			}
			oSourceRect = new System.Drawing.Rectangle( 1,1,11,36 );
			m_oGameEngine.Tile( oSourceRect,oFlashyRect,oClipRegion,Game.m_cGOB_MMLAUNCHBAR_TABLE,System.Drawing.Color.White.ToArgb() );
			oSourceRect = new System.Drawing.Rectangle( 2+11,1,11,36 );
			m_oGameEngine.Tile( oSourceRect,oFlashyRect,oClipRegion,Game.m_cGOB_MMLAUNCHBAR_TABLE,m_oIsland.Color );

			//Now render the screw location
			oBulletTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_BULLETPOINT_TABLE );
			oTrgRect = new System.Drawing.Rectangle( (int)(this.Right - m_cScrewLeft_DistFromRight),
														(int)(Top + m_cScrewTop_DistFromTop),0,0 );
			base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_BULLETPOINT_TABLE,
													System.Drawing.Rectangle.Empty,oTrgRect,
													//new Vector2( oBulletTexture.Size.X/2,oBulletTexture.Size.Y/2 ),
													new Vector2( 8,8 ),
													m_nScrewAngle,0,true,System.Drawing.Color.White.ToArgb() );

			//Draw the players name
			if( m_oGame.Debug_FullVision == true )
			{
				base.DSGraphicsWrapper.RenderText( this.Location.X+6,this.Location.Y+4,System.Drawing.Color.Black,
							this.Text + " (C:" + ((long)m_oIsland.Credits).ToString() + 
										" F:" + ((long)m_oIsland.Fuel).ToString() + ")" );
			}
			else
			{
				base.DSGraphicsWrapper.RenderText( this.Location.X+6,this.Location.Y+4,System.Drawing.Color.Black,this.Text );
			}

			//Draw the coordinates we are at
			if( m_oGame != null &&
				m_oGame.Debug_FPS == true &&
				m_oGameEngine.MouseCursor.X >= this.Location.X &&
				m_oGameEngine.MouseCursor.Y >= this.Location.Y &&
				m_oGameEngine.MouseCursor.X <= this.Location.X + this.Size.X && 
				m_oGameEngine.MouseCursor.Y <= this.Location.Y + this.Size.Y )
			{
				GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nScreenX,ref nScreenY );
				base.DSGraphicsWrapper.RenderText( this.Location.X+6+8,this.Location.Y+4+17,System.Drawing.Color.Black,
												   "Square Under Cursor: (" + nScreenX.ToString() + "," + nScreenY.ToString() + ")" );
			}
}
catch( System.Exception oEx )
{
	DSMisc.ShowErrors( oEx );
}

			n2 = DSMisc.GetQueryPerformanceCounter();
			double nFreq = DSMisc.GetQueryPerformanceFrequency();
			double nDiff1 = ( ( (double)nStartTime - (double)n1 ) / nFreq );
			double nDiff2 = ( ( (double)nStopTime - (double)nStartTime ) / nFreq );
			double nDiff3 = ( ( (double)n2 - (double)nStopTime ) / nFreq );

			double nRenderTerrainAndBuildings = ( ( (double)n3 - (double)nStartTime ) / nFreq );
			//double nRenderMetalMarines = ( ( (double)n4 - (double)n3 ) / (double)m_oGameEngine.m_nTicksPerSecond );
			//double nRenderExplosions = ( ( (double)n5 - (double)n4 ) / (double)m_oGameEngine.m_nTicksPerSecond );
			//double nRenderDragingItem = ( ( (double)nStopTime - (double)n5 ) / (double)m_oGameEngine.m_nTicksPerSecond );
			
			m_oApp.UserFrameStats = "\nPre Render: " + nDiff1.ToString() + 
								"\n - Render Time: " + nDiff2.ToString() + 
								"\n - - Render Terrain And Buildings: " + nRenderTerrainAndBuildings.ToString() + 
								//"\nRenderMetalMarines: " + nRenderMetalMarines.ToString() + 
								//"\nRenderExplosions: " + nRenderExplosions.ToString() + 
								//"\nRenderDragingItem: " + nRenderDragingItem.ToString() + 
								sMsg + 
								"\nPost Render: " + nDiff3.ToString();
		}

		private string RenderTerrainAndBuildings()
		{
			System.Drawing.Rectangle oDrawRect;
			System.Drawing.Rectangle oTrgRect = new System.Drawing.Rectangle( 0,0,0,0 );
			Square oSquare = null;
			Color cColor = System.Drawing.Color.White;
			long nMinX = 0, nMinY = 0, nMaxX = 0, nMaxY = 0;
			long nActualStartX = 0, nActualStartY = 0;
			long nCenterDragX = 0, nCenterDragY = 0;
			long nScreenX = 0, nScreenY = 0;
			long nNumberOfUses = 0;
			long nGobBuildingToPlaceKey = 0;
			long nCenterDragRadius = 0;
			int nOldType;
			object oObject = null;
			bool bInvisible = false;
			bool bOnMyTeamAndSharedVision = false;
			Island oTeamIsland = null;
			Island oMyIsland = null;

int nXTarget = -1;
int nYTarget = -1;
long nTrueStart = 0;
long nTrueStop = 0;
long nPre = 0;
long nPost = 0;
long nStart = 0;
long nStop = 0;
long nBuilding = 0;
long nBuildingCount = 0;
long nTerrain = 0;
long nTerrainCount = 0;
nTrueStart = DSMisc.GetQueryPerformanceCounter();

try{

			//Get our island
			if( m_oApp.GameState != enumStates.MapEditor )
			{
				oMyIsland = m_oApp.GetMyIsland().Island;
			}

			#region Team Setup Calculation
			//Calculate the team layout
			if( ( m_oApp.GameState == enumStates.InGame || m_oApp.GameState == enumStates.ResumeMenu ) &&
				m_oGame.OnSameTeam( m_oIsland,oMyIsland ) == true )
			{
				if( oMyIsland.TeamSetup != null )
				{
					oTeamIsland = oMyIsland;
				}
				else if( oMyIsland.GlobalIDOfPlayerWhoseTeamImOn.Length > 0 )
				{
					oTeamIsland = m_oApp.GetIsland( oMyIsland.GlobalIDOfPlayerWhoseTeamImOn  ).Island;
				}
					
				bOnMyTeamAndSharedVision = ( oTeamIsland != null && oTeamIsland.TeamSetup.SharedVision == true );
			}
			else
			{
				bOnMyTeamAndSharedVision = false;
			}
			#endregion

			//Draw the black rendering area
			oDrawRect = GetWindowRenderArea();

			#region Drag Radius Calculation
			//Find out if we are dragging something, and if so what is our "Yellow" range
			nCenterDragRadius = -1;
			if( BuildingIsBeingDragged( ref nGobBuildingToPlaceKey ) == true && 
				( m_oApp.GameState == enumStates.MapEditor || m_oIsland.IsMyIsland() == true ) &&
				GetWindowRenderArea().Contains( (int)m_oGameEngine.MouseCursor.X,
												(int)m_oGameEngine.MouseCursor.Y ) == true )
			{
				//Ok that was relatively easy... now find the square were over
				GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nCenterDragX,ref nCenterDragY );

				//Now find out the radius we will use
				//Check AA first
				oObject = Game.GetBldStat( nGobBuildingToPlaceKey,Game.m_cGOB_BLDSTATS_AARANGE_CLMN );
				if( oObject != null )
				{
					nCenterDragRadius = Convert.ToInt32( oObject );
				}
				//Now check MM offense range
				else
				{
					oObject = Game.GetBldStat( nGobBuildingToPlaceKey,Game.m_cGOB_BLDSTATS_MMOFFENSERANGE_CLMN );
					if( oObject != null )
					{
						nCenterDragRadius = Convert.ToInt32( oObject );
					}
				}
			}
			#endregion

			#region Render Max/Min Calculation
			//07/15/2005 Chris Hill  For speed reasons find out the bounds of our screen.
			GetSquareFromScrPos( new Vector2( oDrawRect.Left,oDrawRect.Top) ,ref nMinX,ref nMinY );
			GetSquareFromScrPos( new Vector2( oDrawRect.Right,oDrawRect.Bottom) ,ref nMaxX,ref nMaxY );
			//Add some buffer space
			nMinX = DSMisc.Max( nMinX-2,0 );
			//08/06/2005 Chris Hill  You have to start on an even number otherwise squares are missed
			if( nMinX % 2 == 1 )
			{
				nMinX--;
			}
			nMinY = DSMisc.Max( nMinY-1,0 );
			nMaxX = DSMisc.Min( nMaxX+1,m_oIsland.Width-1 );
			nMaxY = DSMisc.Min( nMaxY+1,m_oIsland.Height-1 );
			//Finally configure the actual starting spot
			nActualStartX = nMaxX;
			nActualStartY = nMinY;
			if( nActualStartX % 2 == 1 )
			{
				nActualStartX--;
			}
			#endregion

			//For dragging
			GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nScreenX,ref nScreenY );
nStart = DSMisc.GetQueryPerformanceCounter();
nPre = nStart - nTrueStart;
			//06/16/2005 Chris Hill  Ok this algorithm got a little wierd.  We have to draw the back items first
			//so that the front items cover them.  But because of our wierd 2/3rds top view the back items are
			//the back right corner.  So we have to work our way in a diagnal forward to the front left corner.
			//I found a pattern in the way you count up in this type of a scenario and implimented that.  It
			//goes something like this... 6,0 7,0 / 4,0 5,0 6,1 7,2 / 2,0 3,0 4,1 5,1 6,2 7,2...
			long nY = nActualStartY;
			for( int i=0 ; i<= (nMaxX-nMinX)/2+(nMaxY-nMinY) ; i++ )
			{
				nNumberOfUses = 0;
				for( long nX=nActualStartX ; nX<=nMaxX ; nX++ )
				{
try{
nStart = DSMisc.GetQueryPerformanceCounter();
					nNumberOfUses++;
					if( nNumberOfUses > 2 )
					{
						nY++;
						nNumberOfUses = 1;
					}


//Chris
if( nY == nYTarget && nX == nXTarget )
{
	nStart = DSMisc.GetQueryPerformanceCounter();
}

					//If this is past our maximum then start over
					if( nY <= nMaxY )
					{
						//Get island object
						if( bOnMyTeamAndSharedVision == true || m_oApp.GameState == enumStates.MapEditor )
						{
							oSquare = m_oIsland.GetSquare( nX,nY );
						}
						else
						{
							oSquare = m_oIsland.GetSquareICanSee( nX,nY,oMyIsland );
						}

						if( oSquare == null )
						{
							throw new System.Exception( "Render: Unable to find square at <" + nX.ToString() + "," + nY.ToString() + ">" );
						}
						else
						{
							#region Terrain Rendering Color / Visibility Calculation
							//Render the dragging source
							if( m_oApp.GameState == enumStates.InGame &&
								m_oIsland.IsMyIsland() == true &&
								//MMIslandForm.IsDragingAttack( m_oForms ) == true &&
								m_oApp.SelectedSquares.ContainsKey( nX.ToString() + "," + nY.ToString() ) == true )
							{
								cColor = System.Drawing.Color.Blue;
							}
							else if( nCenterDragRadius > -1 && 
									 Game.GetDistance( nX,nY,nCenterDragX,nCenterDragY ) <= nCenterDragRadius )
							{
								if( oSquare.ScarPercent > 0 &&
									oSquare.SquareStatus == enumSquareStatus.Destroyed )
								{
									cColor = System.Drawing.Color.Red;
								}
								else
								{
									cColor = System.Drawing.Color.LightBlue;
								}
							}
							else
							{
								cColor = System.Drawing.Color.White;
							}

							//Find out if our building is invisible
							bInvisible = false;
							if( 
								(
									oSquare.SquareStatus == enumSquareStatus.Building || 
									oSquare.SquareStatus == enumSquareStatus.Built  
								)
							  )
							{
								if( m_oIsland.GlobalID != m_oApp.MyIslandsGlobalID &&
									(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_INVISIBLE_CLMN ) == true )
								{
									bInvisible = true;
								}
							}
							#endregion

nStop = DSMisc.GetQueryPerformanceCounter();
nPre += nStop - nStart;
nStart = DSMisc.GetQueryPerformanceCounter();
							//Draw!
							oTrgRect = GetScrTerrainPosFromSquare( nX,nY );
							oSquare.RenderTerrain( base.DSGraphicsWrapper, oTrgRect, oDrawRect, Game.m_cSQRW_TRN, Game.m_cSQRH_TRN,cColor,this.Island );
							nTerrainCount++;
nStop = DSMisc.GetQueryPerformanceCounter();
nTerrain += nStop - nStart;
							//We only render the building if its not invisible
							if( bInvisible == false )
							{
								oTrgRect = GetScrBuildingPosFromSquare( nX,nY );
nStart = DSMisc.GetQueryPerformanceCounter();
								nBuildingCount += oSquare.RenderBuilding( base.DSGraphicsWrapper, oTrgRect, oDrawRect, Game.m_cSQRW_BLD, Game.m_cSQRH_BLD,cColor,this.Island,m_oApp.GroupsOfSelectedSquares );
nStop = DSMisc.GetQueryPerformanceCounter();
nBuilding += nStop - nStart;
							}

							oSquare.RenderScrollingMessage( base.DSGraphicsWrapper, oTrgRect,oDrawRect,Game.m_cSQRW_TRN, Game.m_cSQRH_TRN,this.Island );

							//Do we want a grid on or not?
							if( m_oGame.Debug_RenderGrid == true )
							{
								oTrgRect = GetScrTerrainPosFromSquare( nX,nY );
								nOldType = oSquare.SquareType;
								oSquare.SquareType = Game.m_cGRIDTERRAINKEY;
								oSquare.RenderTerrain( base.DSGraphicsWrapper, oTrgRect, oDrawRect, Game.m_cSQRW_TRN, Game.m_cSQRH_TRN,System.Drawing.Color.White,this.Island );
								oSquare.SquareType = nOldType;
							}

nStart = DSMisc.GetQueryPerformanceCounter();
nPost += nStart - nStop;

						}
					}

}
catch( System.Exception oEx )
{
	DSMisc.ShowErrors( oEx );
}
				}

				//This is kind of wierd... basically if we hit the left hand side we need to start going
				//up the side.
				if( nActualStartX - 2 < nMinX )
				{
					nActualStartY++;
					nActualStartX = nMinX;
					nY = nActualStartY;
				}
				else
				{
					nActualStartX -= 2;
					nY = nActualStartY;
				}
			}

}
catch( System.Exception oEx )
{
	DSMisc.ShowErrors( oEx );
}


nTrueStop = DSMisc.GetQueryPerformanceCounter();
double nFreq = DSMisc.GetQueryPerformanceFrequency();
double nTer = ( ( (double)nTerrain ) / nFreq );
double nBld = ( ( (double)nBuilding ) / nFreq );
double nPre1 = ( ( (double)nPre ) / nFreq );
double nPost1 = ( ( (double)nPost ) / nFreq );
return( 
		"\n - - - Pre Time: " + nPre1.ToString() +
		"\n - - - Terrain Time: " + nTer.ToString() + 
	    "\n - - - - Count: " + nTerrainCount.ToString() + 
		"\n - - - Building Time: " + nBld.ToString() + 
		"\n - - - - Count: " + nBuildingCount.ToString() +
		"\n - - - Post Time: " + nPost1.ToString() );


		}
		private void RenderMetalMarines()
		{
			Square oSquare = null;
			System.Drawing.Rectangle oMMPos;
			System.Drawing.Rectangle oMetalMarineSrc;
			MMAttack oLoopMMAttack = null;


			//Walk through all our attacks in progress
			for( int nLoopMMAttackIndex=0 ; nLoopMMAttackIndex<m_oGame.MetalMarineAttacks.Count ; nLoopMMAttackIndex++ )
			{
				oLoopMMAttack = (MMAttack)m_oGame.MetalMarineAttacks.GetByIndex( nLoopMMAttackIndex );

				//Is this the island its on and has it landed?
				if( oLoopMMAttack.TargetIslandGlobalID == m_oIsland.GlobalID && oLoopMMAttack.Landed == true )
				{
					//Get our graphic source size
					oMetalMarineSrc = Game.GetSrcRectForMetalMarine( oLoopMMAttack.Direction, oLoopMMAttack.AnimationCell, oLoopMMAttack.Firing,oLoopMMAttack.MMGraphicType );

					//Get our MM pos
					oMMPos = GetScrTerrainPosFromSquare( oLoopMMAttack.TargetX,oLoopMMAttack.TargetY );

					//Adjust for our location
					oMMPos.Width = oMetalMarineSrc.Width;
					oMMPos.Height = oMetalMarineSrc.Height;
					//Adjust for the graphic location & centering
					oMMPos.X += (int)( (double)Game.m_cSQRW_TRN / 2.0 - (double)Game.m_cSQRW_MM / 2.0 );
					oMMPos.Y += (int)( (double)Game.m_cSQRH_TRN / 2.0 - (double)Game.m_cSQRH_MM );

					oMMPos.X += (int)oLoopMMAttack.LandedPosOffsetX;
					oMMPos.Y += (int)oLoopMMAttack.LandedPosOffsetY;

					//Now draw the metal marine
					base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_METALMARINE_TABLE, oMetalMarineSrc, 
															oMMPos, GetWindowRenderArea(),
															new Vector2( 0,0 ), 0, 0, false, 
															System.Drawing.Color.White.ToArgb() );

					oMetalMarineSrc.Y += 190;
					base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_METALMARINE_TABLE, oMetalMarineSrc, 
															oMMPos, GetWindowRenderArea(),
															new Vector2( 0,0 ), 0, 0, false, 
															oLoopMMAttack.Color );
				}
			}	
	

			//Now render any defensive MM that are out walking around
			for( int nX=0 ; nX<m_oIsland.Width ; nX++ )
			{
				for( int nY=0 ; nY<m_oIsland.Height ; nY++ )
				{
					oSquare = m_oIsland.GetSquare( nX,nY );

					if( oSquare.SquareStatus == enumSquareStatus.Built &&
						( oSquare.MMX != nX || oSquare.MMY != nY || oSquare.MMPosOffsetX != 0 || oSquare.MMPosOffsetY != 0 ) &&
					    oSquare.MMStrength > 0 &&
					    (bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true )
					{
						//Render our MM out walking around
						//Get our graphic source size
						oMetalMarineSrc = Game.GetSrcRectForMetalMarine( oSquare.MMDirection, oSquare.MMAnimationCell, oSquare.MMFiring,oSquare.MMGraphicIndex );

						//Get our MM pos
						oMMPos = GetScrTerrainPosFromSquare( oSquare.MMX,oSquare.MMY );

						//Adjust for our location
						oMMPos.Width = oMetalMarineSrc.Width;
						oMMPos.Height = oMetalMarineSrc.Height;
						//Adjust for the graphic location & centering
						oMMPos.X += (int)( (double)Game.m_cSQRW_TRN / 2.0 - (double)Game.m_cSQRW_MM / 2.0 );
						oMMPos.Y += (int)( (double)Game.m_cSQRH_TRN / 2.0 - (double)Game.m_cSQRH_MM );

						oMMPos.X += (int)oSquare.MMPosOffsetX;
						oMMPos.Y += (int)oSquare.MMPosOffsetY;

						//Now draw the metal marine
						base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_METALMARINE_TABLE, oMetalMarineSrc, 
																oMMPos, GetWindowRenderArea(),
																new Vector2( 0,0 ), 0, 0, false, 
																System.Drawing.Color.White.ToArgb() );

						oMetalMarineSrc.Y += 190;
						base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_METALMARINE_TABLE, oMetalMarineSrc, 
															oMMPos, GetWindowRenderArea(),
															new Vector2( 0,0 ), 0, 0, false, 
															m_oIsland.Color );
					}
				}
			}
		}

		private void RenderExplosions()
		{
			long nFrame = 0;
			string sImage = "";
			System.Drawing.Rectangle oPos = new Rectangle();
			System.Drawing.Rectangle oClipRegion = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oExploSrc = new Rectangle();
			Explosion oLoopExplosion = null;


			//Walk through all our explosions
			for( int nLoopExploIndex=0 ; nLoopExploIndex<m_oGame.Explosions.Count ; nLoopExploIndex++ )
			{
				oLoopExplosion = (Explosion)m_oGame.Explosions.GetByIndex( nLoopExploIndex );

				//Is this the island its on and has it landed?
				if( oLoopExplosion.IslandGlobalID == m_oIsland.GlobalID && oLoopExplosion.DelayTillThisExploIsDone.Length == 0 )
				{
					//Determine our explosion frame
					if( oLoopExplosion.ExplosionType == enumExplosionType.Building )
					{
						nFrame = (long)( oLoopExplosion.TimeIntoExplosion / Game.m_cBLDEXPLO_TIMEPERFRAMES );
						sImage = Game.m_cGOB_BLDEXPLOSIONS_TABLE;
						//Get our graphic source size
						oExploSrc = Game.GetSrcRectForBuildingExplosion( nFrame );
					}
					else if( oLoopExplosion.ExplosionType == enumExplosionType.MetalMarine )
					{
						nFrame = (long)( oLoopExplosion.TimeIntoExplosion / Game.m_cMMEXPLO_TIMEPERFRAMES );
						sImage = Game.m_cGOB_MMEXPLOSIONS_TABLE;
						//Get our graphic source size
						oExploSrc = Game.GetSrcRectForMMExplosion( nFrame );
					}
					else
					{
						continue;
					}

					//Get our explosion pos
					oPos = GetScrTerrainPosFromSquare( oLoopExplosion.SquareX,oLoopExplosion.SquareY );

					//Adjust for our location
					oPos.Width = oExploSrc.Width;
					oPos.Height = oExploSrc.Height;
					oPos.X += (int)( (double)Game.m_cSQRW_TRN / 2.0 - (double)oExploSrc.Width / 2.0 );
					oPos.Y += (int)( (double)Game.m_cSQRH_TRN / 2.0 - (double)oExploSrc.Height ) + (int)Game.m_cSQRH_TRN;

					//Setup our clipping region
					oClipRegion = GetWindowRenderArea();

					//Now draw the explosion
					base.DSGraphicsWrapper.RenderTexture2D( sImage, oExploSrc, 
															oPos, oClipRegion,
															new Vector2( 0,0 ), 0, 0, false, 
															System.Drawing.Color.White.ToArgb() );
				}
			}		
		}

		private void RenderDragingItem()
		{
			object oValue = null;
			DSGobTable oTable = null;
			int nColor = 0;
			System.Drawing.Rectangle oSrcRect;
			System.Drawing.Rectangle oTrgRect;
			Point oEndPoint;
			string sGraphicKey = "";
			bool bFound = false;
			long nGobBuildingToPlaceKey = -1;
			long nBuildingKey = -1;
			long nScreenX = 0, nScreenY = 0;
			long nParentKey = 0;
			long nTerrainIndex = 0;
			long nDeltaX = 0;
			long nDeltaY = 0;

	
			//No matter what, if we aren't over our island then draw the base we are going to place
			if( BuildingIsBeingDragged( ref nGobBuildingToPlaceKey ) == true && 
				( m_oApp.GameState == enumStates.MapEditor || m_oIsland.IsMyIsland() == true ) &&
				GetWindowRenderArea().Contains( (int)m_oGameEngine.MouseCursor.X,
												(int)m_oGameEngine.MouseCursor.Y ) == true )
			{
				//Ok that was relatively easy... now find the square were over
				GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nScreenX,ref nScreenY );

				//Decide how we are going draw the swuare... red or white.
				if( m_oIsland.CanBuildOnSquare( nGobBuildingToPlaceKey,nScreenX,nScreenY ) == true )
				{
					nColor = System.Drawing.Color.White.ToArgb();
				}
				else
				{
					nColor = System.Drawing.Color.Red.ToArgb();
				}

				//Now draw the base were dragging by the mouse cursor, make sure to check to see
				//if its bigger than just one square.
				oTable = Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE );
				for( int nRow=0 ; nRow<oTable.RowCount ; nRow++ )
				{
					oValue = oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQAR_PRNTBLDKEY_TABLE,nRow );
					if( oValue != null && oValue.GetType().ToString() != "System.DBNull" )
					{
						nParentKey = (long)oValue;
						if( nParentKey == nGobBuildingToPlaceKey )
						{
							bFound = true;

							//Get this changed key
							nDeltaX = (long)oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAX_TABLE,nRow );
							nDeltaY = (long)oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAY_TABLE,nRow );
							nBuildingKey = (long)oTable.GetData( Game.m_cGOB_BLDSTATS_BLDKEY_CLMN,nRow );
							oEndPoint = Game.MoveUpRight( nDeltaX,nScreenX,nScreenY );
							oEndPoint = Game.MoveUpLeft( nDeltaY*-1,oEndPoint.X,oEndPoint.Y );

							//Get our base graphic and determine its location
							oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nBuildingKey,0,ref sGraphicKey );
							oTrgRect = GetScrBuildingPosFromSquare( oEndPoint.X,oEndPoint.Y );

							base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
														oTrgRect, GetWindowRenderArea(),
														new Vector2( 0,0 ), 0, 0, false, nColor );
						}
					}

				}
				if( bFound == false && nGobBuildingToPlaceKey >= 0 )
				{
					//Get our base graphic and determine its location
					oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nGobBuildingToPlaceKey,0,ref sGraphicKey );
					oTrgRect = GetScrBuildingPosFromSquare( nScreenX,nScreenY );

					base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
														oTrgRect, GetWindowRenderArea(),
														new Vector2( 0,0 ), 0, 0, false, nColor );
				}
			}
			//Check for terrain if this is edit mode
			else if( MMPlaceTerrainForm.IsDragingTerrain( m_oGameEngine.Forms ) && 
					 m_oApp.GameState == enumStates.MapEditor &&
					 GetWindowRenderArea().Contains( (int)m_oGameEngine.MouseCursor.X,
													 (int)m_oGameEngine.MouseCursor.Y ) == true )
			{
				//Ok that was relatively easy... now find the square were over
				GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nScreenX,ref nScreenY );

				//Get our terrain graphic and location
				nTerrainIndex = MMPlaceTerrainForm.GetDragingTerrain( m_oGameEngine.Forms );
				oSrcRect = Game.GetSrcRectForTerrainType( (int)nTerrainIndex,ref sGraphicKey );
				oTrgRect = GetScrTerrainPosFromSquare( nScreenX,nScreenY );
				
				base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
										oTrgRect, GetWindowRenderArea(),
										new Vector2( 0,0 ), 0, 0, false, System.Drawing.Color.White.ToArgb() );
			}
		}


		public bool BuildingIsBeingDragged( ref long nGobBuildingBeingPlacedKey )
		{
			bool bFound = false;
			MMPlaceBaseForm oBasePlaceForm = null;
			MMPurchaseForm oPurchaseForm = null;


			if( m_oForms.DragAndDropInProgress == true )
			{
				//First of all locate a form which may be dragging a new base
				oBasePlaceForm = (MMPlaceBaseForm)this.Forms.GetForm( Game.m_cFRM_BASEPLACE );
				//This means they are dragging a base on us...
				if( oBasePlaceForm != null && MMPlaceBaseForm.IsDragingBasePlacement( m_oForms ) == true )
				{
					nGobBuildingBeingPlacedKey = Game.m_cGOB_BASE_KEY;
					bFound = true;
				}

				//Now see if were buying something
				//First of all locate a form which may be dragging a new base
				oPurchaseForm = (MMPurchaseForm)this.Forms.GetForm( Game.m_cFRM_PURCHASE );
				//This means they are dragging a base on us...
				if( bFound == false && oPurchaseForm != null && MMPurchaseForm.IsDragingPurchase( m_oForms ) == true )
				{
					nGobBuildingBeingPlacedKey = MMPurchaseForm.GetDragingPurchase( m_oForms );
					bFound = true;
				}
			}

			return( bFound );
		}
		/*public static bool IsDragingAttack( DSForms oForms )
		{
			bool bDraggin = false;


			if( IsDragingMissle( oForms ) == true ||
				IsDragingAntiMatter( oForms ) == true ||
				IsDragingMM( oForms ) == true )
			{
				bDraggin = true;
			}

			return( bDraggin );
		}*/

		public void CheckScrollBarSizes()
		{
			int nRange = 0;
			int nIslandWidth = m_oIsland.Width - 1;
			int nIslandHeight = m_oIsland.Height - 1;
			double nTrnWidth = (Game.m_cSQRW_TRN*m_nZoomFactor);
			double nTrnHeight = (Game.m_cSQRH_TRN*m_nZoomFactor);
			double nTotalWidth, nTotalHeight;
			System.Drawing.Rectangle oDrawRect;


			oDrawRect = GetWindowRenderArea();
			nTotalWidth = nIslandWidth * ( nTrnWidth / 2.0f );
			nTotalHeight = nIslandHeight * nTrnHeight + nTrnHeight / 2.0f;

			nRange = (int)( nTotalWidth - oDrawRect.Width );
			if( m_oHorzScrollBarControl != null && oDrawRect.Width != m_oHorzScrollBarControl.PageSize )
			{
				m_oHorzScrollBarControl.PageSize = oDrawRect.Width;
				m_oHorzScrollBarControl.SetTrackRange( 0,(int)nTotalWidth );
				m_oHorzScrollBarControl.SmallChange = (int)( (double)nTotalWidth * .05 );
				m_oHorzScrollBarControl.LargeChange = (int)( (double)nTotalWidth * .25 );
			}

			nRange = (int)( nTotalHeight - oDrawRect.Height );
			if( m_oVertScrollBarControl != null && oDrawRect.Height != m_oVertScrollBarControl.PageSize )
			{
				m_oVertScrollBarControl.PageSize = oDrawRect.Height;
				m_oVertScrollBarControl.SetTrackRange( 0,(int)nTotalHeight );
				m_oVertScrollBarControl.SmallChange = (int)( (double)nTotalHeight * .05 );
				m_oVertScrollBarControl.LargeChange = (int)( (double)nTotalHeight * .25 );
			}
		}


		public System.Drawing.Rectangle GetWindowRenderArea()
		{
			System.Drawing.Rectangle oDrawRect;

			oDrawRect = new Rectangle( (int)(this.Location.X + m_cBorder_LeftWidth),
									   (int)(this.Location.Y + m_cBorder_TopWidth),
									   (int)(this.Size.X - m_cBorder_LeftWidth - m_cBorder_RightWidth - m_cScrollWidth),
									   (int)(this.Size.Y - m_cBorder_TopWidth - m_cBorder_BottomWidth - m_cScrollWidth) );

			return( oDrawRect );
		}
		public void GetSquareFromScrPos( Vector2 vScreenPos,ref long nScreenX,ref long nScreenY )
		{
			System.Drawing.Rectangle oDrawRect;
			System.Drawing.Rectangle oTrgRect = new System.Drawing.Rectangle( 0,0,0,0 );
			System.Drawing.Rectangle oSrcRect = new System.Drawing.Rectangle( 0,0,0,0 );
			float nYModifier = 0;
			double nTotalWidth, nTotalHeight;
			double nPercentW, nPercentH;
			double nLeftOffset, nTopOffset;
			double nTempPosX = 0;
			double nTempPosY = 0;
			double nGamePosX = 0;
			double nGamePosY = 0;
			double nTrnWidth = Math.Floor(Game.m_cSQRW_TRN*m_nZoomFactor);
			double nTrnHeight = Math.Floor(Game.m_cSQRH_TRN*m_nZoomFactor);
			double nWRadius = ( nTrnWidth / 2.0f );
			double nHRadius = ( nTrnHeight / 2.0f );
            double nM = 0, nB = 0;
			double nXIntercept1 = 0, nXIntercept2 = 0;
			long nUpperRightToLowerLeftVane = 0;
			long nUpperLeftToLowerRightVane = 0;
			int nIslandWidth = m_oIsland.Width - 1;
			int nIslandHeight = m_oIsland.Height - 1;


			//Draw the black rendering area
			oDrawRect = GetWindowRenderArea();

			//Setup the location based upon the progress bar
			nTotalWidth = nIslandWidth * ( nTrnWidth / 2.0f ) - oDrawRect.Width;
			if( m_oHorzScrollBarControl.EndRange - m_oHorzScrollBarControl.PageSize == 0 )
			{
				nLeftOffset = nTrnWidth / 2.0f;
			}
			else
			{
				nPercentW = (float)m_oHorzScrollBarControl.TrackPosition / 
							( m_oHorzScrollBarControl.EndRange - m_oHorzScrollBarControl.PageSize );
				nLeftOffset = nTotalWidth * nPercentW + ( nTrnWidth / 2.0f );
			}

			nTotalHeight = nIslandHeight * nTrnHeight + nTrnHeight / 2.0f - oDrawRect.Height;
			if( m_oVertScrollBarControl.EndRange - m_oVertScrollBarControl.PageSize == 0 )
			{
				nTopOffset = nTrnHeight / 2.0f;
			}
			else
			{
				nPercentH = (float)m_oVertScrollBarControl.TrackPosition / 
							( m_oVertScrollBarControl.EndRange - m_oVertScrollBarControl.PageSize );
				nTopOffset = nTotalHeight * nPercentH + ( nTrnHeight / 2.0f );
			}


			//First of all find out the X.  
			//Remove the graphical adjustments
			nTempPosX = vScreenPos.X - base.Location.X - m_nUpperLeftX - m_cBorder_LeftWidth;
			//Add in however much were off screen
			nTempPosX += nLeftOffset;
			nGamePosX = nTempPosX;


			//Now find the Y since we can adjust for the X position 
			//Remove the graphical adjustments
			nTempPosY = vScreenPos.Y - base.Location.Y - m_nUpperLeftY - m_cScrollWidth;
			//Add in however much were off screen
			nTempPosY += nTopOffset;
			//Add in our Y offset
			nTempPosY -= nYModifier;
			nGamePosY = nTempPosY;




			//Ok new plan... this isn't work.  Lets try intersecting the line and figuring out the diagonal
			//lines so we can tell which "vane" we are in.
			//Step 1.)  Get m
			nM = (double)Game.m_cSQRH_TRN / (double)Game.m_cSQRW_TRN;
			//Step 2.)  Get b.... y-Mx = b
			nB = nGamePosY - nM * nGamePosX;
			//Step 3.)  Get the x-Intercept, -b / m = x
			nXIntercept1 = -nB / nM;
			//This tells us where it hits the X axis, now translate that to our "vane"
			nUpperLeftToLowerRightVane = (long)( nXIntercept1 / nWRadius );
			//Now convert the two sub-vanes into a single vein
			if( nUpperLeftToLowerRightVane % 2 != 0 )
			{
				if( nUpperLeftToLowerRightVane > 0 )
				{
					nUpperLeftToLowerRightVane++;
				}
				else
				{
					nUpperLeftToLowerRightVane--;
				}
			}
			nUpperLeftToLowerRightVane /= 2;


			//Step 1.)  Get m
			nM = (double)Game.m_cSQRH_TRN / -(double)Game.m_cSQRW_TRN;
			//Step 2.)  Get b.... y-Mx = b
			nB = nGamePosY - nM * nGamePosX;
			//Step 3.)  Get the x-Intercept, -b / m = x
			nXIntercept2 = -nB / nM;
			//This tells us where it hits the X axis, now translate that to our "vane"
			nUpperRightToLowerLeftVane = (long)( nXIntercept2 / nWRadius ) - 1;
			nUpperRightToLowerLeftVane /= 2;


			nScreenX = nUpperLeftToLowerRightVane*2 + Math.Abs(nUpperLeftToLowerRightVane-nUpperRightToLowerLeftVane);
			nScreenY = Math.Abs( nUpperLeftToLowerRightVane-nUpperRightToLowerLeftVane ) / 2;
		}
		public System.Drawing.Rectangle GetScrBuildingPosFromSquare( long nX,long nY )
		{
			System.Drawing.Rectangle oTrgRect;
			double nRatio = 0;

			oTrgRect = GetScrTerrainPosFromSquare( nX,nY );

			nRatio = (double)Game.m_cSQRH_TRN / (double)Game.m_cSQRH_BLD;
			oTrgRect.Y -= (int)(16 * m_nZoomFactor);//(int)((double)oTrgRect.Height / nRatio);
			oTrgRect.Height += (int)(16 * m_nZoomFactor);

			return( oTrgRect );
		}
		public System.Drawing.Rectangle GetScrTerrainPosFromSquare( long nX,long nY )
		{
			System.Drawing.Rectangle oDrawRect;
			System.Drawing.Rectangle oTrgRect = new System.Drawing.Rectangle( 0,0,0,0 );
			System.Drawing.Rectangle oSrcRect = new System.Drawing.Rectangle( 0,0,0,0 );
			float nYModifier = 0;
			double nTotalWidth, nTotalHeight;
			double nPercentW = 0, nPercentH = 0;
			double nLeftOffset, nTopOffset;
			double nTrnWidth = (Game.m_cSQRW_TRN*m_nZoomFactor);
			double nTrnHeight = (Game.m_cSQRH_TRN*m_nZoomFactor);
			int nIslandWidth = m_oIsland.Width - 1;
			int nIslandHeight = m_oIsland.Height - 1;


			//Draw the black rendering area
			oDrawRect = GetWindowRenderArea();

			//Setup the location based upon the progress bar
			nTotalWidth = nIslandWidth * ( nTrnWidth / 2.0f ) - oDrawRect.Width;
			if( m_oHorzScrollBarControl.EndRange - m_oHorzScrollBarControl.PageSize == 0 )
			{
				nLeftOffset = nTrnWidth / 2.0f;
			}
			else
			{
				nPercentW = (float)m_oHorzScrollBarControl.TrackPosition / 
							( m_oHorzScrollBarControl.EndRange - m_oHorzScrollBarControl.PageSize );
				nLeftOffset = nTotalWidth * nPercentW + ( nTrnWidth / 2.0f );
				nLeftOffset = Math.Floor( nLeftOffset );
			}

			nTotalHeight = nIslandHeight * nTrnHeight + nTrnHeight / 2.0f - oDrawRect.Height;
			if( m_oVertScrollBarControl.EndRange - m_oVertScrollBarControl.PageSize == 0 )
			{
				nTopOffset = nTrnHeight / 2.0f;
			}
			else
			{
				nPercentH = (float)m_oVertScrollBarControl.TrackPosition / 
							( m_oVertScrollBarControl.EndRange - m_oVertScrollBarControl.PageSize );
				nTopOffset = nTotalHeight * nPercentH + ( nTrnHeight / 2.0f );
				nTopOffset = Math.Floor( nTopOffset );
			}

			//Find our offset based on our X and Y.  Every other x is half its high farther down.
			nYModifier = 0;
			if( nX % 2 != 0 )
			{
				nYModifier = (float)(nTrnHeight / 2.0);
			}

			//Calculate the drawing locations
			oTrgRect.X = (int)Math.Floor(base.Location.X + m_nUpperLeftX + ( nTrnWidth / 2.0f ) * nX + m_cBorder_LeftWidth - nLeftOffset );
			oTrgRect.Y = (int)Math.Floor(base.Location.Y + m_nUpperLeftY + ( nTrnHeight * nY ) + nYModifier + m_cBorder_TopWidth - nTopOffset );

			oTrgRect.Width = (int)Math.Floor(Game.m_cSQRW_TRN * m_nZoomFactor);
			oTrgRect.Height = (int)Math.Floor(Game.m_cSQRH_TRN * m_nZoomFactor);


			return( oTrgRect );
		}


		public override void OnInitialize()
		{
			Point oArrow = new Point( 0,0 );
			double nTrnWidth = (Game.m_cSQRW_TRN*m_nZoomFactor);
			double nTrnHeight = (Game.m_cSQRH_TRN*m_nZoomFactor);


			m_oHorzScrollBarControl = new DSHorzScrollBar( base.Forms,this );
			m_oHorzScrollBarControl.Visible = true;
			m_oHorzScrollBarControl.Name = this.Name + "_HorzScrollBar";
			//m_oHorzScrollBarControl.SetTrackRange( 0,m_oIsland.Width );
			m_oHorzScrollBarControl.PageSize = (int)nTrnWidth;
			base.AddControl( m_oHorzScrollBarControl );

			m_oVertScrollBarControl = new DSVertScrollBar( base.Forms,this );
			m_oVertScrollBarControl.Visible = true;
			m_oVertScrollBarControl.Name = this.Name + "_VertScrollBar";
			//m_oVertScrollBarControl.SetTrackRange( 0,m_oIsland.Height );
			m_oVertScrollBarControl.PageSize = (int)nTrnHeight;
			base.AddControl( m_oVertScrollBarControl );

			CheckScrollBarSizes();

			//Set our default positions
			oArrow = m_oIsland.GetArrowCorner();
			if( oArrow.X > 0 )
			{
				m_oHorzScrollBarControl.TrackPosition = m_oHorzScrollBarControl.EndRange;
			}
			if( oArrow.Y > 0 )
			{
				m_oVertScrollBarControl.TrackPosition = m_oVertScrollBarControl.EndRange;
			}
		}

		public override void OnResize()
		{
			int nIslandWidth = m_oIsland.Width - 1;
			int nIslandHeight = m_oIsland.Height - 1;
			double nTrnWidth = (Game.m_cSQRW_TRN*m_nZoomFactor);
			double nTrnHeight = (Game.m_cSQRH_TRN*m_nZoomFactor);
			double nTotalWidth, nTotalHeight;
			System.Drawing.Rectangle oDrawRect;


			base.OnResize();

			//Get the black rendering area
			if( m_oApp != null )
			{
				oDrawRect = GetWindowRenderArea();
				nTotalWidth = nIslandWidth * ( nTrnWidth / 2.0f );
				nTotalHeight = nIslandHeight * nTrnHeight + nTrnHeight / 2.0f;
				if( oDrawRect.Width > nTotalWidth || oDrawRect.Height > nTotalHeight )
				{
					this.Size = new Vector2( (float)DSMisc.Min( oDrawRect.Width,nTotalWidth )  + m_cBorder_LeftWidth + m_cBorder_RightWidth + m_cScrollWidth,
											 (float)DSMisc.Min( oDrawRect.Height,nTotalHeight ) + m_cBorder_TopWidth + m_cBorder_BottomWidth + m_cScrollWidth );
				}
			}

			if( this.Size.X < m_cISLANDMINWIDTH || this.Size.Y < m_cISLANDMINHEIGHT )
			{
				this.Size = new Vector2( DSMisc.Max( this.Size.X,m_cISLANDMINWIDTH ),
										 DSMisc.Max( this.Size.Y,m_cISLANDMINHEIGHT ) );
			}

			if( m_oHorzScrollBarControl != null )
			{
				m_oHorzScrollBarControl.Location = new System.Drawing.Point( (int)m_cBorder_LeftWidth,
																			 (int)(this.Size.Y - m_cScrollWidth - m_cBorder_BottomWidth) );
				m_oHorzScrollBarControl.Size = new Vector2( this.Size.X - m_cBorder_LeftWidth - m_cBorder_RightWidth /* - m_cScrollWidth*/,
															m_cScrollWidth );
			}
			if( m_oVertScrollBarControl != null )
			{
				m_oVertScrollBarControl.Location = new System.Drawing.Point( (int)(this.Size.X - m_cScrollWidth - m_cBorder_RightWidth),
																			 (int)m_cBorder_TopWidth );
				m_oVertScrollBarControl.Size = new Vector2( m_cScrollWidth,
															this.Size.Y - m_cScrollWidth - m_cBorder_TopWidth - m_cBorder_BottomWidth );
			}

			CheckScrollBarSizes();
		}

		public override void OnDragDrop()
		{
			string sFailureMessage = "";
			string sPayMessage = "";
			bool bAntiMatter = false;
			bool bSuccess = false;
			bool bBuildingIsBeingDragged = false;
			bool bJustAttacked = false;
			bool bJustBuilt = false;
			long nScreenX = 0, nScreenY = 0;
			long nGobBuildingKey = -1;
			long nTerrainIndex = -1;
			long nMoneyNeeded = 0;
			Point oSquarePoint = new Point( 0,0 );
			Square oSquare = null;
			MMAttack oMMAttack = null;
			MMIslandForm oMyIsland = null;			
			MMPlaceBaseForm oBPlaceForm = null;
			DSSortedList oMissles = null;
			DSSortedList oList = null;
			MissleAttack oLoopAttack = null;
			Point oEndPoint = new Point( 0,0 );
			bool[] oKeyboardState = null;
			
try
{
			//Find the square were dropping on
			GetSquareFromScrPos( m_oGameEngine.MouseCursor,ref nScreenX,ref nScreenY );
			m_oApp.DSGameEngine.DirectInput.GetKeyboardState( ref oKeyboardState );
			oMyIsland = m_oApp.GetMyIsland();

			if( m_oApp.GameState == enumStates.MapEditor )
			{
				if( MMPurchaseForm.IsDragingPurchase( m_oForms ) == true )
				{
					//Find the building they are dropping on us
					nGobBuildingKey = MMPurchaseForm.GetDragingPurchase( m_oForms );
				
					//Place the building here and finish the purchase
					m_oIsland.SetSquare( nGobBuildingKey,nScreenX,nScreenY );
					oSquare = m_oIsland.GetSquare( nScreenX,nScreenY );
					oSquare.Strength = (double)Game.GetBldStat( nGobBuildingKey,Game.m_cGOB_BLDSTATS_STRENGTH_CLMN );

					//Bulldoze it... first check to see if its a composite building
					oList = m_oIsland.GetCompositeBuilding( oSquare.X,oSquare.Y );
					if( oList.Count > 0 )
					{
						for( int i=0 ; i<oList.Count ; i++ )
						{
							oEndPoint = (Point)oList.GetByIndex( i );
							oSquare = m_oIsland.GetSquare( oEndPoint.X,oEndPoint.Y );
							oSquare.SquareStatus = enumSquareStatus.Built;
						}
					}
					else
					{
						oSquare.SquareStatus = enumSquareStatus.Built;
					}
				}
				else if( MMPlaceTerrainForm.IsDragingTerrain( m_oForms ) == true )
				{
					//Find the terrain they are dropping on us
					nTerrainIndex = MMPlaceTerrainForm.GetDragingTerrain( m_oForms );
				
					//Place the building here
					m_oIsland.GetSquare( nScreenX,nScreenY ).SquareType = (int)nTerrainIndex;
				}
			}
			//This means they are dropping a base on us...
			else if( MMPlaceBaseForm.IsDragingBasePlacement( m_oForms ) == true &&
					 m_oIsland.IsMyIsland() == true )
			{
				//Can we build here?
				if( m_oIsland.CanBuildOnSquare( Game.m_cGOB_BASE_KEY,nScreenX,nScreenY ) == true )
				{
					//Find the form and drop the count of bases to place
					oBPlaceForm = (MMPlaceBaseForm)m_oForms.GetForm( Game.m_cFRM_BASEPLACE );
					oBPlaceForm.BasesToPlace--;

					//Place the base here
					oSquare = m_oIsland.GetSquare( nScreenX,nScreenY );
					oSquare.SetSquare( Game.m_cGOB_BASE_KEY );

					//Make the sound
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_BASEPLACE );

					//Did we finish placing our bases?
					if( oBPlaceForm.BasesToPlace == 0 )
					{
						m_oApp.DonePlacingBases_ClientAndHost();
					}
				}
				else
				{
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
				}
			}
			//This means they bought something
			else if( MMPurchaseForm.IsDragingPurchase( m_oForms ) == true &&
				     m_oIsland.IsMyIsland() == true )
			{
				//Find the building they are dropping on us
				nGobBuildingKey = MMPurchaseForm.GetDragingPurchase( m_oForms );
				//Get the price just in case
				nMoneyNeeded = Convert.ToInt64( Game.GetBldStat( nGobBuildingKey,Game.m_cGOB_BLDSTATS_COST_CLMN ) );

				//Can we build here?
				if( m_oIsland.CanBuildOnSquare( nGobBuildingKey,nScreenX,nScreenY ) == false )
				{
					m_oApp.UpdateStatus( Game.m_cALERT_ACTION + "Unable to build on this square" );
					m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
				}
				else if( m_oGame.CanIAffordCredits( oMyIsland.Island,nMoneyNeeded,ref sFailureMessage ) == false )
				{
					m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sFailureMessage );
					m_oApp.DSGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
				}
				else
				{
					bJustBuilt = true;

					//Take the money away
					nMoneyNeeded = Game.GetPriceOfBuilding( nGobBuildingKey );
					sPayMessage = m_oApp.Game.PayCredits( m_oIsland,nMoneyNeeded );
					if( sPayMessage.Length > 0 )
					{
						m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sPayMessage );
						//m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
					}
					//else
					{
						//Add our purchased message
						oSquare = m_oIsland.GetSquare( nScreenX,nScreenY );
						oSquare.AddScrollingMessage( "-$" + nMoneyNeeded.ToString(),System.Drawing.Color.Red );

						//Place the building here
						m_oIsland.SetSquare( nGobBuildingKey,nScreenX,nScreenY );

						//Send an update
						m_oApp.SendIslandUpdate( m_oIsland );
					}
				}
			}
			//If we did drag somewhere, and they aren't our team-mate, fire
			else if( nScreenX != m_nDragSourceX || nScreenY != m_nDragSourceY )
			{
				if( m_oGame.OnSameTeam( m_oIsland,m_oApp.GetMyIsland().Island ) == false ||
					m_oIsland == m_oApp.GetMyIsland().Island )
				{
					//Get our source X and Y from our island
					for( int i=0 ; i<m_oApp.SelectedSquares.Count ; i++ )
					{
						oSquarePoint = (Point)m_oApp.SelectedSquares.GetByIndex( i );
						oSquare = oMyIsland.Island.GetSquare( oSquarePoint.X,oSquarePoint.Y );

						//This means we are dropping a missle on them
						//This means we are dropping an anti-matter missle on them
						if( oSquare.Armed == true &&
							oSquare.SquareStatus == enumSquareStatus.Built &&
							(
								(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESANTIMATTER ) == true ||
								(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMISSLES_CLMN ) == true 
								//MMIslandForm.IsDragingAntiMatter( m_oForms ) == true ||
								//MMIslandForm.IsDragingMissle( m_oForms ) == true 
							)
							&&
							(
								m_oIsland.IsMyIsland() == false ||
								m_oGame.Debug_CanAttackOurselves == true 
							)
						  )
						{
							//bAntiMatter = ( MMIslandForm.IsDragingAntiMatter( m_oForms ) == true );
							bAntiMatter = (bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESANTIMATTER );

							//Launch the attack
							oMissles = m_oGame.AddMissleAttacks( m_oApp.GetMyIsland().Island.GlobalID,
											//oMyIsland.DragDropX, oMyIsland.DragDropY,
											oSquarePoint.X,oSquarePoint.Y,
											m_oIsland.GlobalID, nScreenX, nScreenY,
											(long)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_NUMSHOTS_CLMN ),
											!bAntiMatter,bAntiMatter,
											(long)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_EXPLOSIONRADIUS ),
											out bSuccess,out sFailureMessage );

							if( bSuccess == false )
							{
								m_oApp.UpdateStatus( Game.m_cALERT_ACTION + sFailureMessage );
							}
							else
							{
								oSquare.FireWeapon();

								//Send an update
								for( int nLoopMissleIndex=0 ; nLoopMissleIndex<oMissles.Count ; nLoopMissleIndex++ )
								{
									oLoopAttack = (MissleAttack)oMissles.GetByIndex( nLoopMissleIndex );
									m_oApp.SendMMMsg( enumNetMsg.MissleAttack,oLoopAttack.Serialize() );
									m_oGame.MissleAttacks.Add( oLoopAttack.GlobalID,oLoopAttack );
								}
							}

							bJustAttacked = true;
						}
							//This means we are dropping a Metal Marine on them
						else if( //MMIslandForm.IsDragingMM( m_oForms ) == true &&
								oSquare.Armed == true &&
								(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true 
								&&
								(
									m_oIsland.IsMyIsland() == false ||
									m_oGame.Debug_CanAttackOurselves == true 
								)
							  )
						{
							//Get our source X and Y from our island
							oMyIsland = m_oApp.GetMyIsland();

							//Launch the attack
							oMMAttack = m_oGame.AttackWithMetalMarine( m_oApp.GetMyIsland().Island.GlobalID,
								//oMyIsland.DragDropX, oMyIsland.DragDropY,
								oSquarePoint.X,oSquarePoint.Y,
								m_oIsland.GlobalID, nScreenX, nScreenY,
								oSquare.MMStrength,
								(double)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_MMOFFENSE_CLMN ),
								out bSuccess,out sFailureMessage );

							if( bSuccess == false )
							{
								m_oApp.UpdateStatus( Game.m_cALERT_ACTION + sFailureMessage );
							}
							else
							{
								oSquare.FireWeapon();

								//Send an update
								m_oApp.SendMMAttackUpdate( oMMAttack );
							}

							bJustAttacked = true;
						}
					}
				}
				else
				{
					m_oApp.Game.AlertManager.AddMessage( "You are on the same team as this player and cannot attack them." );
				}
			}


			//Do we keep dragging?
			oBPlaceForm = (MMPlaceBaseForm)m_oForms.GetForm( Game.m_cFRM_BASEPLACE );
			bBuildingIsBeingDragged = BuildingIsBeingDragged( ref nGobBuildingKey );
			//Now make the determination
			if( 
				(
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] != true && 
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] != true &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] != true && 
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] != true 
				)
				||
				(
					bBuildingIsBeingDragged == true &&
					nGobBuildingKey == Game.m_cGOB_BASE_KEY &&
					oBPlaceForm.BasesToPlace <= 0
				)
			  )
			{
				if( bJustAttacked == false && bJustBuilt == true &&
					( bBuildingIsBeingDragged == false || nGobBuildingKey != Game.m_cGOB_BASE_KEY ) )
				{
					oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
					m_oApp.SelectedSquares = new DSSortedList();
					m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
				}
				
				base.OnDragDrop();
			}
}
catch( System.Exception oEx )
{
	DSMisc.ShowErrors( oEx );
}
		}

		public override void OnMoved()
		{
			base.OnMoved();
			m_oApp.SaveINIFile();
		}
		public override bool OnMouseDown(Vector2 vMousePosInFormSpace, long nButton)
		{
			Vector2 vMousePosInScreenSpace = new Vector2( vMousePosInFormSpace.X + this.Location.X,
														  vMousePosInFormSpace.Y + this.Location.Y );
			bool[] oKeyboardState = null;
			bool bActionWasUsed = false;
			bool bBuildingIsBeingDragged = false;
			bool bDoubleClick = false;
			long nScreenX = 0;
			long nScreenY = 0;			
			long nGobBuildingKey = 0;
			Square oSquare = null;
			Square oLoopSquare = null;
			System.Drawing.Rectangle oDrawRect;
			MMPopupForm oNewPopup = null;
			Point oSquarePoint = new Point( 0,0 );
			TimeSpan oSpan = TimeSpan.MinValue;

try
{
			if( MousePosOnMenuBorder( vMousePosInScreenSpace ) == true )
			{
				return( false );
			}

			base.OnMouseDown( vMousePosInFormSpace,nButton );

			//If not everything has been created then bail
			if( m_oHorzScrollBarControl == null || m_oVertScrollBarControl == null )
			{
				return( true );
			}


			#region Screw Functionality
			//Did they click on our screw?
			if( vMousePosInFormSpace.X + this.Location.X >= this.Right - m_cScrewLeft_DistFromRight &&
				vMousePosInFormSpace.X + this.Location.X <= this.Right - m_cScrewLeft_DistFromRight + m_cScrewWidth &&
				vMousePosInFormSpace.Y + this.Location.Y >= this.Top + m_cScrewTop_DistFromTop &&
				vMousePosInFormSpace.Y + this.Location.Y <= this.Top + m_cScrewTop_DistFromTop + m_cScrewHeight )
			{
				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CLICK );

				//Don't shrink or grow if we are zooming
				m_oApp.DSGameEngine.DirectInput.GetKeyboardState( ref oKeyboardState );
				if( oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == false &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == false &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftAlt ] == false &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightAlt ] == false &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == false &&
					oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == false )
				{
					if( m_bShrinking == true ||
						( m_bGrowing == false && m_oOrigSize != Vector2.Empty ) )
					{
						m_bShrinking = false;
						m_bGrowing = true;
					}
					else if( m_bGrowing == true || m_oOrigSize == Vector2.Empty )
					{
						m_bShrinking = true;
						m_bGrowing = false;

						if( m_oOrigSize == Vector2.Empty )
						{
							m_oOrigSize = this.Size;
						}
					}
				}
			}
			#endregion

			//Get the key state
			m_oGame.GameEngine.DirectInput.GetKeyboardState( ref oKeyboardState );

			//Get the black rendering area
			oDrawRect = GetWindowRenderArea();
			GetSquareFromScrPos( new Vector2( this.Location.X + vMousePosInFormSpace.X,
												this.Location.Y + vMousePosInFormSpace.Y ),
									ref nScreenX,ref nScreenY );
			oSquare = m_oIsland.GetSquare( nScreenX,nScreenY );

			//Just in case, find out if we are dragging things
			bBuildingIsBeingDragged = BuildingIsBeingDragged( ref nGobBuildingKey );

			#region Double Click Functionality
			//Find out if this was a double click or not
			oSpan = DateTime.Now - m_dtLastMouseDown;
			m_dtLastMouseDown = DateTime.Now;
			if( oSpan.TotalMilliseconds < 300 &&
				m_dtLastMouseDownX == nScreenX && m_dtLastMouseDownY == nScreenY )
			{
				bDoubleClick = true;
				//We set this way back so the next click won't register as a double click
				m_dtLastMouseDown = DateTime.MinValue;
			}				
			m_dtLastMouseDownX = nScreenX;
			m_dtLastMouseDownY = nScreenY;
			#endregion


			if( bBuildingIsBeingDragged == true )
			{
				//Do nothing... we want drag and drop to handle this
			}
			//Did we click on a square in this island?  And is it our island and is it a weapon?
			else if( oDrawRect.Contains( (int)( this.Location.X + vMousePosInFormSpace.X ),
										 (int)( this.Location.Y + vMousePosInFormSpace.Y ) ) == true &&
					nButton == 0 && 
					(
						m_oApp.GameState != enumStates.InGame ||
						m_oIsland.IsMyIsland() == true 
					)
					&&
					(
						(
							oSquare.SquareStatus == enumSquareStatus.Built &&
							(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_AIATTACKS_CLMN ) == true 
						) 
						||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == true || 
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == true ||
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true || 
						oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true 
						||
						bDoubleClick == true
					)
				   )
			{
				if( m_oIsland.BasesPlaced == true )
				{
					//No matter what if we double clicked override all else to select things
					if( bDoubleClick == true /*&&
						oSquare.SquareStatus == enumSquareStatus.Built &&
						(
							(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMISSLES_CLMN ) == true ||
							(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true ||
							(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESANTIMATTER ) == true 
						)*/
					  )
					{
						//Go through and select all buildings of this type
						for( int nX=0 ; nX<m_oIsland.Width ; nX++ )
						{
							for( int nY=0 ; nY<m_oIsland.Height ; nY++ )
							{
								oLoopSquare = m_oIsland.GetSquare( nX,nY );

								if( oSquare.SquareStatus == enumSquareStatus.Built &&
									oLoopSquare.SquareStatus == enumSquareStatus.Built &&
									oLoopSquare.GobBuildingKey == oSquare.GobBuildingKey &&
									m_oApp.SelectedSquares.ContainsKey( nX.ToString() + "," + nY.ToString() ) == false )
								{
									oSquarePoint = new Point( (int)nX,(int)nY );
									m_oApp.SelectedSquares.Add( nX.ToString() + "," + nY.ToString(),oSquarePoint );
								}
								else if( oSquare.SquareStatus == enumSquareStatus.Destroyed && 
										 oSquare.ScarPercent == 1 &&
										 oLoopSquare.SquareStatus == enumSquareStatus.Destroyed && 
										 oLoopSquare.ScarPercent == 1 )
								{
									oSquarePoint = new Point( (int)nX,(int)nY );
									m_oApp.SelectedSquares.Add( nX.ToString() + "," + nY.ToString(),oSquarePoint );
								}
								else if( oSquare.SquareStatus == enumSquareStatus.Destroyed && 
										 oSquare.ScarPercent < 1 &&
										 oLoopSquare.SquareStatus == enumSquareStatus.Destroyed && 
										 oLoopSquare.ScarPercent < 1 )
								{
									oSquarePoint = new Point( (int)nX,(int)nY );
									m_oApp.SelectedSquares.Add( nX.ToString() + "," + nY.ToString(),oSquarePoint );
								}
							}
						}
					}
					//If these keys are down then we just add to our list of selected squares
					else if( oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == true || 
								oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == true ||
								oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true || 
								oKeyboardState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true )
					{
						if( m_oApp.SelectedSquares.ContainsKey( nScreenX.ToString() + "," + nScreenY.ToString() ) == true )
						{
							m_oApp.SelectedSquares.Remove( nScreenX.ToString() + "," + nScreenY.ToString() );
						}
						else if( oSquare.SquareStatus == enumSquareStatus.Built /*&&
								(
									(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMISSLES_CLMN ) == true ||
									(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true ||
									(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESANTIMATTER ) == true 
								)*/
							   )
						{							
							oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
							m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
						}
						bActionWasUsed = true;
					}
					//If we already have this guy do nothing
					else if( m_oApp.SelectedSquares.ContainsKey( nScreenX.ToString() + "," + nScreenY.ToString() ) == true )
					{
						this.DoDragDrop( "Something" );
						bActionWasUsed = true;
					}
					else if( oSquare.SquareStatus == enumSquareStatus.Built )
					{
						//Are they dragging a missle bay?				
						this.DoDragDrop( "Something" );
						oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
						m_oApp.SelectedSquares = new DSSortedList();
						m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
						bActionWasUsed = true;
					}
					/*else if( (bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMISSLES_CLMN ) == true )
					{
						//Are they dragging a missle bay?				
						this.DoDragDrop( Game.m_cDRAGDROP_MISSLE );
						oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
						m_oApp.SelectedSquares = new DSSortedList();
						m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
						bActionWasUsed = true;
					}
					else if( (bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true )
					{
						//Are they dragging a missle bay?				
						this.DoDragDrop( Game.m_cDRAGDROP_METALMARINE );
						oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
						m_oApp.SelectedSquares = new DSSortedList();
						m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
						bActionWasUsed = true;
					}
					else if( (bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESANTIMATTER ) == true )
					{
						//Are they dragging an antimatter missle?
						this.DoDragDrop( Game.m_cDRAGDROP_ANTIMATTER );
						oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
						m_oApp.SelectedSquares = new DSSortedList();
						m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
						bActionWasUsed = true;
					}	*/
					else
					{
						m_oApp.SelectedSquares = new DSSortedList();
						bActionWasUsed = true;
					}
					m_nDragSourceX = nScreenX;
					m_nDragSourceY = nScreenY;
				}
				else if( bBuildingIsBeingDragged == false || nGobBuildingKey != Game.m_cGOB_BASE_KEY )
				{
					m_oApp.UpdateStatus( Game.m_cALERT_ACTION + "You must place your bases before attacking" );
				}
			}
			//Did we right click on one of our buildings?
			else if( oDrawRect.Contains( (int)( this.Location.X + vMousePosInFormSpace.X ),
										 (int)( this.Location.Y + vMousePosInFormSpace.Y ) ) == true &&
 					 nButton == 1 && 
					 oSquare.GobBuildingKey != Game.m_cGOB_BASE_KEY &&
					 (
						m_oApp.GameState != enumStates.InGame ||
						m_oIsland.IsMyIsland() == true
					 ) &&
				     ( oSquare.SquareStatus != enumSquareStatus.Empty || m_oApp.GameState == enumStates.MapEditor )
				   )
			{
				//If we right clicked on an existing selected item use that, else pick a new one
				if( m_oApp.SelectedSquares.Contains( nScreenX.ToString() + "," + nScreenY.ToString() ) == false )
				{
					oSquarePoint = new Point( (int)nScreenX,(int)nScreenY );
					m_oApp.SelectedSquares = new DSSortedList();
					m_oApp.SelectedSquares.Add( nScreenX.ToString() + "," + nScreenY.ToString(),oSquarePoint );
				}

				if( m_oIsland.BasesPlaced == true || m_oApp.GameState == enumStates.MapEditor )
				{
					//Start by removing the popup menu
					m_oGameEngine.Forms.Remove( Game.m_cFRM_POPUP );

					//Make a new menu to popup
					oNewPopup = new MMPopupForm( m_oGameEngine.Forms );
					oNewPopup.Name = Game.m_cFRM_POPUP;
					oNewPopup.App = App;
					oNewPopup.Left = (int)( this.Location.X + vMousePosInFormSpace.X );
					oNewPopup.Top = (int)( this.Location.Y + vMousePosInFormSpace.Y );
					oNewPopup.GameEngine = m_oGameEngine;
					oNewPopup.SetupForSquare( m_oIsland,m_oApp.SelectedSquares );
					m_oGameEngine.Forms.Add( oNewPopup );
				}
				else
				{
					m_oApp.UpdateStatus( Game.m_cALERT_ACTION + "You must place your bases before you can upgrade buildings" );
				}

				bActionWasUsed = true;
			}
			//Are we dragging by clicking in water or an unbilt square?
			else if( oDrawRect.Contains( (int)( this.Location.X + vMousePosInFormSpace.X ),
											(int)( this.Location.Y + vMousePosInFormSpace.Y ) ) == true &&
						nButton == 0 && 
						oSquare.SquareStatus != enumSquareStatus.Building &&
						(
						oSquare.SquareStatus != enumSquareStatus.Built ||
						(bool)Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_AIATTACKS_CLMN ) == false
						)
					)
			{
				//Ok start the drag
				m_oApp.SelectedSquares = new DSSortedList();
				m_vDragMouseDown = vMousePosInFormSpace;
				m_bDraggingIsland = true;
			}

}
catch( System.Exception oEx )
{
	DSMisc.ShowErrors( oEx );
}

			return( bActionWasUsed );
		}
		public override bool OnMouseMove(Vector2 vMousePosInControlSpace, bool[] baButtons)
		{
			Vector2 vMousePosInScreenSpace = new Vector2( vMousePosInControlSpace.X + this.Location.X,
														  vMousePosInControlSpace.Y + this.Location.Y );


			if( MousePosOnMenuBorder( vMousePosInScreenSpace ) == true )
			{
				return( false );
			}

			base.OnMouseMove( vMousePosInControlSpace,baButtons );

			if( m_bDraggingIsland == true )
			{
				if( m_oHorzScrollBarControl != null )
				{
					m_oHorzScrollBarControl.TrackPosition -= (int)( ( vMousePosInControlSpace.X - m_vDragMouseDown.X ) * 1.5 );
				}
				if( m_oVertScrollBarControl != null )
				{
					m_oVertScrollBarControl.TrackPosition -= (int)( ( vMousePosInControlSpace.Y - m_vDragMouseDown.Y ) * 1.5 );
				}

				m_vDragMouseDown = vMousePosInControlSpace;
			}

			return( true );
		}
		public override bool OnMouseUp(Vector2 vMousePosInControlSpace, long nButton)
		{
			bool bMouseActionClicked = false;
			Vector2 vMousePosInScreenSpace = new Vector2( vMousePosInControlSpace.X + this.Location.X,
														  vMousePosInControlSpace.Y + this.Location.Y );

			if( MousePosOnMenuBorder( vMousePosInScreenSpace ) == true )
			{
				bMouseActionClicked = false;
			}
			else
			{
				base.OnMouseUp( vMousePosInControlSpace,nButton );
				m_bDraggingIsland = false;
				bMouseActionClicked = !MousePosOnMenuBorder( vMousePosInScreenSpace );
			}

			return( bMouseActionClicked );
		}
		private bool MousePosOnMenuBorder( Vector2 vMousePosInScreenSpace )
		{
			bool bRetVal = false;

			if( vMousePosInScreenSpace.X <= 126 && vMousePosInScreenSpace.Y <= 25 )
			{
				bRetVal = true;
			}
			if( vMousePosInScreenSpace.X <= 125 - ( vMousePosInScreenSpace.Y - 25 ) &&
				vMousePosInScreenSpace.Y <= 35 )
			{
				bRetVal = true;
			}			
			if( vMousePosInScreenSpace.X <= 99 && vMousePosInScreenSpace.Y <= 41 )
			{
				bRetVal = true;
			}
			if( vMousePosInScreenSpace.X <= 45 - ( vMousePosInScreenSpace.Y - 42 ) &&
				vMousePosInScreenSpace.Y <= 82 )
			{
				bRetVal = true;
			}			

			return( bRetVal );
		}


		public override bool OnKeyUp(Key oKey, bool[] oState)
		{
			bool bRetVal = base.OnKeyUp(oKey, oState);

			//If the mouse was up then undo the drop
			if( m_oGameEngine.DirectInput.CurrentMouseButtonState[ 0 ] == false &&
				(
					oKey == Microsoft.DirectX.DirectInput.Key.LeftShift || 
					oKey == Microsoft.DirectX.DirectInput.Key.RightShift ||
					oKey == Microsoft.DirectX.DirectInput.Key.LeftControl || 
					oKey == Microsoft.DirectX.DirectInput.Key.RightControl 
				) 				
			  )
			{
				m_oGameEngine.Forms.DragAndDropInProgress = false;
			}

			return( bRetVal );
		}


		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( ( vMousePosInFormSpace.X >= this.Size.X - 48 && vMousePosInFormSpace.X <= this.Size.X - 48 + 10 ) &&
				( vMousePosInFormSpace.Y >= this.Size.Y - 10 && vMousePosInFormSpace.Y <= this.Size.Y - 10 + 10 ) &&
				m_oOrigSize == Vector2.Empty )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( IsResizeHotSpot( vMousePosInFormSpace ) == false &&
				(
					vMousePosInFormSpace.Y <= m_cBorder_TopWidth * 1.5 || 
					vMousePosInFormSpace.Y >= this.Size.Y - m_cBorder_TopWidth * 1.5 || 
					vMousePosInFormSpace.X <= Game.m_cBORDER_BEISH_COLORSTRIP_WIDTH + Game.m_cBORDER_BEISH_COLORSTRIP_LEFT * 2 ||
					(
						vMousePosInFormSpace.X >= this.Size.X - 48 &&
						vMousePosInFormSpace.X <= this.Size.X - 48 + 12 
					)
					||
					( 
						vMousePosInFormSpace.X >= this.Size.X - 48 && 
						vMousePosInFormSpace.Y <= 64 
					) 
					||
					m_oOrigSize != Vector2.Empty 
				)
			  )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}

		public override bool ContainsPoint( System.Drawing.Point oPointInAppSpace ) 
		{ 
			if( oPointInAppSpace.X >= m_vPos.X && oPointInAppSpace.Y >= m_vPos.Y &&
				(
					oPointInAppSpace.X <= m_vPos.X + m_vSize.X - 38 &&
					oPointInAppSpace.Y <= m_vPos.Y + m_vSize.Y 
				)
				||
				(
					oPointInAppSpace.X > m_vPos.X + m_vSize.X - 38 &&
					oPointInAppSpace.X <= m_vPos.X + m_vSize.X &&
					oPointInAppSpace.Y < m_vPos.Y + 64 - ( oPointInAppSpace.X - m_vPos.X - m_vSize.X + 38 ) &&
					oPointInAppSpace.Y >= m_vPos.Y
				)
			  )
			{
				return( true ); 
			}
			else
			{
				return( false ); 
			}			
		}

		

		#region Properties
		public bool Minimized
		{
			get
			{
				return( m_bShrinking || m_oOrigSize != Vector2.Empty );
			}
		}
		public Island Island
		{
			set
			{
				m_oIsland = value;
				CheckScrollBarSizes();
			}
			get
			{
				return( m_oIsland );
			}
		}
		public DSGameEngine GameEngine
		{
			get
			{
				return( m_oGameEngine );
			}
			set
			{
				m_oGameEngine = value;
			}
		}
		public Game Game
		{
			get
			{
				return( m_oGame );
			}
			set
			{
				m_oGame = value;
			}
		}
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		/*public long DragDropX
		{
			get
			{
				return( m_nDragSourceX );
			}
		}
		public long DragDropY
		{
			get
			{
				return( m_nDragSourceY );
			}
		}*/
		public double ZoomFactor
		{
			get
			{
				return( m_nZoomFactor );
			}
			set
			{
				m_nZoomFactor = value;
			}
		}
		public bool FormHasBeenPositioned
		{
			get
			{
				return( m_bFormHasBeenPositioned );
			}
			set
			{
				m_bFormHasBeenPositioned = value;
			}
		}
		#endregion
	}
	#endregion

	#region PlaceTerrain Form
	public class MMPlaceTerrainForm : DSForm 
	{
		#region Properties
		private MetalMarines m_oApp = null;
		#endregion


		public MMPlaceTerrainForm( DSForms oForms ) : base( oForms )
		{
		}


		public override void Render()
		{
			string sGraphicKey = "";
			int nCount = 0;
			long nX = 0;
			long nY = 0;
			System.Drawing.Rectangle oTrgRect;
			System.Drawing.Rectangle oSrcRect;
			System.Drawing.Rectangle oDrawRect;


			if( this.Visible == true )
			{
				base.Render();

				//Draw the black rendering area
				oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 
 
				//Draw our terrain
				nCount = Game.GobFile.GetTable( Game.m_cGOB_TRNSTATS_TABLE ).RowCount;
				for( int nTerrainIndex=0 ; nTerrainIndex<Convert.ToInt64( nCount ) ; nTerrainIndex++ )
				{
					oSrcRect = Game.GetSrcRectForTerrainType( (int)nTerrainIndex,ref sGraphicKey );
					oSrcRect.Y = (int)Game.m_cSQRH_TRN;
					nX = nTerrainIndex % 4;
					nY = (int)Math.Floor( (double)nTerrainIndex / 4 );

					oTrgRect = oSrcRect;
					oTrgRect.X = (int)(nX*oSrcRect.Width + Game.m_cBORDER_GRAY_LEFTWIDTH + this.Location.X);
					oTrgRect.Y = (int)(nY*oSrcRect.Height + Game.m_cBORDER_GRAY_TOPWIDTH + this.Location.Y);

					m_oApp.DSGameEngine.RenderTexture2D( sGraphicKey, oSrcRect, oTrgRect, oDrawRect,
											new Vector2( 0,0 ), 0, 0, false,
											System.Drawing.Color.White.ToArgb() );
				}			
	

				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}

		public override void OnResize()
		{
			base.OnResize ();

			base.Size = new Vector2( Game.m_cSQRW_TRN*4 + Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH,
									 Game.m_cSQRH_TRN*9 + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cBORDER_GRAY_BOTTOMWIDTH );
		}

		public override bool OnMouseDown(Vector2 vMousePosInFormSpace, long nButton)
		{
			double nXClick = 0, nYClick = 0;
			long nX = 0, nY = 0;
			long nTerrainIndex = -1;
			bool bActionUsed = false;
			System.Drawing.Rectangle oDrawRect;


			bActionUsed = base.OnMouseDown (vMousePosInFormSpace, nButton);

			oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
								   	   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
								   	   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH),
								   	   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );			

			//Get the building they clicked on
			nXClick = vMousePosInFormSpace.X - Game.m_cBORDER_GRAY_LEFTWIDTH;
			nYClick = vMousePosInFormSpace.Y - Game.m_cBORDER_GRAY_TOPWIDTH;
			nX = (long)( nXClick / (double)Game.m_cSQRW_TRN );
			nY = (long)( nYClick / (double)Game.m_cSQRH_TRN );
			

			//Make sure their selection was valid
			if( nX >= 0 && nX <= 4 && nY >= 0 && nY <= 9 &&
				oDrawRect.Contains( (int)(vMousePosInFormSpace.X+this.Location.X),
				(int)(vMousePosInFormSpace.Y+this.Location.Y) ) == true )
			{
				//Lookup our purchase picture to our graphic key
				nTerrainIndex = nX + nY * 4;
				this.DoDragDrop( Game.m_cDRAGDROP_TERRAIN + nTerrainIndex.ToString() );
				bActionUsed = true;
			}


			return( bActionUsed );
		}

		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( false );
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( vMousePosInFormSpace.X <= Game.m_cBORDER_GRAY_LEFTWIDTH || 
				vMousePosInFormSpace.X >= this.Size.X - Game.m_cBORDER_GRAY_RIGHTWIDTH ||
				vMousePosInFormSpace.Y <= Game.m_cBORDER_GRAY_TOPWIDTH ||
				vMousePosInFormSpace.Y >= this.Size.Y - Game.m_cBORDER_GRAY_BOTTOMWIDTH )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}


		public static long GetDragingTerrain( DSForms oForms )
		{
			string sDragging = "";
			long nTerrainIndexReturnValue = -1;


			if( oForms.DragAndDropInProgress == true && 
				oForms.DragAndDropData.GetType().FullName.ToString() == "System.String" )
			{
				sDragging = (string)oForms.DragAndDropData;

				if( sDragging.Substring( 0,Game.m_cDRAGDROP_TERRAIN.Length ) == Game.m_cDRAGDROP_TERRAIN )
				{
					sDragging = sDragging.Substring( Game.m_cDRAGDROP_TERRAIN.Length );
					nTerrainIndexReturnValue = Convert.ToInt64( sDragging );
				}
			}

			return( nTerrainIndexReturnValue );
		}
		public static bool IsDragingTerrain( DSForms oForms )
		{
			bool bDragginTerrain = false;
			string sDragging = "";


			if( oForms.DragAndDropInProgress == true && 
				oForms.DragAndDropData.GetType().FullName.ToString() == "System.String" )
			{
				sDragging = (string)oForms.DragAndDropData;

				if( sDragging.Length > Game.m_cDRAGDROP_TERRAIN.Length &&
					sDragging.Substring( 0,Game.m_cDRAGDROP_TERRAIN.Length ) == Game.m_cDRAGDROP_TERRAIN )
				{
					bDragginTerrain = true;
				}
			}

			return( bDragginTerrain );
		}



		#region Properties
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}
	#endregion

	#region Purchase Form
	public class MMPurchaseForm : DSForm 
	{
		#region Properties
		private MetalMarines m_oApp = null;
		#endregion


		public MMPurchaseForm( DSForms oForms ) : base( oForms )
		{
		}


		public override void Render()
		{
			bool bCanBeBuilt = false;
			long nGobBuildingKey = -1;
			long nX = 0;
			long nY = 0;
			long nHighestPriceICanAfford = 0;
			long nPriceToBuy = 0;
			int nColor = 0;
			string sTemp = "";
			string sGraphicKey = "";
			System.Drawing.Color oTextColor = System.Drawing.Color.White;
			MMIslandForm oMyIsland = null;
			System.Drawing.Rectangle oTrgRect;
			System.Drawing.Rectangle oSrcRect;
			System.Drawing.Rectangle oDrawRect;


			if( this.Visible == true )
			{
				base.Render();

				//Draw the main form
				//oFormRect = new Rectangle( (int)this.Location.X,(int)this.Location.Y,(int)this.Size.X,(int)this.Size.Y );
				//base.DSGraphicsWrapper.RenderRect2D( oFormRect,System.Drawing.Color.DarkGray.ToArgb() ); 
				//Draw the black rendering area
				oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 
				//Label our form
				//base.DSGraphicsWrapper.RenderText( this.Location.X+5,this.Location.Y+3,System.Drawing.Color.White,this.Text );

				//Draw our purchase-able units
				for( int nRow=0 ; nRow<Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).RowCount ; nRow++ )
				{
					bCanBeBuilt = (bool)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_CANBEBUILT_CLMN,nRow );
					if( bCanBeBuilt == true ||
						( 
							m_oApp.GameState == enumStates.MapEditor && 
							(bool)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_SHOWINMAPEDITOR_CLMN,nRow ) == true 
						)
					  )
					{
						nGobBuildingKey = (long)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_BLDKEY_CLMN,nRow );

						oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nGobBuildingKey,0,ref sGraphicKey );
						oTrgRect = oSrcRect;
						oTrgRect.X = (int)(nX*oSrcRect.Width + Game.m_cBORDER_GRAY_LEFTWIDTH + this.Location.X);
						oTrgRect.Y = (int)(nY*oSrcRect.Height + Game.m_cBORDER_GRAY_TOPWIDTH + this.Location.Y);


						//Decide what color to make the building
						nColor = System.Drawing.Color.White.ToArgb();
						oTextColor = System.Drawing.Color.FromArgb( 200,200,200 );
						if( m_oApp.GameState == enumStates.InGame || m_oApp.GameState == enumStates.ResumeMenu )
						{
							oMyIsland = m_oApp.GetMyIsland();
							if( oMyIsland != null )
							{
								//Do we have the money?
								nPriceToBuy = Game.GetPriceOfBuilding( nGobBuildingKey );
								if( nPriceToBuy < nHighestPriceICanAfford ||
									m_oApp.Game.CanIAffordCredits( oMyIsland.Island,nPriceToBuy,ref sTemp ) == true )
								{
									//Can Afford
									nHighestPriceICanAfford = nPriceToBuy;

									if( nPriceToBuy > oMyIsland.Island.Credits )
									{
										oTextColor = System.Drawing.Color.Blue;
										nColor = System.Drawing.Color.LightBlue.ToArgb();
									}
								}
								else
								{
									//Can't Afford
									nColor = System.Drawing.Color.Gray.ToArgb();
									oTextColor = System.Drawing.Color.Red;
								}
							}

							sTemp = "-$" + nPriceToBuy.ToString();
						}
						else if( m_oApp.GameState == enumStates.MapEditor )
						{
							if( nGobBuildingKey == Game.m_cGOB_BASE_KEY )
							{
								sTemp = "Base";
							}
							else
							{
								sTemp = "";
							}
						}


						//Render our graphic
						base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
													oTrgRect, new Vector2( 0,0 ), 0, 0, false,nColor );	
		m_oApp.RenderTextWithShadow( sTemp,oTrgRect.X+15,oTrgRect.Y,oTextColor,System.Drawing.Color.Black );
						//Now render its cost
/*						base.DSGraphicsWrapper.RenderText( oTrgRect.X-1+15,oTrgRect.Y-1,System.Drawing.Color.Black,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X-1+15,oTrgRect.Y+1,System.Drawing.Color.Black,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+1+15,oTrgRect.Y-1,System.Drawing.Color.Black,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+1+15,oTrgRect.Y+1,System.Drawing.Color.Black,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+15,oTrgRect.Y,oTextColor,sTemp );*/
						/*base.DSGraphicsWrapper.RenderText( oTrgRect.X-1+15,oTrgRect.Y-1,oTextColor,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X-1+15,oTrgRect.Y+1,oTextColor,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+1+15,oTrgRect.Y-1,oTextColor,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+1+15,oTrgRect.Y+1,oTextColor,sTemp );
						base.DSGraphicsWrapper.RenderText( oTrgRect.X+15,oTrgRect.Y,System.Drawing.Color.FromArgb( 200,200,200 ),sTemp );*/

						nX++;
						if( nX >= 3 )
						{
							nX = 0;
							nY++;
						}
					}
				}

				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}

		public override void OnResize()
		{
			base.OnResize ();

			if( m_oApp.GameState == enumStates.MapEditor )
			{
				base.Size = new Vector2( Game.m_cSQRW_BLD*3 + Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH,
						 				 Game.m_cSQRH_BLD*7 + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cBORDER_GRAY_BOTTOMWIDTH );
			}
			else
			{
				base.Size = new Vector2( Game.m_cSQRW_BLD*3 + Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH,
						 				 Game.m_cSQRH_BLD*4 + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cBORDER_GRAY_BOTTOMWIDTH );
			}
		}

		public override void OnMoved()
		{
			base.OnMoved();
			m_oApp.SaveINIFile();
		}
		public override bool OnMouseDown(Vector2 vMousePosInFormSpace, long nButton)
		{
			string sFailureMessage = "";
			long nGobBuildingKey = -1;
			bool bActionUsed = false;
			System.Drawing.Rectangle oDrawRect;
			MMIslandForm oMyIsland = null;


			m_oApp.SelectedSquares = new DSSortedList();

			bActionUsed = base.OnMouseDown (vMousePosInFormSpace, nButton);

			oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
									   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
									   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH),
									   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );			

			//Get the building they clicked on
			nGobBuildingKey = GetBldKeyForMousePosInFormSpace( vMousePosInFormSpace );

			if( nGobBuildingKey != -1 )
			{
				//Lookup our purchase picture to our graphic key
				//nGobBuildingKey = GetBldKeyForRowCol( nX,nY );

				//Can they afford this building?  Find our island and check
				if( m_oApp.GameState == enumStates.InGame )
				{
					oMyIsland = m_oApp.GetMyIsland();
					if( oMyIsland != null )
					{
						//Its ok, we have the money
						if( m_oApp.Game.CanIAffordCredits( oMyIsland.Island,Game.GetPriceOfBuilding( nGobBuildingKey ),ref sFailureMessage ) == true )
						{
							this.DoDragDrop( nGobBuildingKey );
							bActionUsed = true;
						}
						//We don't have enough money!
						else
						{
							m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sFailureMessage );
							m_oApp.DSGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
						}
					}
						//Error, can't find our island
					else
					{
						throw new System.Exception( "Unable to find your island!" );
					}
				}
				else
				{
					this.DoDragDrop( nGobBuildingKey );
					bActionUsed = true;
				}
			}


			return( bActionUsed );
		}

		public override bool OnMouseHover(Vector2 vMousePosInControlSpace)
		{
			long nGobBuildingKey = -1;
			MMPurchaseHoverForm oHoverForm = null;
			Vector2 vHoverPositionInScreenSpace = Vector2.Empty;
			
			
			nGobBuildingKey = GetBldKeyForMousePosInFormSpace( vMousePosInControlSpace );
			if( nGobBuildingKey != -1 )
			{
				vHoverPositionInScreenSpace = new Vector2( vMousePosInControlSpace.X + this.Location.X,
														   vMousePosInControlSpace.Y + this.Location.Y );

				oHoverForm = new MMPurchaseHoverForm( base.Forms );
				oHoverForm.DSGraphicsWrapper = this.DSGraphicsWrapper;
				oHoverForm.App = m_oApp;
				oHoverForm.SetupHoverForm( vHoverPositionInScreenSpace,nGobBuildingKey );
				m_oApp.DSGameEngine.Forms.Add( oHoverForm );
			}


			return( base.OnMouseHover( vMousePosInControlSpace ) );
		}

		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( false );
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( vMousePosInFormSpace.X <= Game.m_cBORDER_GRAY_LEFTWIDTH * 1.5 || 
				vMousePosInFormSpace.X >= this.Size.X - Game.m_cBORDER_GRAY_RIGHTWIDTH * 1.5 ||
				vMousePosInFormSpace.Y <= Game.m_cBORDER_GRAY_TOPWIDTH * 1.5 ||
				vMousePosInFormSpace.Y >= this.Size.Y - Game.m_cBORDER_GRAY_BOTTOMWIDTH * 1.5 )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}


		private long GetBldKeyForMousePosInFormSpace( Vector2 vMousePosInFormSpace )
		{
			double nXClick = 0, nYClick = 0;
			long nX = 0, nY = 0;
			long nRetVal = -1;


			//Get the building they clicked on
			nXClick = vMousePosInFormSpace.X - Game.m_cBORDER_GRAY_LEFTWIDTH;
			nYClick = vMousePosInFormSpace.Y - Game.m_cBORDER_GRAY_TOPWIDTH;
			nX = (long)( nXClick / (double)Game.m_cSQRW_BLD );
			nY = (long)( nYClick / (double)Game.m_cSQRH_BLD );

			if( nXClick >= 0 && nYClick >= 0 &&
				nX >= 0 && nX < 3 && nY >= 0 &&
				(
					nY < 4 ||
					( 
						m_oApp.GameState == enumStates.MapEditor && nY < 7
					)
				)
			  )
			{
				nRetVal = GetBldKeyForRowCol( nX,nY );
			}


			return( nRetVal );
		}
		private long GetBldKeyForRowCol( long nFindX,long nFindY )
		{
			bool bCanBeBuilt = false;
			long nGobBuildingKey = -1;
			long nLoopX = 0;
			long nLoopY = 0;
			

			//Draw our purchase-able units
			for( int nRow=0 ; nRow<Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).RowCount ; nRow++ )
			{
				bCanBeBuilt = (bool)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_CANBEBUILT_CLMN,nRow );
				if( bCanBeBuilt == true ||
					( 
						m_oApp.GameState == enumStates.MapEditor && 
						(bool)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_SHOWINMAPEDITOR_CLMN,nRow ) == true 
					)
				  )
				{
					if( nFindX == nLoopX && nFindY == nLoopY )
					{
						nGobBuildingKey = (long)Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE ).GetData( Game.m_cGOB_BLDSTATS_BLDKEY_CLMN,nRow );
						return( nGobBuildingKey );
					}

					nLoopX++;
					if( nLoopX >= 3 )
					{
						nLoopX = 0;
						nLoopY++;
					}
				}
			}

			return( -1 );
		}


		public static long GetDragingPurchase( DSForms oForms )
		{
			long nGobBuildingKeyReturnValue = -1;

			if( oForms.DragAndDropInProgress == true && 
				oForms.DragAndDropData.GetType().FullName.ToString() == "System.Int64" )
			{
				nGobBuildingKeyReturnValue = (long)oForms.DragAndDropData;
			}

			return( nGobBuildingKeyReturnValue );
		}
		public static bool IsDragingPurchase( DSForms oForms )
		{
			bool bDragginPurchase = false;

			if( oForms.DragAndDropInProgress == true && 
				oForms.DragAndDropData.GetType().FullName.ToString() == "System.Int64" )
			{
				bDragginPurchase = true;
			}

			return( bDragginPurchase );
		}



		#region Properties
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}
	#endregion

	#region PurchaseHover Form
	public class MMPurchaseHoverForm : DSForm 
	{
		#region Properties
		private const int m_nMaxTextLength = 40;
		private const int  m_nSearchPoint = 35;

		private long m_nGobBuildingKey = -1;
		private MetalMarines m_oApp = null;
		#endregion


		public MMPurchaseHoverForm( DSForms oForms ) : base( oForms )
		{
		}

		public void SetupHoverForm( Vector2 vHoverPositionInScreenSpace,long nGobBuildingKey )
		{
			long nY = 0;
			int nPos = 0;
			string sDesc = "";
			string sTemp = "";


			m_nGobBuildingKey = nGobBuildingKey;

			//Description
			nY = Game.m_cBORDER_GRAY_TOPWIDTH * 2 + this.Location.Y + Game.m_cSQRH_BLD + 15;
			sDesc = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_TOOLTIP_CLMN ).ToString();
			while( sDesc.Length > 0 )
			{
				if( sDesc.Length > m_nMaxTextLength )
				{
					nPos = sDesc.IndexOf( " ",m_nSearchPoint );
					if( nPos == -1 || nPos > m_nMaxTextLength )
					{
						nPos = m_nSearchPoint;
					}
					sTemp = sDesc.Substring( 0,nPos );
					sDesc = sDesc.Substring( nPos );
				}
				else
				{
					sTemp = sDesc;
					sDesc = "";
				}
				nY += 15;
			}

			this.Size = new Vector2( 250,nY + 30 );
			this.Location = new Point( (int)( vHoverPositionInScreenSpace.X - 125 ),
									   (int)( vHoverPositionInScreenSpace.Y - nY/2 ) );
			if( this.Location.X + this.Size.X > this.DSGraphicsWrapper.ScreenWidth )
			{
				this.Location = new Point( (int)( this.DSGraphicsWrapper.ScreenWidth - this.Size.X ),
										   this.Location.Y );
			}
			if( this.Location.Y + this.Size.Y > this.DSGraphicsWrapper.ScreenHeight )
			{
				this.Location = new Point( this.Location.X,
										   (int)( this.DSGraphicsWrapper.ScreenHeight - this.Size.Y ) );
			}

			this.Name = "MMPurchaseHoverForm";
		}


		public override void Render()
		{
			long nX = 0;
			long nY = 0;
			int nPos = 0;
			string sTemp = "";
			string sDesc = "";
			string sGraphicKey = "";
			System.Drawing.Rectangle oTrgRect;
			System.Drawing.Rectangle oSrcRect;
			System.Drawing.Rectangle oDrawRect;


			if( this.Visible == true )
			{
				base.Render();

				//Draw the black rendering area
				oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 


				//Draw our unit
				oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( m_nGobBuildingKey,0,ref sGraphicKey );
				oTrgRect = oSrcRect;
				oTrgRect.X = (int)(Game.m_cBORDER_GRAY_LEFTWIDTH + this.Location.X + 8);
				oTrgRect.Y = (int)(Game.m_cBORDER_GRAY_TOPWIDTH + this.Location.Y);
				//Render our graphic
				base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
						oTrgRect, new Vector2( 0,0 ), 0, 0, false,System.Drawing.Color.White.ToArgb() );	
		
				//Render the stats
				nX = Game.m_cBORDER_GRAY_LEFTWIDTH * 2 + this.Location.X + Game.m_cSQRH_BLD + 15 + 8;
				nY = Game.m_cBORDER_GRAY_TOPWIDTH + this.Location.Y + 8;
				//Name
				m_oApp.RenderTextWithShadow( Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_NAME_CLMN ).ToString(),
						nX,nY,System.Drawing.Color.White,System.Drawing.Color.Black );
				//Price 
				m_oApp.RenderTextWithShadow( "Price: -$" + Game.GetPriceOfBuilding( m_nGobBuildingKey ).ToString(),
						nX,nY + 15,System.Drawing.Color.White,System.Drawing.Color.Black );
				//Strength
				m_oApp.RenderTextWithShadow( "Defense: " + Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_STRENGTH_CLMN ).ToString(),
						nX,nY + 30,System.Drawing.Color.White,System.Drawing.Color.Black );

				//Description
				nX = Game.m_cBORDER_GRAY_LEFTWIDTH * 2 + this.Location.X;
				nY = Game.m_cBORDER_GRAY_TOPWIDTH * 2 + this.Location.Y + oTrgRect.Height + 15;
				sDesc = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_TOOLTIP_CLMN ).ToString();
				while( sDesc.Length > 0 )
				{
					if( sDesc.Length > m_nMaxTextLength )
					{
						nPos = sDesc.IndexOf( " ",m_nSearchPoint );
						if( nPos == -1 || nPos > m_nMaxTextLength )
						{
							nPos = m_nSearchPoint;
						}
						sTemp = sDesc.Substring( 0,nPos );
						sDesc = sDesc.Substring( nPos );
					}
					else
					{
						sTemp = sDesc;
						sDesc = "";
					}
					m_oApp.RenderTextWithShadow( sTemp.Trim(),nX,nY,System.Drawing.Color.White,System.Drawing.Color.Black );
					nY += 15;
				}
								

				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}

		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( false );
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( vMousePosInFormSpace.X <= Game.m_cBORDER_GRAY_LEFTWIDTH * 1.5 || 
				vMousePosInFormSpace.X >= this.Size.X - Game.m_cBORDER_GRAY_RIGHTWIDTH * 1.5 ||
				vMousePosInFormSpace.Y <= Game.m_cBORDER_GRAY_TOPWIDTH * 1.5 ||
				vMousePosInFormSpace.Y >= this.Size.Y - Game.m_cBORDER_GRAY_BOTTOMWIDTH * 1.5 )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}


		public override bool OnMouseLeave(Vector2 vMousePosInControlSpace, bool[] baButtons)
		{
			/*if( m_oForms.DragAndDropInProgress == false )
			{
				m_oForms.Remove( this.Name );
				return( true );
			}
			else
			{
				return( false );
			}*/
			m_oForms.Remove( this.Name );
			return( base.OnMouseLeave (vMousePosInControlSpace, baButtons) );
		}

		public override bool OnMouseDown(Vector2 vMousePosInFormSpace, long nButton)
		{
			string sFailureMessage = "";
			bool bActionUsed = false;
			MMIslandForm oMyIsland = null;


			m_oApp.SelectedSquares = new DSSortedList();

			bActionUsed = base.OnMouseDown( vMousePosInFormSpace, nButton );

			//Can they afford this building?  Find our island and check
			if( m_oApp.GameState == enumStates.InGame )
			{
				oMyIsland = m_oApp.GetMyIsland();
				if( oMyIsland != null )
				{
					//Its ok, we have the money
					if( m_oApp.Game.CanIAffordCredits( oMyIsland.Island,Game.GetPriceOfBuilding( m_nGobBuildingKey ),ref sFailureMessage ) == true )
					{
						DSForm oForm = m_oForms.GetForm( Game.m_cFRM_PURCHASE );
						oForm.DoDragDrop( m_nGobBuildingKey );

						//this.DoDragDrop( m_nGobBuildingKey );
						bActionUsed = true;
					}
					//We don't have enough money!
					else
					{
						m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sFailureMessage );
						m_oApp.DSGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_CANTBUILD );
					}
				}
				//Error, can't find our island
				else
				{
					throw new System.Exception( "Unable to find your island!" );
				}
			}
			else
			{
				DSForm oForm = m_oForms.GetForm( Game.m_cFRM_PURCHASE );
				oForm.DoDragDrop( m_nGobBuildingKey );
				//this.DoDragDrop( m_nGobBuildingKey );
				bActionUsed = true;
			}


			return( bActionUsed );
		}



		#region Properties
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}
	#endregion

	#region PlaceBase Form
	public class MMPlaceBaseForm : DSForm 
	{
		#region Properties
		private const long m_cBorderWidth = 2;
		private const long m_cScrollWidth = 20;
		
		private long m_nBasesLeftToPlace = 0;
		private long m_nMaxBasesToPlace = 0;

		private DSGameEngine m_oGameEngine = null;
		#endregion


		public MMPlaceBaseForm( DSForms oForms ) : base( oForms )
		{
		}


		public override void Render()
		{
			string sGraphicKey = "";
			long nTempNumToDraw = m_nBasesLeftToPlace;
			System.Drawing.Rectangle oDrawRect;
			System.Drawing.Rectangle oSrcRect;
			System.Drawing.Rectangle oTrgRect;


			if( this.Visible == true )
			{
				base.Render();

				//Draw the main form
				oDrawRect = new Rectangle( (int)(this.Location.X+Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y+Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X-Game.m_cBORDER_GRAY_LEFTWIDTH-Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y-Game.m_cBORDER_GRAY_TOPWIDTH-Game.m_cBORDER_GRAY_BOTTOMWIDTH) );
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 


				//Get our base graphic
				oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( Game.m_cGOB_BASE_KEY,0,ref sGraphicKey );

				//Decide how many bases to draw
				if( MMPlaceBaseForm.IsDragingBasePlacement( m_oForms ) == true )
				{
					nTempNumToDraw--;
				}

				//Draw our placable bases
				for( int i=0 ; i<nTempNumToDraw ; i++ )
				{
					oTrgRect = new System.Drawing.Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
								(int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cSQRH_BLD * i),
								(int)Game.m_cSQRW_BLD,(int)Game.m_cSQRH_BLD );

					base.DSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, 
						oTrgRect, oDrawRect, new Vector2( 0,0 ), 0, 0, false,
						System.Drawing.Color.White.ToArgb() );			
				}

				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}

		public override void OnInitialize()
		{
			base.OnInitialize ();
		}

		public override void OnResize()
		{
			base.OnResize ();

			base.Size = new Vector2( Game.m_cSQRW_BLD + Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH,
									 Game.m_cSQRH_BLD * MaxBasesToPlace + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cBORDER_GRAY_BOTTOMWIDTH );
		}

		public override bool OnMouseDown(Vector2 vMousePosInFormSpace, long nButton)
		{
			System.Drawing.Rectangle oBaseRect;
			bool bActionUsed = false;


			bActionUsed = base.OnMouseDown (vMousePosInFormSpace, nButton);

			//Get the black rendering area
			oBaseRect = new Rectangle( (int)(this.Location.X + m_cBorderWidth),
				(int)(this.Location.Y + m_cScrollWidth),
				(int)(this.Size.X - m_cBorderWidth*2),
				(int)(this.Location.Y + m_cScrollWidth + m_nBasesLeftToPlace * Game.m_cSQRH_TRN ) );

			//Did they click on a base location?
			if( oBaseRect.Contains( (int)(vMousePosInFormSpace.X + this.Location.X),(int)(vMousePosInFormSpace.Y + this.Location.Y) ) == true && 
				nButton == 0 && m_nBasesLeftToPlace > 0 )
			{
				//Then they picked up a base
				bActionUsed = true;
				this.DoDragDrop( Game.m_cDRAGDROP_BASE );
			}


			return( bActionUsed );
		}


		public static bool IsDragingBasePlacement( DSForms oForms )
		{
			bool bDragginBase = false;

			if( oForms.DragAndDropInProgress == true && 
				oForms.DragAndDropData.GetType().FullName.ToString() == "System.String" &&
				(string)oForms.DragAndDropData == Game.m_cDRAGDROP_BASE )
			{
				bDragginBase = true;
			}

			return( bDragginBase );
		}



		#region Properties
		public long BasesToPlace
		{
			get
			{
				return( m_nBasesLeftToPlace );
			}
			set
			{
				m_nBasesLeftToPlace = value;
			}
		}
		public long MaxBasesToPlace
		{
			get
			{
				return( m_nMaxBasesToPlace );
			}
			set
			{
				m_nMaxBasesToPlace = value;
			}
		}
		public DSGameEngine GameEngine
		{
			get
			{
				return( m_oGameEngine );
			}
			set
			{
				m_oGameEngine = value;
			}
		}
		#endregion
	}
	#endregion

	#region Console Form
	/*public class MMConsoleForm : DSForm 
	{
		#region Properties
		private DSGameEngine m_oGameEngine = null;
		private string m_sStatus = "";
		private Island m_oMyIsland = null;
		private MetalMarines m_oApp = null;
		#endregion


		public MMConsoleForm( DSForms oForms ) : base( oForms )
		{
		}


		public override void Render()
		{
			System.Drawing.Rectangle oDrawRect;


			if( this.Visible == true && m_oMyIsland != null )
			{
				base.Render();

				//Draw the black rendering area
				oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y - Game.m_cBORDER_GRAY_BOTTOMWIDTH - Game.m_cBORDER_GRAY_TOPWIDTH) );
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 


				//Draw our status
				base.DSGraphicsWrapper.RenderText( this.Location.X+5+Game.m_cBORDER_GRAY_LEFTWIDTH,
												   this.Location.Y+3+20,
												   System.Drawing.Color.White,m_sStatus );
				//Draw our money and Fuel
				base.DSGraphicsWrapper.RenderText( this.Location.X+5+Game.m_cBORDER_GRAY_LEFTWIDTH,
												   this.Location.Y+3+60,System.Drawing.Color.White,
								"Fuel: " + ((long)m_oMyIsland.Fuel).ToString() + 
								" (+" + ((long)m_oMyIsland.FuelIncomePerSecond).ToString() + ")" );
				base.DSGraphicsWrapper.RenderText( this.Location.X+5+Game.m_cBORDER_GRAY_LEFTWIDTH,
												   this.Location.Y+3+80,System.Drawing.Color.White,
								"Credits: " + ((long)m_oMyIsland.Credits).ToString() + 
								" (+" + ((long)m_oMyIsland.CreditIncomePerSecond).ToString() + ")" );


				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
								 Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}

		public override void OnMoved()
		{
			base.OnMoved();
			m_oApp.SaveINIFile();
		}
		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( false );
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( true );
		}



		#region Properties
		public string Status
		{
			get
			{
				return( m_sStatus );
			}
			set
			{
				m_sStatus = value;
			}
		}
		public DSGameEngine GameEngine
		{
			get
			{
				return( m_oGameEngine );
			}
			set
			{
				m_oGameEngine = value;
			}
		}
		public Island MyIsland
		{
			get
			{
				return( m_oMyIsland );
			}
			set
			{
				m_oMyIsland = value;
			}
		}
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}*/
	#endregion

	#region Popup Form
	public class MMPopupForm : DSForm 
	{
		#region Properties
        private const string m_cBULLDOZE_BUTTON_NAME = "btnBulldoze";
		private const string m_cBUILDUP_BUTTON_NAME = "btnBuildUp";
		private const string m_cSTRENGTH_LABEL_NAME = "lblStrength";
		private const string m_cOFFENSIVE_LABEL_NAME = "lblOffensive";
		private const string m_cDAMAGE_BUTTON_NAME = "btnDamage";

		private const long m_cBorderWidth = 2;
		private const long m_cScrollWidth = 20;

		private DSGameEngine m_oGameEngine = null;
		private string m_sStatus = "";
		private Island m_oIslandClickedOn = null;
		private DSSortedList m_oSquaresClickedOn = null;
		private MetalMarines m_oApp = null;
		#endregion


		public MMPopupForm( DSForms oForms ) : base( oForms )
		{
		}

		public void SetupForSquare( Island oIslandClickedOn,DSSortedList oSelectedSquares )
		{
			Square oSquare = null;
			DSButton oButton = null;
			DSLabel oLabel = null;
			Point oSquarePoint = new Point( 0,0 );
			object oOffensive = null;
			int nHeight = 0;
			string sFailureMessage = "";
			long nBulldozeCost = 0;
			long nBuildUpCost = 0;


			//Save which square we clicked on
			m_oIslandClickedOn = oIslandClickedOn;
			m_oSquaresClickedOn = oSelectedSquares.Clone();

			//Now setup our screen
			if( m_oApp.GameState == enumStates.MapEditor )
			{
				//This means we damage the swuare
				oButton = this.AddControl_Button( m_cDAMAGE_BUTTON_NAME,
					new Point( 5 + (int)Game.m_cBORDER_GRAY_LEFTWIDTH,nHeight + 5 + (int)Game.m_cBORDER_GRAY_TOPWIDTH ), new Vector2( 100,20 ),
					"Damage Sqr" );
				oButton.Click += new EventHandler( Damage_Click );
				oButton.Enabled = true;
				oButton.FontColor = System.Drawing.Color.White;
				nHeight += 20;
			}
			if( CanBulldoze( false,ref nBulldozeCost ) == true )
			{
				oButton = this.AddControl_Button( m_cBULLDOZE_BUTTON_NAME,
							new Point( 5 + (int)Game.m_cBORDER_GRAY_LEFTWIDTH,nHeight + 5 + (int)Game.m_cBORDER_GRAY_TOPWIDTH ), new Vector2( 100,20 ),
							"Bulldoze (-$" + nBulldozeCost.ToString() + "M)" );
				oButton.Click += new EventHandler( Bulldoze_Click );
				oButton.Enabled = ( m_oApp.Game.CanIAffordCredits( m_oIslandClickedOn,nBulldozeCost,ref sFailureMessage ) );
				oButton.FontColor = System.Drawing.Color.White;
				nHeight += 20;
			}
			if( CanBuildUp( false,ref nBuildUpCost ) == true )
			{
				//This means the square can build up
				oButton = this.AddControl_Button( m_cBUILDUP_BUTTON_NAME,
							new Point( 5 + (int)Game.m_cBORDER_GRAY_LEFTWIDTH,nHeight + 5 + (int)Game.m_cBORDER_GRAY_TOPWIDTH ), new Vector2( 100,20 ),
							"Build Up (-$" + nBuildUpCost.ToString() + "M)" );
				oButton.Click += new EventHandler( BuildUp_Click );
				oButton.Enabled = ( m_oApp.Game.CanIAffordCredits( m_oIslandClickedOn,nBuildUpCost,ref sFailureMessage ) );
				oButton.FontColor = System.Drawing.Color.White;
				nHeight += 20;
			}

			if( oSelectedSquares.Count == 1 )
			{
				oSquarePoint = (Point)m_oSquaresClickedOn.GetByIndex( 0 );
				oSquare = (Square)m_oIslandClickedOn.GetSquare( oSquarePoint.X,oSquarePoint.Y );

				if( oSquare.SquareStatus == enumSquareStatus.Built )
				{
					//Add the strength line 
					oLabel = this.AddControl_Label( m_cSTRENGTH_LABEL_NAME,
							new Point( 5 + (int)Game.m_cBORDER_GRAY_LEFTWIDTH,nHeight + 10 + (int)Game.m_cBORDER_GRAY_TOPWIDTH ), new Vector2( 100,20 ),
							"Strength: " + ((int)oSquare.Strength).ToString() );
					oLabel.FontColor = System.Drawing.Color.White;
					nHeight += 20;

					//Add the offense power line
					oOffensive = Game.GetBldStat( oSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_OFFENSIVE_CLMN );
					if( oOffensive != null )
					{
						oLabel = this.AddControl_Label( m_cOFFENSIVE_LABEL_NAME,
							new Point( 5 + (int)Game.m_cBORDER_GRAY_LEFTWIDTH,nHeight + 5 + (int)Game.m_cBORDER_GRAY_TOPWIDTH ), new Vector2( 100,20 ),
							"Offensive: " + oOffensive.ToString() );
						oLabel.FontColor = System.Drawing.Color.White;
						nHeight += 20;
					}
				}
			}

			//Setup our display size
			this.Size = new Vector2( 110 + Game.m_cBORDER_GRAY_LEFTWIDTH + Game.m_cBORDER_GRAY_RIGHTWIDTH,
									 nHeight + 10 + Game.m_cBORDER_GRAY_TOPWIDTH + Game.m_cBORDER_GRAY_BOTTOMWIDTH );
		}


		private void Bulldoze_Click( object sender, EventArgs e )
		{
			string sFailureMessage = "";
			long nBulldozeCost = 0;

			CanBulldoze( false,ref nBulldozeCost );

			//Make sure we can still afford it
			if( m_oApp.Game.CanIAffordCredits( m_oIslandClickedOn,nBulldozeCost,ref sFailureMessage ) == true ||
				m_oApp.GameState == enumStates.MapEditor )
			{
				CanBulldoze( true,ref nBulldozeCost );
				m_oApp.SelectedSquares = new DSSortedList();
			}
			else
			{
				m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sFailureMessage );
			}

			//Hide the popup
			m_oGameEngine.Forms.Remove( Game.m_cFRM_POPUP );
		}
		private bool CanBulldoze( bool bBulldoze,ref long nBulldozeCost )
		{
			string sPayMessage = "";
			bool bCanBulldoze = false;
			Square oLoopSquare = null;
			Square oSquare = null;
			DSSortedList oList = null;
			Point oEndPoint = new Point( 0,0 );
			Point oSquarePoint = new Point( 0,0 );
			nBulldozeCost = 0;


			//Go through and find out what we can do
			for( int nSquareIndex=0 ; nSquareIndex<m_oSquaresClickedOn.Count ; nSquareIndex++ )
			{
				oSquarePoint = (Point)m_oSquaresClickedOn.GetByIndex( nSquareIndex );
				oLoopSquare = (Square)m_oIslandClickedOn.GetSquare( oSquarePoint.X,oSquarePoint.Y );

				//First of all can we add the bulldoze button?
				if( oLoopSquare.SquareStatus != enumSquareStatus.Empty )
				{
					bCanBulldoze = true;
					nBulldozeCost += 5;
				}

				if( bBulldoze == true )
				{
					//Bulldoze it... first check to see if its a composite building
					oList = m_oIslandClickedOn.GetCompositeBuilding( oLoopSquare.X,oLoopSquare.Y );
					if( oList.Count > 0 )
					{
						for( int i=0 ; i<oList.Count ; i++ )
						{
							oEndPoint = (Point)oList.GetByIndex( i );
							oSquare = m_oIslandClickedOn.GetSquare( oEndPoint.X,oEndPoint.Y );

							oSquare.Bulldoze();

							//Add our purchased message
							oSquare.AddScrollingMessage( "-$5",System.Drawing.Color.Red );
						}
					}
					else
					{
						oLoopSquare.Bulldoze();

						//Add our purchased message
						oLoopSquare.AddScrollingMessage( "-$5",System.Drawing.Color.Red );
					}
				}
			}

			//Did we bulldoze?
			if( bBulldoze == true )
			{
				//Take the money from our island
				sPayMessage = m_oApp.Game.PayCredits( m_oIslandClickedOn,nBulldozeCost );
				if( sPayMessage.Length > 0 )
				{
					m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sPayMessage );
				}

				m_oGameEngine.DirectSound.PlaySound( Game.m_cGOB_SOUND_BULLDOZE );

				//Send the update to everyone else
				if( m_oApp.GameState != enumStates.MapEditor )
				{
					App.SendIslandUpdate( m_oIslandClickedOn );
				}
			}

			return( bCanBulldoze );
		}

		private bool CanBuildUp( bool bBuildUp,ref long nBuildupCost )
		{
			string sPayMessage = "";
			object oUpgradeTo = null;
			bool bCanBuildUp = false;
			long nNewCost = 0;
			Point oSquarePoint = new Point( 0,0 );
			Square oLoopSquare = null;
			nBuildupCost = 0;


			//Go through and find out what we can do
			for( int nSquareIndex=0 ; nSquareIndex<m_oSquaresClickedOn.Count ; nSquareIndex++ )
			{
				oSquarePoint = (Point)m_oSquaresClickedOn.GetByIndex( nSquareIndex );
				oLoopSquare = (Square)m_oIslandClickedOn.GetSquare( oSquarePoint.X,oSquarePoint.Y );
	            
				//Do we add the build up button?
				if( oLoopSquare.SquareStatus == enumSquareStatus.Built )
				{
					//Find out the upgrade cost
					oUpgradeTo = Game.GetBldStat( oLoopSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_UPGRADETO_CLMN );

					//If this produces MM and the MM is away on buisness then we replace
					if( oLoopSquare.SquareStatus == enumSquareStatus.Built && 
						(bool)Game.GetBldStat( oLoopSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true &&
						oLoopSquare.Armed == false && oLoopSquare.MMIsOverseas == false )
					{
						bCanBuildUp = true;
						nBuildupCost += (long)Game.GetBldStat( oLoopSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_REPLACECOST_CLMN );						

						if( bBuildUp == true )
						{
							//Replace it... downgrade us to normal and set to armed
							oLoopSquare.SetSquare( WhatIsMyBaseType( oLoopSquare ) );
						}
					}
					//Otherwise can we upgrade?  And if we can, and were a MM the MM has to be there.
					else if( oUpgradeTo != null 
							&&
							(
								(bool)Game.GetBldStat( oLoopSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == false 
								||
								(
									oLoopSquare.SquareStatus == enumSquareStatus.Built  
									&&
									oLoopSquare.Armed == true && oLoopSquare.MMIsOverseas == false 
								)
							)
						  )
					{
						bCanBuildUp = true;
						nNewCost = (long)Game.GetBldStat( oLoopSquare.GobBuildingKey,Game.m_cGOB_BLDSTATS_BUILDUPCOST_CLMN );
						nBuildupCost += nNewCost;

						if( bBuildUp == true )
						{
							//Upgrade it
							oLoopSquare.SetSquare( (long)oUpgradeTo );

							//Add our purchased message
							oLoopSquare.AddScrollingMessage( "-$" + nNewCost.ToString(),System.Drawing.Color.Red );
						}
					}

					//We do things differently for the map editor
					if( m_oApp.GameState == enumStates.MapEditor )
					{
						oLoopSquare.SquareStatus = enumSquareStatus.Built;
					}
				}
			}


			//If we aren't in map editor mode then send the update
			if( bBuildUp == true && m_oApp.GameState != enumStates.MapEditor )
			{
				//Take the money from our island
				sPayMessage = m_oApp.Game.PayCredits( m_oIslandClickedOn,nBuildupCost );
				if( sPayMessage.Length > 0 )
				{
					m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sPayMessage );
				}

				App.SendIslandUpdate( m_oIslandClickedOn );
			}

			return( bCanBuildUp );
		}

		private void BuildUp_Click( object sender, EventArgs e )
		{
			string sFailureMessage = "";
			long nBuildUpCost = 0;

			CanBuildUp( false,ref nBuildUpCost );

			//Make sure we can still afford it
			if( m_oApp.Game.CanIAffordCredits( m_oIslandClickedOn,nBuildUpCost,ref sFailureMessage ) == true ||
				m_oApp.GameState == enumStates.MapEditor )
			{
				CanBuildUp( true,ref nBuildUpCost );
			}
			else
			{
				m_oApp.UpdateStatus( Game.m_cALERT_MONEY + sFailureMessage );
			}

			//Hide the popup
			m_oGameEngine.Forms.Remove( Game.m_cFRM_POPUP );			
		}

		private void Damage_Click( object sender, EventArgs e )
		{
			Square oLoopSquare = null;
			Point oSquarePoint = new Point( 0,0 );
			double nDamageAmt = 0;

			
			for( int nSquareIndex=0 ; nSquareIndex<m_oSquaresClickedOn.Count ; nSquareIndex++ )
			{
				oSquarePoint = (Point)m_oSquaresClickedOn.GetByIndex( nSquareIndex );
				oLoopSquare = (Square)m_oIslandClickedOn.GetSquare( oSquarePoint.X,oSquarePoint.Y );

				nDamageAmt = oLoopSquare.Strength;
				if( nDamageAmt <= 0 )
				{
					nDamageAmt = 10;
				}
				
				oLoopSquare.DamageSquare( nDamageAmt,m_oIslandClickedOn.GlobalID,"",false );
			}


			//Hide the popup
			m_oGameEngine.Forms.Remove( Game.m_cFRM_POPUP );			
		}

		public long WhatIsMyBaseType( Square oSquare )
		{
			object oRetVal = null;

			oRetVal = Game.GobFile.FindValue( Game.m_cGOB_BLDSTATS_TABLE,
											  Game.m_cGOB_BLDSTATS_UPGRADETO_CLMN,
											  oSquare.GobBuildingKey,
											  Game.m_cGOB_BLDSTATS_BLDKEY_CLMN,false );
			if( oRetVal == null )
			{
				oRetVal = oSquare.GobBuildingKey;
			}

			return( (long)oRetVal );
		}


		public override void Render()
		{
			System.Drawing.Rectangle oFormRect;


			if( this.Visible == true )
			{
				//Draw the main form
				//oFormRect = new Rectangle( (int)this.Location.X,(int)this.Location.Y,(int)this.Size.X,(int)this.Size.Y );
				//Draw the black rendering area
				oFormRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
										   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
										   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
										   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );

				base.DSGraphicsWrapper.RenderRect2D( oFormRect,System.Drawing.Color.Gray.ToArgb() ); 

				base.Render();

				base.DrawBorder( Game.m_cGOB_GRAYBORDER_UPPERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_UPPERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_UPPERRIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_MIDDLELEFT_TABLE, Game.m_cGOB_GRAYBORDER_MIDDLERIGHT_TABLE,
					Game.m_cGOB_GRAYBORDER_LOWERLEFT_TABLE, Game.m_cGOB_GRAYBORDER_LOWERMIDDLE_TABLE, Game.m_cGOB_GRAYBORDER_LOWERRIGHT_TABLE );
			}
		}



		#region Properties
		public string Status
		{
			get
			{
				return( m_sStatus );
			}
			set
			{
				m_sStatus = value;
			}
		}
		public DSGameEngine GameEngine
		{
			get
			{
				return( m_oGameEngine );
			}
			set
			{
				m_oGameEngine = value;
			}
		}
		public Island MyIsland
		{
			get
			{
				return( m_oIslandClickedOn );
			}
			set
			{
				m_oIslandClickedOn = value;
			}
		}
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}
	#endregion

	#region Team Form
	public class MMTeamForm : DSForm 
	{
		#region Properties
		private const long m_cTEAM_TEAMBORDER_LEFTSPACE = 105;
		private const long m_cTEAM_TEAMBORDER_TOPSPACE = 10;
		private const long m_cTEAM_TEAMTEXT_LEFTSPACE = 150;
		private const long m_cTEAM_TEAMTEXT_TOPSPACE = 9;
		private const long m_cTEAM_BULLET_LEFTSPACE = 149;
		private const long m_cTEAM_BULLET_TOPSPACE = 9;
		private const long m_cTEAM_PLRTEXT_LEFTSPACE = 170;
		private const long m_cTEAM_PLRTEXT_TOPSPACE = 10;

		private const long m_cTEAM_TEAMBORDER_WIDTH = 172;
		private const long m_cTEAM_TEAMBORDER_HEIGHT = 73;
		private const long m_cTEAM_BULLET_WIDTH = 17;
		private const long m_cTEAM_BULLET_HEIGHT = 17;
		private Island m_oSelected = null;
		private MetalMarines m_oApp = null;
		#endregion


		public MMTeamForm( DSForms oForms ) : base( oForms )
		{
		}


		//This function is wierd, it has two purposes... to calculate how high the team layout
		//will stretch and then to actually draw it.  This is because the difference between
		//the two functions is almost nill.  
		public void CalculateAndDraw( out long nHeight )
		{
			Island oSelectedItem = null;
			Point oClickPoint = new Point( 0,0 );

			CalculateAndDraw( false,0,System.Drawing.Rectangle.Empty,
							  out nHeight,oClickPoint,out oSelectedItem );
		}
		public void CalculateAndDraw( bool bDraw,long nYOffset,System.Drawing.Rectangle oClipRegion,
									  out long nHeight,Point oClickPoint,out Island oSelectedItem )
		{
			bool bAddedTeamHeader = false;
			string sTemp = "";
			long nY = Game.m_cBORDER_GRAY_TOPWIDTH + nYOffset;
			DSNetworkPlayer oNetPlayer = null;
			Island oTeamIsland = null;
			Island oPlayerIsland = null;
			System.Drawing.Rectangle oTarget = System.Drawing.Rectangle.Empty;
			System.Drawing.Rectangle oDrawArea = GetDrawingArea();
			System.Drawing.Color nColor = System.Drawing.Color.White;
			LoadedTexture oTexture = null;


			//Init our variables
			oSelectedItem = null;

			nY += 80;

			//Walk the list of islands and count how tall this needs to be
			for( int nIslandIndex=0 ; nIslandIndex<m_oApp.Game.Islands.Count ; nIslandIndex++ )
			{
				oTeamIsland = (Island)m_oApp.Game.Islands.GetByIndex( nIslandIndex );

				//Does this guy have his team setup?
				if( oTeamIsland.TeamSetup != null )
				{
					//////////////////////////////////////////////////////////////////////
					//Draw our team name
					//////////////////////////////////////////////////////////////////////
					//Figure out where we will draw this item 
					oTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_TEAMBORDER_TABLE );
					oTarget = new System.Drawing.Rectangle( 
									this.Location.X + (int)( Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_TEAMBORDER_LEFTSPACE ),
									this.Location.Y + (int)( nY + m_cTEAM_TEAMBORDER_TOPSPACE - nYOffset),0,0 );
					//Did we just select it?
					if( this.Location.X + oClickPoint.X >= oTarget.X && this.Location.X + oClickPoint.X <= oTarget.X + m_cTEAM_TEAMBORDER_WIDTH &&
						this.Location.Y + oClickPoint.Y >= oTarget.Y && this.Location.Y + oClickPoint.Y <= oTarget.Y + m_cTEAM_TEAMBORDER_HEIGHT )
					{
						oSelectedItem = oTeamIsland;
					}
					//Now render
					if( bDraw == true )
					{
						nColor = System.Drawing.Color.White;
						if( m_oSelected != null && m_oSelected == oTeamIsland )
						{
							nColor = System.Drawing.Color.Red;
						}

						base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_TEAMBORDER_TABLE,
									System.Drawing.Rectangle.Empty,oTarget,oDrawArea,
									Microsoft.DirectX.Vector2.Empty,0,0,false,nColor.ToArgb() );

						base.DSGraphicsWrapper.RenderText( this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_TEAMTEXT_LEFTSPACE,
														   this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_TEAMTEXT_TOPSPACE + nY - nYOffset,
														   System.Drawing.Color.White,
														   oTeamIsland.TeamSetup.Name,oDrawArea );
					}
					nY += 20;

					//Now render the team attributes
					bAddedTeamHeader = false;
					if( oTeamIsland.TeamSetup.SharedVision == true )
					{
						sTemp += "Shared Vision";

						//Draw the info
						base.DSGraphicsWrapper.RenderText( 
										this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_TEAMTEXT_LEFTSPACE,
										this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_BULLET_TOPSPACE + nY - nYOffset,
										System.Drawing.Color.White,sTemp,oDrawArea );
						nY += 12;
						bAddedTeamHeader = true;
					}
					if( oTeamIsland.TeamSetup.MinFuelSharedPerMinute > 0 ||
						oTeamIsland.TeamSetup.MinCreditsSharedPerMinute > 0 )
					{
						if( oTeamIsland.TeamSetup.MinFuelSharedPerMinute > 0 )
						{
							sTemp = oTeamIsland.TeamSetup.MinFuelSharedPerMinute.ToString() + " fuel";
						}
						if( oTeamIsland.TeamSetup.MinCreditsSharedPerMinute > 0 )
						{
							if( sTemp.Length > 0 ){ sTemp += ", "; }
							sTemp += oTeamIsland.TeamSetup.MinCreditsSharedPerMinute.ToString() + " credits";
						}
						sTemp = "Share " + sTemp + " / min";

						//Draw the info
						base.DSGraphicsWrapper.RenderText( 
										this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_TEAMTEXT_LEFTSPACE,
										this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_PLRTEXT_TOPSPACE + nY - nYOffset,
										System.Drawing.Color.White,sTemp,oDrawArea );
						nY += 12;
						bAddedTeamHeader = true;
					}
					if( bAddedTeamHeader == true )
					{
						nY += 8;
					}

					//Now how many players are on this team?
					for( int nPlayerIndex=0 ; nPlayerIndex<m_oApp.Game.Islands.Count ; nPlayerIndex++ )
					{
						oPlayerIsland = (Island)m_oApp.Game.Islands.GetByIndex( nPlayerIndex );

						//Is this guy in our current team?
						if( oPlayerIsland.GlobalIDOfPlayerWhoseTeamImOn == oTeamIsland.GlobalID ||
							oPlayerIsland.GlobalID == oTeamIsland.GlobalID )
						{
							oTexture = DSResourceManager.GetGlobalInstance().GetLoadedTexture( Game.m_cGOB_BULLETPOINT_TABLE );
							oTarget = new System.Drawing.Rectangle( 
											this.Location.X + (int)( Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_BULLET_LEFTSPACE ),
											this.Location.Y + (int)( Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_BULLET_TOPSPACE + nY - nYOffset ),0,0 );
							if( this.Location.X + oClickPoint.X >= oTarget.X && this.Location.X + oClickPoint.X <= oTarget.X + m_cTEAM_BULLET_WIDTH &&
								this.Location.Y + oClickPoint.Y >= oTarget.Y && this.Location.Y + oClickPoint.Y <= oTarget.Y + m_cTEAM_BULLET_HEIGHT )
							{
								oSelectedItem = oPlayerIsland;
							}
							if( bDraw == true )
							{
								//Yes!  Draw him
								oNetPlayer = (DSNetworkPlayer)m_oApp.DSGameEngine.DirectPlay.Players.GetByKey( oPlayerIsland.OwnerSocketID );

								nColor = System.Drawing.Color.White;
								if( oPlayerIsland.TeamJoinApproved == false &&
								    DateTime.Now.Second % 2 == 0 )
								{
									nColor = System.Drawing.Color.DarkBlue;
								}
								else if( m_oSelected != null && m_oSelected == oPlayerIsland )
								{
									nColor = System.Drawing.Color.Red;
								}

								base.DSGraphicsWrapper.RenderTexture2D( Game.m_cGOB_BULLETPOINT_TABLE,
											System.Drawing.Rectangle.Empty,oTarget,oDrawArea,
											Microsoft.DirectX.Vector2.Empty,0,0,false,nColor.ToArgb() );
							

								base.DSGraphicsWrapper.RenderText( this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_PLRTEXT_LEFTSPACE,
																   this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_PLRTEXT_TOPSPACE + nY - nYOffset,
																   System.Drawing.Color.White,
															       oNetPlayer.Name,oDrawArea );
							}
							nY += 20;

							//Now if this is a temporary approval, mark it.
							if( oPlayerIsland.TeamJoinApproved == false || 
								oPlayerIsland.TeamQuitPending == true )
							{
								if( bDraw == true )
								{
									nColor = System.Drawing.Color.White;
									if( DateTime.Now.Second % 2 == 0 )
									{
										nColor = System.Drawing.Color.DarkBlue;
									}

									if( oPlayerIsland.TeamJoinApproved == false )
									{
										sTemp = "Pending Approval";
									}
									else
									{
										sTemp = "Pending Quit";
									}

									base.DSGraphicsWrapper.RenderText( 
													this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH + m_cTEAM_PLRTEXT_LEFTSPACE + 15,
													this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH + m_cTEAM_PLRTEXT_TOPSPACE + nY - nYOffset - 10,
													nColor,sTemp,oDrawArea );
								}
								nY += 15;
							}
							
						}
					}
					nY += 50;
				}				
			}

			nHeight = nY;
		}


		public override void Render()
		{
			long nHeight = 0;
			long nOffset = 0;
			long nAvailableScreenSpace = 0;
			Island oSelectedIsland = null;
			System.Drawing.Rectangle oDrawRect;
			DSVertScrollBar oVertBar = null;


			if( this.Visible == true )
			{
				//Draw the black rendering area
				oDrawRect = GetDrawingArea();
				base.DSGraphicsWrapper.RenderRect2D( oDrawRect,System.Drawing.Color.Gray.ToArgb() ); 
				base.Render();

				//Draw our team layout
				CalculateAndDraw( out nHeight );

				oVertBar = (DSVertScrollBar)this.GetControl( "scrVertScroll" );
				nAvailableScreenSpace = (long)( this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH );
				if( nHeight < nAvailableScreenSpace )
				{
					CalculateAndDraw( true,0,System.Drawing.Rectangle.Empty,out nHeight,Point.Empty,out oSelectedIsland );
					oVertBar.Visible = false;
				}
				else
				{
					nOffset = GetOffset( nHeight );
					CalculateAndDraw( true,nOffset,
									  System.Drawing.Rectangle.Empty,out nHeight,Point.Empty,out oSelectedIsland );
					oVertBar.Visible = true;
				}

				SetupButtons();
			}
		}

		public override void OnInitialize()
		{
			DSEditBox oTextBox = null;
			DSVertScrollBar oVertBar = null;
			DSButton oButton = null;
			DSListBox oListBox = null;


			//Hook up our events
			oButton = (DSButton)this.GetControl( "cmdLeaveTeam" );
			oButton.Click += new EventHandler( cmdLeaveTeam_Click );

			oButton = (DSButton)this.GetControl( "cmdJoin" );
			oButton.Click += new EventHandler( cmdJoinTeam_Click );

			oButton = (DSButton)this.GetControl( "cmdKick" );
			oButton.Click += new EventHandler( cmdKickTeam_Click );

			oButton = (DSButton)this.GetControl( "cmdDisbandTeam" );
			oButton.Click += new EventHandler( cmdDisbandTeam_Click );

			oButton = (DSButton)this.GetControl( "cmdCreateTeam" );
			oButton.Click += new EventHandler( cmdCreateTeam_Click );

			oButton = (DSButton)this.GetControl( "cmdClose2" );
			oButton.Click += new EventHandler( cmdCloseTeamScreen_Click );

			oButton = (DSButton)this.GetControl( "cmdApprove" );
			oButton.Click += new EventHandler( cmdApprove_Click );

			oButton = (DSButton)this.GetControl( "cmdGiveResources" );
			oButton.Click += new EventHandler( cmdGiveRes_Click );


			oListBox = (DSListBox)this.GetControl( "lstUnassignedPlayers" );
			oListBox.Selection += new EventHandler( lstUnassignedPlayers_Click );


			oVertBar = (DSVertScrollBar)this.GetControl( "scrVertScroll" );
			oVertBar.TrackPosition = 0;
			oVertBar.SetTrackRange( 0,10 );

			oTextBox = (DSEditBox)this.GetControl( "txtSharedGold" );
			oTextBox.Text = m_oApp.GetMyIsland().Island.FuelSharedPerMinute.ToString();
			oTextBox.Changed += new EventHandler( txtSharedCredit_Changed );

			oTextBox = (DSEditBox)this.GetControl( "txtSharedFuel" );
			oTextBox.Text = m_oApp.GetMyIsland().Island.CreditsSharedPerMinute.ToString();
			oTextBox.Changed += new EventHandler( txtSharedFuel_Changed );


			SetupButtons();
		}


		public override bool IsResizeHotSpot( Vector2 vMousePosInFormSpace )
		{
			return( false );
		}

		public override bool IsMoveHotSpot( Vector2 vMousePosInFormSpace )
		{
			if( vMousePosInFormSpace.X <= Game.m_cBORDER_GRAY_LEFTWIDTH || 
				vMousePosInFormSpace.X >= this.Size.X - Game.m_cBORDER_GRAY_RIGHTWIDTH ||
				vMousePosInFormSpace.Y <= Game.m_cBORDER_GRAY_TOPWIDTH ||
				vMousePosInFormSpace.Y >= this.Size.Y - Game.m_cBORDER_GRAY_BOTTOMWIDTH )
			{
				return( true );
			}
			else
			{
				return( false );
			}
		}

		public override bool OnMouseUp(Vector2 vMousePosInFormSpace, long nButton)
		{
			long nHeight = 0;
			bool bActionUsed = false;


			bActionUsed = base.OnMouseUp( vMousePosInFormSpace, nButton );

			//If the user clicked on something that swipped our event then we won't run this code.
			//An example of this would be clicking the close button.
			if( bActionUsed == false )
			{
				//Draw our team layout
				CalculateAndDraw( out nHeight );
				CalculateAndDraw( false,GetOffset( nHeight ),System.Drawing.Rectangle.Empty,out nHeight,
								  new Point( (int)vMousePosInFormSpace.X,(int)vMousePosInFormSpace.Y ),
								  out m_oSelected );

				//Configure our buttons
				SetupButtons();
			}
				

			return( bActionUsed );
		}


		private long GetOffset( long nHeight )
		{
			long nPosition = 0;
			long nAvailableScreenSpace = 0;
			double nOffset = 0;
			DSVertScrollBar oVertBar = null;


			oVertBar = (DSVertScrollBar)this.GetControl( "scrVertScroll" );
			nPosition = oVertBar.TrackPosition;
			nAvailableScreenSpace = (long)( this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH );
			nOffset = ( nHeight - nAvailableScreenSpace ) * ( nPosition / 9.0 );


			return( (long)nOffset );
		}

		private System.Drawing.Rectangle GetDrawingArea()
		{
			System.Drawing.Rectangle oDrawRect = System.Drawing.Rectangle.Empty;

			oDrawRect = new Rectangle( (int)(this.Location.X + Game.m_cBORDER_GRAY_LEFTWIDTH),
									   (int)(this.Location.Y + Game.m_cBORDER_GRAY_TOPWIDTH),
									   (int)(this.Size.X - Game.m_cBORDER_GRAY_LEFTWIDTH - Game.m_cBORDER_GRAY_RIGHTWIDTH),
									   (int)(this.Size.Y - Game.m_cBORDER_GRAY_TOPWIDTH - Game.m_cBORDER_GRAY_BOTTOMWIDTH) );

			return( oDrawRect );
		}


		public void SetupButtons()
		{
			DSListBox oListBox = null;


			//Configure our bu/ttons
			((DSButton)this.GetControl( "cmdLeaveTeam" )).Enabled = false;
			((DSButton)this.GetControl( "cmdJoin" )).Enabled = false;
			((DSButton)this.GetControl( "cmdKick" )).Enabled = false;
			((DSButton)this.GetControl( "cmdDisbandTeam" )).Enabled = false;
			((DSButton)this.GetControl( "cmdCreateTeam" )).Enabled = false;
			((DSButton)this.GetControl( "cmdApprove" )).Enabled = false;
			((DSButton)this.GetControl( "cmdGiveResources" )).Enabled = false;

			//This means we didn't click on anything so don't let them do anything
			if( m_oSelected == null ){}
			//This means we clicked on a player in our team
			else if( m_oSelected.GlobalIDOfPlayerWhoseTeamImOn == m_oApp.GetMyIsland().Island.GlobalID && 
					m_oApp.GetMyIsland().Island.TeamSetup != null )
			{
				((DSButton)this.GetControl( "cmdKick" )).Enabled = true;
			}
			//This means we aen't in a team and we clicked on someone elses team
			else if( m_oApp.GetMyIsland().Island.TeamSetup == null &&
					m_oApp.GetMyIsland().Island.GlobalIDOfPlayerWhoseTeamImOn == "" &&
					m_oSelected.TeamSetup != null )
			{
				((DSButton)this.GetControl( "cmdJoin" )).Enabled = true;
			}

            
			//This means its our gteam and the guy is unapproved
			if( m_oSelected != null &&
				m_oSelected.GlobalIDOfPlayerWhoseTeamImOn == m_oApp.GetMyIsland().Island.GlobalID &&
			    (
					m_oSelected.TeamJoinApproved == false ||
					m_oSelected.TeamQuitPending == true
				)
			  )
			{
				((DSButton)this.GetControl( "cmdApprove" )).Enabled = true;
			}
			//No matter what if we are not in a team then we can create one
			if( m_oApp.GetMyIsland().Island.GlobalIDOfPlayerWhoseTeamImOn == "" &&
				m_oApp.GetMyIsland().Island.TeamSetup == null )
			{
				((DSButton)this.GetControl( "cmdCreateTeam" )).Enabled = true;
			}
			//No matter what if we own a team we can dispand it
			if( m_oApp.GetMyIsland().Island.TeamSetup != null )
			{
				((DSButton)this.GetControl( "cmdDisbandTeam" )).Enabled = true;
			}
			//No matter what let me leave a team if i'm on it
			if( m_oApp.GetMyIsland().Island.GlobalIDOfPlayerWhoseTeamImOn != "" &&
				m_oApp.GetMyIsland().Island.TeamSetup == null &&
				m_oApp.GetMyIsland().Island.TeamQuitPending == false )
			{
				((DSButton)this.GetControl( "cmdLeaveTeam" )).Enabled = true;
			}
			//No matter what if we click on another player we can give resources
			if( m_oSelected != null && m_oSelected.IsMyIsland() == false )
			{
				((DSButton)this.GetControl( "cmdGiveResources" )).Enabled = true;
			}


			//Configure the list of unassigned players
			oListBox = (DSListBox)this.GetControl( "lstUnassignedPlayers" );
			if( oListBox.NumberItems != GetUnassignedPlayerCount( null ) )
			{
				lock( oListBox )
				{
					GetUnassignedPlayerCount( oListBox );
				}
			}
		}
		private long GetUnassignedPlayerCount( DSListBox oPopulateThisListWithThem )
		{
			long nPlayerCount = 0;
			Island oPlayerIsland = null;
			DSNetworkPlayer oNetPlayer = null;
			string sGlobalID = "";


			try
			{
				//Make sure we don't clear the one we have selected
				if( oPopulateThisListWithThem != null )
				{
					if( oPopulateThisListWithThem.GetSelectedIndex() != -1 )
					{
						sGlobalID = (string)oPopulateThisListWithThem.GetSelectedItem().ItemData;
					}
					else
					{
						sGlobalID = "";
					}
			
					//Walk the list of islands and count how tall this needs to be
					oPopulateThisListWithThem.Clear();
				}

				for( int nPlayerIndex=0 ; nPlayerIndex<m_oApp.Game.Islands.Count ; nPlayerIndex++ )
				{
					oPlayerIsland = (Island)m_oApp.Game.Islands.GetByIndex( nPlayerIndex );
					if( oPlayerIsland.AIOwnerGlobalID.Length == 0 )
					{
						oNetPlayer = m_oApp.DSGameEngine.DirectPlay.GetPlayer( oPlayerIsland.OwnerSocketID );
						//Only if the player is unassigned and not us
						if( oPlayerIsland.TeamSetup == null && oPlayerIsland.GlobalIDOfPlayerWhoseTeamImOn == "" &&
							oPlayerIsland.IsMyIsland() == false )
						{
							if( oPopulateThisListWithThem != null )
							{
								oPopulateThisListWithThem.AddItem( oNetPlayer.Name,oPlayerIsland.GlobalID );

								//Reselect our item
								if( oPlayerIsland.GlobalID == sGlobalID )
								{
									oPopulateThisListWithThem.SelectItem( nPlayerIndex );
								}
							}
							nPlayerCount++;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				DSMisc.ShowErrors( oEx );
			}


			return( nPlayerCount );
		}
		

		private void txtSharedCredit_Changed( object sender, EventArgs e )
		{
			DSEditBox oTextBox = null;
			Island oIsland = m_oApp.GetMyIsland().Island;
			Island oTeamIsland = null;
			bool bRefresh = false;


			oTextBox = (DSEditBox)this.GetControl( "txtSharedGold" );

			if( DSMisc.IsNumericLong( oTextBox.Text ) == true )
			{
				if( Convert.ToInt64( oTextBox.Text ) < 0 )
				{
					oIsland.CreditsSharedPerMinute = 0;
				}
				else
				{
					oIsland.CreditsSharedPerMinute = Convert.ToInt64( oTextBox.Text );
					bRefresh = true;
				}
			}
			else
			{
				oIsland.CreditsSharedPerMinute = 0;
			}

            //Make sure it wasn't set to low
			oTeamIsland = m_oApp.Game.GetTeamsIsland( oIsland.GlobalID );
			if( oTeamIsland != null )
			{
				if( oTeamIsland.TeamSetup.MinCreditsSharedPerMinute > oIsland.CreditsSharedPerMinute )
				{
					oIsland.CreditsSharedPerMinute = oTeamIsland.TeamSetup.MinCreditsSharedPerMinute;
					bRefresh = true;
				}
			}	
		
			//Update the GUI
			if( bRefresh == true )
			{
				oTextBox.Text = oIsland.CreditsSharedPerMinute.ToString();
			}
			m_oApp.SendIslandUpdate( oIsland );
		}
		private void txtSharedFuel_Changed( object sender, EventArgs e )
		{
			DSEditBox oTextBox = null;
			Island oIsland = m_oApp.GetMyIsland().Island;
			Island oTeamIsland = null;
			bool bRefresh = false;


			oTextBox = (DSEditBox)this.GetControl( "txtSharedFuel" );

			if( DSMisc.IsNumericLong( oTextBox.Text ) == true )
			{
				if( Convert.ToInt64( oTextBox.Text ) < 0 )
				{
					oIsland.FuelSharedPerMinute = 0;
				}
				else
				{
					oIsland.FuelSharedPerMinute = Convert.ToInt64( oTextBox.Text );
					bRefresh = true;
				}
			}
			else
			{
				oIsland.FuelSharedPerMinute = 0;
			}

			//Make sure it wasn't set to low
			oTeamIsland = m_oApp.Game.GetTeamsIsland( oIsland.GlobalID );
			if( oTeamIsland != null )
			{
				if( oTeamIsland.TeamSetup.MinFuelSharedPerMinute > oIsland.FuelSharedPerMinute )
				{
					oIsland.FuelSharedPerMinute = oTeamIsland.TeamSetup.MinFuelSharedPerMinute;
					bRefresh = true;
				}
			}
		
			//Update the GUI
			if( bRefresh == true )
			{
				oTextBox.Text = oIsland.FuelSharedPerMinute.ToString();
			}
			m_oApp.SendIslandUpdate( oIsland );
		}
		private void cmdLeaveTeam_Click( object sender, EventArgs e )
		{
			Island oOurCurTeam = null;
			Island oOurIsland = null;


			//Get our team
			oOurIsland = m_oApp.GetMyIsland().Island;
			oOurCurTeam = (Island)m_oApp.GetIsland( oOurIsland.GlobalIDOfPlayerWhoseTeamImOn ).Island;

			//Does this team have a disband policy?
			if( oOurCurTeam.TeamSetup.MutualTeamDeparturesRequired == true )
			{
				oOurIsland.TeamQuitPending = true;
			}
			else
			{
				oOurIsland.GlobalIDOfPlayerWhoseTeamImOn = "";
			}

			//Send the update			
			m_oApp.SendIslandUpdate( oOurIsland );
			SetupButtons();
		}
		private void cmdJoinTeam_Click( object sender, EventArgs e )
		{
			Island oMyIsland = m_oApp.GetMyIsland().Island;


			//Can we join?
			if( oMyIsland.FuelSharedPerMinute >= m_oSelected.TeamSetup.MinFuelSharedPerMinute &&
				oMyIsland.CreditsSharedPerMinute >= m_oSelected.TeamSetup.MinCreditsSharedPerMinute )
			{
				oMyIsland.GlobalIDOfPlayerWhoseTeamImOn = m_oSelected.GlobalID;
				oMyIsland.TeamJoinApproved = false;
				m_oApp.SendIslandUpdate( oMyIsland );
				SetupButtons();
			}
			else
			{
				m_oApp.UpdateStatus( Game.m_cALERT_INFO + "You do not meet the minimum requirements to join this team" );
			}
		}
		private void cmdKickTeam_Click( object sender, EventArgs e )
		{
			m_oApp.SendTeamKick( m_oSelected );
			m_oSelected = null;
			SetupButtons();
		}
		private void cmdDisbandTeam_Click( object sender, EventArgs e )
		{
			m_oApp.SendTeamDisband( m_oApp.GetMyIsland().Island );
			m_oApp.GetMyIsland().Island.TeamSetup = null;
			m_oApp.SendIslandUpdate( m_oApp.GetMyIsland().Island );
			m_oSelected = null;
			SetupButtons();
		}
		private void cmdCreateTeam_Click( object sender, EventArgs e )
		{
			m_oApp.StartCreateTeamForm( false );
			m_oApp.SwitchMenus( this.Name,Game.m_cFRM_CREATETEAM,true );
		}

		private void cmdGiveRes_Click( object sender, EventArgs e )
		{
			m_oApp.StartGiveResourcesForm( false,m_oSelected );
			m_oApp.SwitchMenus( this.Name,Game.m_cFRM_GIVERES,true );
		}
		private void cmdApprove_Click( object sender, EventArgs e )
		{
			m_oApp.SendPlayerApprove( m_oSelected );
		}
		private void cmdCloseTeamScreen_Click( object sender, EventArgs e )
		{
			//Update our team count
			m_oApp.GetMyIsland().Island.NumberOfTeamMembers = m_oApp.Game.GetTeamCount( m_oApp.GetMyIsland().Island );
			m_oApp.GetMyIsland().Island.TeamChanged = false;

			m_oApp.SwitchMenus( this.Name,"",false );
			//this.Visible = false;
		}

		private void lstUnassignedPlayers_Click(object sender, EventArgs e )
		{
			DSListBox oListBox = null;
			string sGlobalID = "";
			Island oIsland = null;


			//Find out who we clicked on
			oListBox = (DSListBox)this.GetControl( "lstUnassignedPlayers" );

			lock( oListBox )
			{
				if( oListBox.GetSelectedIndex() != -1 )
				{
					sGlobalID = (string)oListBox.GetSelectedItem().ItemData;

					//Find the island
					oIsland = m_oApp.GetIsland( sGlobalID ).Island;
					if( oIsland != null )
					{
						m_oSelected = oIsland;
					}
				}
			}
		}



		#region Properties
		public MetalMarines App
		{
			get
			{
				return( m_oApp );
			}
			set
			{
				m_oApp = value;
			}
		}
		#endregion
	}
	#endregion
}