using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Reflection;

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


namespace DarkStrideToolbox
{
	#region DSMenus Class
	public class DSMenus
	{
		#region Properties
		//This is the actual DSMenu data storage
		private DSMenu[] m_oaMenusInZOrder = null;
		private int m_nMaxMenuSize = 50;
		private int m_nNextFreeIndex = 0;
		private int m_nCurrentMoveIndex = -1;

		//Track mouse movements so we know where focuses are and such
		private DSMenu m_oMenuMouseDownOn = null;

		//Keep track of who has focus
		private DSMenu m_oMenuWithFocus = null;

		private DSGraphicsWrapper m_oDSGraphicsWrapper = null;
		#endregion


		public DSMenus( DSGraphicsWrapper oDSGraphicsWrapper )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Menus";

			try
			{
				m_oDSGraphicsWrapper = oDSGraphicsWrapper;
				m_oaMenusInZOrder = new DSMenu[ m_nMaxMenuSize ];
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//Returns weather or not the mouse event was used by the DSMenu.  The mouse cursor returned is the mouse cursor
		//the DSMenu would like to have used.	
		public bool MouseDown( Vector2 vMousePosInScrSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MouseDown";
			DSMenu oMenuClickedOn = null;
			Vector2 vMousePosInMenuSpace;
			bool bMouseActionWasUsed = false;

			try
			{
				//Did they click on a DSMenu?  If so its either a control click or a DSMenu moving
				oMenuClickedOn = GetMenuAt( vMousePosInScrSpace );

				//No DSMenu.  Just an idle screen click.  Ignore it.
				if( oMenuClickedOn == null )
				{
					m_oMenuMouseDownOn = null;
					m_oMenuWithFocus = null;
					bMouseActionWasUsed = false;
				}
					//They clicked on a DSMenu!  
				else
				{
					vMousePosInMenuSpace = vMousePosInScrSpace - oMenuClickedOn.Pos;

					m_oMenuWithFocus = oMenuClickedOn;
					m_oMenuMouseDownOn = oMenuClickedOn;
					oMenuClickedOn.MouseDown( vMousePosInMenuSpace,nButton );
					MoveMenuToTop( oMenuClickedOn.Name );

					bMouseActionWasUsed = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bMouseActionWasUsed );
		}
		public bool MouseUp( Vector2 vMousePosInScrSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MouseUp";
			bool bMouseActionWasUsed = false;
			Vector2 vMousePosInMenuSpace;

			try
			{
				if( m_oMenuMouseDownOn != null )
				{
					//12/18/2004 Chris Hill  The click location was being passsed in as screen
					//space not menuy space as we really needed it to be.
					vMousePosInMenuSpace = vMousePosInScrSpace - m_oMenuMouseDownOn.Pos;

					m_oMenuMouseDownOn.MouseUp( vMousePosInMenuSpace,nButton );
					bMouseActionWasUsed = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
			return( bMouseActionWasUsed );
		}

		public bool MouseMoved( Vector2 vMousePosInScrSpace,MouseState oMouseState,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MouseMoved";
			DSMenu oMenuMovedOver = null;
			Vector2 vMousePosInMenuSpace;
			bool bMouseActionWasUsed = false;

			try
			{
				//11/16/2004 Chris Hill  If you do a sliding click on an exit button then you can cuase the menu to 
				//call this even though most of the member variables are gone.  So just exit out.
				if( m_oaMenusInZOrder != null )
				{
					oMenuMovedOver = GetMenuAt( vMousePosInScrSpace );

					if( oMenuMovedOver == null )
					{
						bMouseActionWasUsed = false;
					}
					else
					{
						vMousePosInMenuSpace = vMousePosInScrSpace - oMenuMovedOver.Pos;
						oMenuMovedOver.MouseMoved( vMousePosInMenuSpace,baButtons );
						bMouseActionWasUsed = true;
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
			return( bMouseActionWasUsed );
		}
		public bool MouseWheelMoved( long nDirection )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MouseWheelMoved";
			bool bMouseActionWasUsed = false;

			try
			{
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
			return( bMouseActionWasUsed );
		}

		//These functions are where the keyboard input comes in from
		public bool KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.KeyboardKeyDown";
			bool bMouseActionWasUsed = false;

			try
			{
				if( m_oMenuWithFocus != null )
				{
					m_oMenuWithFocus.KeyboardKeyDown( oKey,oState );
					bMouseActionWasUsed = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bMouseActionWasUsed );
		}
		public bool KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.KeyboardKeyUp";
			bool bMouseActionWasUsed = false;

			try
			{
				if( m_oMenuWithFocus != null )
				{
					m_oMenuWithFocus.KeyboardKeyUp( oKey,oState );
					bMouseActionWasUsed = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bMouseActionWasUsed );
		}


		//Handle the maintance of our array
		public DSMenu Add( string sMenuName,Vector2 vPosition,Vector2 vSize,bool bIsModal )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Add";
			DSMenu oNewMenu = null;

			try
			{
				oNewMenu = Add( sMenuName,"System_Form",vPosition,vSize,bIsModal );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewMenu );
		}
		public DSMenu Add( string sMenuName,string sMenuTextureKey,Vector2 vPosition,Vector2 vSize,bool bIsModal )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Add";
			DSMenu oNewMenu = null;

			try
			{
				oNewMenu = new DSMenu( m_oDSGraphicsWrapper );

				oNewMenu.Name = sMenuName;
				oNewMenu.Pos = vPosition;
				oNewMenu.Size = vSize;
				oNewMenu.IsModal = bIsModal;
				oNewMenu.TextureKey = sMenuTextureKey;

				//Save our work
				Add( oNewMenu );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewMenu );
		}

		public void Add( DSMenu oNewMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Add";

			try
			{
				//First make sure they aren't breaking modal, non-modal rules
				if( oNewMenu.IsModal == false && this.IsModalForm == true )
				{
					throw new System.Exception( "You cannot add a non-modal DSMenu when their is already a modal DSMenu in use. <" + oNewMenu.Name + "." );
				}

				if( m_nNextFreeIndex < m_nMaxMenuSize )
				{
					m_oaMenusInZOrder[ m_nNextFreeIndex++ ] = oNewMenu;
				}
				else
				{
					throw new System.Exception( "Adding DSMenu exceeds limit.  This functionality needs to be enhanced to dynamically grow in size." );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public void Remove( string sMenuName )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Remove";
			int nIndex = -1;

			try
			{
				nIndex = GetMenuIndex( sMenuName );

				if( m_oaMenusInZOrder[ nIndex ] != null )
				{
					if( m_oMenuWithFocus != null )
					{
						if( m_oMenuWithFocus.Name.Equals( m_oaMenusInZOrder[ nIndex ].Name ) == true )
						{
							m_oMenuWithFocus = null;
						}
					}

					if( m_oMenuMouseDownOn != null )
					{
						if( m_oMenuMouseDownOn.Name.Equals( m_oaMenusInZOrder[ nIndex ].Name ) == true )
						{
							m_oMenuMouseDownOn = null;
						}
					}
				}

				m_oaMenusInZOrder[ nIndex ] = null;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public DSMenu GetMenu( string sMenuName )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetMenu";
			DSMenu oRetMenu = null;
			int nIndex = -1;

			try
			{
				nIndex = GetMenuIndex( sMenuName );
				if( nIndex != -1 )
				{
					oRetMenu = m_oaMenusInZOrder[ nIndex ];
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetMenu );
		}
		public int GetMenuIndex( string sMenuName )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetMenuIndex";
			int nMenuIndex = -1;

			try
			{
				if( sMenuName == null )
				{
					//02/19/2005 Chris Hill  If you pass in a null name then throw an error.
					throw new System.Exception( "Menu names can't be null." );
				}
				else
				{
					for( int i=0 ; i<m_nNextFreeIndex ; i++ )
					{
						if( m_oaMenusInZOrder[ i ] != null )
						{
							if( m_oaMenusInZOrder[ i ].Name.Equals( sMenuName ) == true )
							{
								nMenuIndex = i;
								break;
							}
						}
					}

					/*if( nMenuIndex == -1 )
					{
						throw new System.Exception( "Unable to locate DSMenu <" + sMenuName + ">" );
					}*/
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nMenuIndex );
		}

		public DSMenu GetMenuAt( Vector2 vMouseClickInScrSpace )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetMenuAt";
			DSMenu oMenu = null;
			DSMenu oRetVal = null;

			try
			{
				for( int i=m_nNextFreeIndex ; i>=0 ; i-- )
				{
					oMenu = m_oaMenusInZOrder[ i ];
					if( oMenu != null )
					{
						if( vMouseClickInScrSpace.X >= oMenu.Pos.X && vMouseClickInScrSpace.Y >= oMenu.Pos.Y &&
							vMouseClickInScrSpace.X <= oMenu.Pos.X + oMenu.Size.X &&
							vMouseClickInScrSpace.Y <= oMenu.Pos.Y + oMenu.Size.Y )
						{
							oRetVal = oMenu;
							break;
						}
							//If this form is modal we can't go any lower... so no click was registered
						else if( oMenu.IsModal == true )
						{
							break;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetVal );
		}

		public void MoveMenuToTop( string sMenuName )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MoveMenuToTop";
			int nIndex = -1;

			try
			{
				nIndex = GetMenuIndex( sMenuName );

				m_oaMenusInZOrder[ m_nNextFreeIndex++ ] = m_oaMenusInZOrder[ nIndex ];
				m_oaMenusInZOrder[ nIndex ] = null;

				ReShuffleZOrders();
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		private void ReShuffleZOrders()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.ReShuffleZOrders";
			bool bReplacementDone = false;

			try
			{
				for( int i=0 ; i<m_nNextFreeIndex ; i++ )
				{
					if( m_oaMenusInZOrder[ i ] == null )
					{
						//Now find the next non-null DSMenu spot
						bReplacementDone = false;
						for( int nNextUsedSpot=i+1 ; nNextUsedSpot<m_nNextFreeIndex ; nNextUsedSpot++ )
						{
							if( m_oaMenusInZOrder[ nNextUsedSpot ] != null )
							{
								bReplacementDone = true;
								m_oaMenusInZOrder[ i ] = m_oaMenusInZOrder[ nNextUsedSpot ];
								m_oaMenusInZOrder[ nNextUsedSpot ] = null;
								break;
							}
						}

						//If we didn't do a replacement then the next free spot gets moved up
						if( bReplacementDone == false )
						{
							m_nNextFreeIndex = i;
							break;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		private void ReDimArray()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.ReDimArray";
			DSMenu[] oaTempStorage = null;

			try
			{
				//Create a new array
				m_nMaxMenuSize = m_nMaxMenuSize * 2;
				oaTempStorage = new DSMenu[ m_nMaxMenuSize ];
				
				//Now copy over our data
				for( int i=0 ; i<m_nNextFreeIndex ; i++ )
				{
					oaTempStorage[ i ] = m_oaMenusInZOrder[ i ];
				}

				//And finally copy over our new array
				m_oaMenusInZOrder = oaTempStorage;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		private int GetHighestMenuIndex()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetHighestMenuIndex";
			int nRetVal = 0;

			try
			{
				//Chris
				//				m_bIsModalForm = IsModalForm();

				for( int nIndex=m_nNextFreeIndex-1 ; nIndex>0 ; nIndex-- )
				{
					if( m_oaMenusInZOrder[ nIndex ] != null )
					{
						nRetVal = nIndex;
						break;
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nRetVal );
		}

		public bool PointCanBeClickedOn( DSMenu oMenu,Vector2 vScreenPoint )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.PointCanBeClickedOn";
			int nMyIndex = 0;
			bool bCanBeClickedOn = true;

			try
			{
				//First of all find me in the array o' menus
				nMyIndex = GetMenuIndex( oMenu.Name );

				//Now walk up the list 
				for( int nIndex=nMyIndex+1 ; nIndex<m_nNextFreeIndex ; nIndex++ )
				{
					if( m_oaMenusInZOrder[ nIndex ] != null )
					{
						//Is the point within the range of the menus above us?  If so then we can't click on it
						if( vScreenPoint.X >= m_oaMenusInZOrder[ nIndex ].Pos.X && vScreenPoint.X <= m_oaMenusInZOrder[ nIndex ].Pos.X+m_oaMenusInZOrder[ nIndex ].Size.X && 
							vScreenPoint.Y >= m_oaMenusInZOrder[ nIndex ].Pos.Y && vScreenPoint.Y <= m_oaMenusInZOrder[ nIndex ].Pos.Y+m_oaMenusInZOrder[ nIndex ].Size.Y )
						{
							bCanBeClickedOn = false;
							break;
						}
							//But their is more... is their a modal form above us?  If so it can't be clicked on
						else if( m_oaMenusInZOrder[ nIndex ].IsModal == true )
						{
							bCanBeClickedOn = false;
							break;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bCanBeClickedOn );
		}


		//This of course is where we render the DSMenu from 
		public void Render()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.Render";

			try
			{
				for( int nIndex=0 ; nIndex<m_nNextFreeIndex ; nIndex++ )
				{
					if( m_oaMenusInZOrder[ nIndex ] != null )
					{
						m_oaMenusInZOrder[ nIndex ].Render( this );
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public string GetCurrentCursorTextureKey( Vector2 vMousePosInScrSpace )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetCurrentCursorTextureKey";
			DSMenu oMenuMouseOver = null;
			Vector2 vMousePosInMenuSpace;
			string sRetVal = "";

			try
			{
				oMenuMouseOver = GetMenuAt( vMousePosInScrSpace );

				if( oMenuMouseOver != null )
				{
					vMousePosInMenuSpace = vMousePosInScrSpace - oMenuMouseOver.Pos;
					sRetVal = oMenuMouseOver.GetCurrentCursorTextureKey( vMousePosInMenuSpace );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sRetVal );
		}

		public void FrameMove( float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.FrameMove";

			try
			{
				for( int nIndex=0 ; nIndex<m_nNextFreeIndex ; nIndex++ )
				{
					if( m_oaMenusInZOrder[ nIndex ] != null )
					{
						m_oaMenusInZOrder[ nIndex ].FrameMove( this,fElapsedTime,fAppTime );
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void Dispose()
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.Dispose";

			try
			{
				m_oMenuMouseDownOn = null;
				m_oMenuWithFocus = null;

				for( int i=m_nNextFreeIndex ; i>=0 ; i-- )
				{
					if( m_oaMenusInZOrder[ i ] != null )
					{
						m_oaMenusInZOrder[ i ].Dispose();
						m_oaMenusInZOrder[ i ] = null;
					}
				}

				m_oaMenusInZOrder = null;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//Navigation Functions
		public void MoveFirst()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MoveFirst";

			try
			{
				m_nCurrentMoveIndex = -1;

				for( int i=0 ; i<m_nNextFreeIndex ; i++ )
				{
					if( m_oaMenusInZOrder[ i ] != null )
					{
						m_nCurrentMoveIndex = i;
						break;
					}
				}				
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public void MoveNext()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.MoveNext";
			int i = -1;

			try
			{
				i = m_nCurrentMoveIndex + 1;
				m_nCurrentMoveIndex = -1;
				for( ; i<m_nNextFreeIndex ; i++ )
				{
					if( m_oaMenusInZOrder[ i ] != null )
					{
						m_nCurrentMoveIndex = i;
						break;
					}
				}		
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public DSMenu GetItem()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetItem";
			DSMenu oRetMenu = null;

			try
			{
				if( GetEOF() == false )
				{
					oRetMenu = m_oaMenusInZOrder[ m_nCurrentMoveIndex ];
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetMenu );
		}
		public bool GetEOF()
		{
			const string sRoutineName = "DarkStrideToolbox.Menus.GetEOF";
			bool bEOF = false;

			try
			{
				bEOF = ( m_nCurrentMoveIndex == -1 );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bEOF );
		}

		public long Count
		{
			get
			{
				const string sRoutineName = "DarkStrideToolbox.Menus.get_Count";
				long nCount = 0;

				try
				{				
					for( int i=0 ; i<m_nNextFreeIndex ; i++ )
					{
						if( m_oaMenusInZOrder[ i ] != null )
						{
							nCount++;
						}
					}				
				}
				catch( System.Exception oEx )
				{
					throw new System.Exception( sRoutineName + " Failed.",oEx );
				}

				return( nCount );
			}
		}



		#region Properties
		public bool IsModalForm
		{
			get
			{
				const string sRoutineName = "DarkStrideToolbox.Menus.IsModalForm";
				DSMenu oMenu = null;
				bool bRetVal = false;

				try
				{
					for( int i=0 ; i<m_nNextFreeIndex ; i++ )
					{
						oMenu = m_oaMenusInZOrder[ i ];
						if( oMenu != null )
						{
							if( oMenu.IsModal == true )
							{
								bRetVal = true;
								break;
							}
						}
					}
				}
				catch( System.Exception oEx )
				{
					throw new System.Exception( sRoutineName + " Failed.",oEx );
				}

				return( bRetVal );
			}
		}
		public DSMenu MenuWithFocus
		{
			get
			{
				return( m_oMenuWithFocus );
			}
		}
		#endregion
	};
	#endregion
    
	#region DSMenu Class
	public class DSMenu
	{
		//Chris 9c
		public static readonly ColorValue WhiteColorValue = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f); 
		public static readonly ColorValue TransparentWhite = new ColorValue(1.0f, 1.0f, 1.0f, 0.0f); 
		public static readonly ColorValue BlackColorValue = new ColorValue(0.0f, 0.0f, 0.0f, 1.0f); 
		private static DSBaseControl controlFocus = null; // The control which has focus
		private static DSBaseControl controlMouseOver = null; // The control which is hovered over
		private static DSBaseControl controlMouseDown = null; // The control which the mouse was pressed on
//private ArrayList defaultElementList = new ArrayList();
private DSBaseControl m_oControlMouseOver = null;

		#region Properties
		//Basic properties of the DSMenu
		private Vector2 m_vSize;
		private Vector2 m_vPos;
		private string m_sName;
		private string m_sTextureKey;
		private string m_sMouseCursorTextureKey;
		private bool m_bIsModal;
		private bool m_bCanBeDragged;		
		private string m_sText = "";

		//Collection of the controls on this form
		private SortedList m_oControls = new SortedList();

		//Mouse control things
		private Vector2 m_vMenuDraggingPoint;
		private bool m_bBeingDragged = false;
		private DSBaseControl m_oControlMouseDownOn = null;

		//Focus management
		private DSBaseControl m_oControlWithFocus = null;

		//Event/Delegate tracking
		private DelegateMouseDown		m_odDelegate_MouseDown		= null;
		private DelegateMouseUp			m_odDelegate_MouseUp		= null;
		private DelegateMouseMoved		m_odDelegate_MouseMoved		= null;
		private DelegateMouseClicked	m_odDelegate_MouseClicked	= null;
		private DelegateKeyDown			m_odDelegate_KeyDown		= null;
		private DelegateKeyUp			m_odDelegate_KeyUp			= null;
		public delegate void DelegateMouseDown( Vector2 vMousePosInControlSpace,long nButton );
		public delegate void DelegateMouseUp( Vector2 vMousePosInControlSpace,long nButton );
		public delegate void DelegateMouseMoved( Vector2 vMousePosInControlSpace,bool[] baButtons );
		public delegate void DelegateMouseClicked( Vector2 vMousePosInControlSpace,bool[] baButtons );
		public delegate void DelegateKeyDown( Key oKey,bool[] oState );
		public delegate void DelegateKeyUp( Key oKey,bool[] oState );

		private DSGraphicsWrapper m_oDSGraphicsWrapper = null;

		private bool m_bHaveInitedMenu = false;
		#endregion


		public DSMenu()
		{
//			InitializeDefaultElements();
		}
		public DSMenu( DSGraphicsWrapper oDSGraphicsWrapper )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Button";

			try
			{
				m_oDSGraphicsWrapper  = oDSGraphicsWrapper;
//				InitializeDefaultElements();
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


/*		//Control minipulation
		public DSButtonControl AddControl_Button( string sControlName,Vector2 vPosition,Vector2 vSize,string sText,DSButtonControl.DelegateClick odClick )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Button";
			DSButtonControl oNewCtrl = null;

			try
			{
				oNewCtrl = AddControl_Button( sControlName,vPosition,vSize,sText );
				oNewCtrl.RegisterDelegate_Click( odClick );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}*/
//Chris
		public DSButton AddControl_SpecialButton( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Button";
			DSButton b = null;

			try
			{
				// First create the button
				b = new DSButton(null,this);
				b.OnInitialize();

				// Set the properties of the button now
				b.ID = 0;
				b.Label = sText;
				b.SetLocation((int)vPosition.X, (int)vPosition.Y);
				b.SetSize((int)vSize.X,(int)vSize.Y);
				b.IsVisible = true;
				//b.Hotkey = "T";
				//b.isDefault = isDefault;

				AddControl( b,sControlName,vPosition,vSize );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( b );
		}
		public DSLabel AddControl_SpecialLabel( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			DSLabel oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSLabel( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.Label = sText;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;
			//b.Hotkey = "T";
			//b.isDefault = isDefault;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}

		public DSCheckBox AddControl_SpecialCheckBox( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			DSCheckBox oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSCheckBox( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.Label = sText;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;
			//b.Hotkey = "T";
			//b.isDefault = isDefault;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}

		public DSRadioButton AddControl_SpecialRadioButton( string sControlName,int nGroup,Vector2 vPosition,Vector2 vSize,string sText )
		{
			DSRadioButton oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSRadioButton( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.Label = sText;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;
			oNewCtrl.ButtonGroup = nGroup;
			//b.Hotkey = "T";
			//b.isDefault = isDefault;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}

		public DSComboBox AddControl_ComboBoxButton( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			DSComboBox oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSComboBox( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}

		public DSSlider AddControl_Slider( string sControlName,Vector2 vPosition,Vector2 vSize )
		{
			DSSlider oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSSlider( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}
		public DSListBox AddControl_ListBox( string sControlName,Vector2 vPosition,Vector2 vSize,ListBoxStyle style )
		{
			DSListBox oNewCtrl = null;


			// First create the button
			oNewCtrl = new DSListBox( null,this );
			oNewCtrl.OnInitialize();

			// Set the properties of the button now
			oNewCtrl.ID = 0;
			oNewCtrl.SetLocation((int)vPosition.X, (int)vPosition.Y);
			oNewCtrl.SetSize((int)vSize.X,(int)vSize.Y);
			oNewCtrl.IsVisible = true;
			oNewCtrl.Style = style;

			AddControl( oNewCtrl,sControlName,vPosition,vSize );

			return( oNewCtrl );
		}


		#region Old Controls
		/*
		public DSButtonControl AddControl_Button( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Button";
			DSButtonControl oNewCtrl = null;

			try
			{
				oNewCtrl = new DSButtonControl();
				oNewCtrl.Text = sText;
				AddControl( oNewCtrl,sControlName,vPosition,vSize );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		public DSTextControl AddControl_Text( string sControlName,Vector2 vPosition,Vector2 vSize )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Text";
			DSTextControl oNewCtrl = null;

			try
			{
				oNewCtrl = AddControl_Text( sControlName,vPosition,vSize,"" );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		public DSTextControl AddControl_Text( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Text";
			DSTextControl oNewCtrl = null;

			try
			{
				oNewCtrl = new DSTextControl();
				oNewCtrl.Text = sText;
				AddControl( oNewCtrl,sControlName,vPosition,vSize );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		public DSLabelControl AddControl_Label( string sControlName,Vector2 vPosition,Vector2 vSize )
		{
			const string sRoutineName = "DarkStrideToolbox.AddControl_Label.AddControl_Text";
			DSLabelControl oNewCtrl = null;

			try
			{
				oNewCtrl = AddControl_Label( sControlName,vPosition,vSize,"" );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		public DSLabelControl AddControl_Label( string sControlName,Vector2 vPosition,Vector2 vSize,string sText )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl_Label";
			DSLabelControl oNewCtrl = null;

			try
			{
				oNewCtrl = new DSLabelControl();
				oNewCtrl.Text = sText;
				AddControl( oNewCtrl,sControlName,vPosition,vSize );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		public DSListBoxControl AddControl_ListBox( string sControlName,Vector2 vPosition,Vector2 vSize )
		{
			const string sRoutineName = "DarkStrideToolbox.AddControl_Label.AddControl_ListBox";
			DSListBoxControl oNewCtrl = null;

			try
			{
				oNewCtrl = new DSListBoxControl();
				AddControl( oNewCtrl,sControlName,vPosition,vSize );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}
		*/
		#endregion
		public DSBaseControl AddControl( DSBaseControl oNewCtrl,string sControlName,Vector2 vPosition,Vector2 vSize )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.AddControl";

			try
			{
				oNewCtrl.DSGraphicsWrapper = m_oDSGraphicsWrapper;
				oNewCtrl.Name = sControlName;
				oNewCtrl.Pos = vPosition;
				oNewCtrl.Size = vSize;

				m_oControls.Add( sControlName,oNewCtrl );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oNewCtrl );
		}

		
		public DSBaseControl GetControlAt( Vector2 vMousePosInMenuSpace )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.GetControlAt";
			DSBaseControl oControl = null;
			DSBaseControl oRetVal = null;

			try
			{
				if( m_oControls != null )
				{
					for( int i=0 ; i<m_oControls.Count ; i++ )
					{
						oControl = (DSBaseControl)m_oControls.GetByIndex( i );
						if( oControl != null )
						{
							if( oControl.ContainsPoint( new Point( (int)vMousePosInMenuSpace.X,(int)vMousePosInMenuSpace.Y ) ) == true )
							{
								oRetVal = oControl;
								break;
							}
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetVal );
		}

		public DSBaseControl GetControl( string sControlName )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.GetControl";
			DSBaseControl oControl = null;
			DSBaseControl oRetVal = null;

			try
			{
				for( int i=0 ; i<m_oControls.Count ; i++ )
				{
					oControl = (DSBaseControl)m_oControls.GetByIndex( i );
					if( oControl != null )
					{
						if( oControl.Name.Equals( sControlName ) == true )
						{
							oRetVal = oControl;
							break;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetVal );
		}


		//Draw the form!
		public virtual void Render( DSMenus oMenus )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.Render";
			Vector2 vGap = new Vector2( 1,1 );
			Vector2 vStart = new Vector2( 0,0 );
			DSBaseControl oLoopBaseCtrl = null;

			try
			{
				if( m_bHaveInitedMenu == false )
				{
					m_bHaveInitedMenu = true;
					Initialize( oMenus );					
				}

/*
				//11/16/2004 Chris Hill  Changed over to a drawn menu for speed reasons.
				m_oDSGraphicsWrapper.Render2DRect( this.Pos,this.Pos + this.Size,System.Drawing.Color.Black ); 
				m_oDSGraphicsWrapper.Render2DRect( this.Pos,this.Pos + this.Size,System.Drawing.Color.Gray ); 
				m_oDSGraphicsWrapper.Render2DRect( this.Pos,this.Pos + this.Size - vGap,System.Drawing.Color.White ); 
				m_oDSGraphicsWrapper.Render2DRect( this.Pos + vGap,this.Pos + this.Size - vGap,System.Drawing.Color.DarkGray ); 
				m_oDSGraphicsWrapper.Render2DRect( this.Pos + vGap,this.Pos + this.Size - vGap - vGap,System.Drawing.Color.LightGray ); 

				vGap.Multiply( 3 );
				vStart = this.Pos + vGap;
				m_oDSGraphicsWrapper.Render2DRect(	vStart,
					vStart + new Vector2( this.Size.X - vGap.X * 2,vGap.Y*5 ),
					System.Drawing.Color.DarkBlue ); 

				//Draw the form label
				this.DSGraphicsWrapper.RenderText( vStart.X,vStart.Y,System.Drawing.Color.White,m_sText );

*/
				//12/22/2004 Chris Hill  If we use an enumeration we can't add to the list.
				//Now render all our controls
				for( int i=0 ; i<m_oControls.Count ; i++ )
					//foreach( DSBaseControl oLoopBaseCtrl in m_oControls.GetValueList() )
				{
					oLoopBaseCtrl = (DSBaseControl)m_oControls.GetByIndex( i );
					oLoopBaseCtrl.Render( oMenus,this );

					//12/23/2004 Chris Hill  Their is now an init call that happens in the base
					//object render call.  But that means each derived control must call the base
					//render.  To make sure that happens i'm going to throw an error her if ie doesn't.
					if( oLoopBaseCtrl.HaveInitedMenus == false )
					{
						new System.Exception( "The control <" + oLoopBaseCtrl.Name + "> did not call the base control's render method." );
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public string GetCurrentCursorTextureKey( Vector2 vMousePosInMenuSpace )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.GetCurrentCursorTextureKey";
			DSBaseControl oControlMouseOver = null;
			Vector2 vMousePosInControlSpace;
			string sRetVal = "";

			try
			{
				oControlMouseOver = GetControlAt( vMousePosInMenuSpace );

				if( oControlMouseOver != null )
				{
					vMousePosInControlSpace = vMousePosInMenuSpace - oControlMouseOver.Pos;
					sRetVal = oControlMouseOver.GetCurrentCursorTextureKey( vMousePosInControlSpace );
				}
				else
				{
					sRetVal = m_sMouseCursorTextureKey;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sRetVal );
		}

		public virtual void FrameMove( DSMenus oMenus,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.FrameMove";
			Vector2 vGap = new Vector2( 1,1 );
			Vector2 vStart = new Vector2( 0,0 );
			DSBaseControl oLoopBaseCtrl = null;

			try
			{
				if( m_bHaveInitedMenu == false )
				{
					m_bHaveInitedMenu = true;
					Initialize( oMenus );					
				}

				//12/22/2004 Chris Hill  If we use an enumeration we can't add to the list.
				//Now render all our controls
				for( int i=0 ; i<m_oControls.Count ; i++ )
					//foreach( DSBaseControl oLoopBaseCtrl in m_oControls.GetValueList() )
				{
					oLoopBaseCtrl = (DSBaseControl)m_oControls.GetByIndex( i );
					oLoopBaseCtrl.FrameMove( oMenus,this,fElapsedTime,fAppTime );

					//12/23/2004 Chris Hill  Their is now an init call that happens in the base
					//object render call.  But that means each derived control must call the base
					//render.  To make sure that happens i'm going to throw an error her if ie doesn't.
					if( oLoopBaseCtrl.HaveInitedMenus == false )
					{
						new System.Exception( "The control <" + oLoopBaseCtrl.Name + "> did not call the base control's render method." );
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		//02/18/2005 Chris Hill  Usefull for initializing things.
		public virtual void Initialize( DSMenus oMenus ){}


		//This is the mouse events that users can override.  It would be unwise for a user to override these calls and
		//then not call the base class.  Some things like focus and dragging would cease to work.
		public virtual void MouseDown( Vector2 vMousePosInMenuSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.MouseDown";
			Vector2 vMousePosInControlSpace;

			try
			{
				m_oControlMouseDownOn = GetControlAt( vMousePosInMenuSpace );

				if( m_oControlMouseDownOn == null )
				{
					m_bBeingDragged = true;
					m_vMenuDraggingPoint = vMousePosInMenuSpace;
					m_oControlWithFocus = null;
				}
				else
				{
					m_oControlWithFocus = m_oControlMouseDownOn;
					vMousePosInControlSpace = vMousePosInMenuSpace - m_oControlMouseDownOn.Pos;
					m_oControlMouseDownOn.MouseDown( vMousePosInControlSpace,nButton );
				}

				if( m_odDelegate_MouseDown != null )
				{
					m_odDelegate_MouseDown( vMousePosInMenuSpace,nButton );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseUp( Vector2 vMousePosInMenuSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.MouseUp";
			Vector2 vMousePosInControlSpace;
			bool[] baButtons = null;

			try
			{
				if( m_bBeingDragged == true )
				{
					m_bBeingDragged = false;
					//12/19/2004 Chris Hill  The position changes as we drag it so we don't need
					//to set it.  Which is good because all we know is the location in memory space.
					//this.Pos = vMousePosInMenuSpace - m_vMenuDraggingPoint;
				}
				else if( m_oControlMouseDownOn != null )
				{
					vMousePosInControlSpace = vMousePosInMenuSpace - m_oControlMouseDownOn.Pos;
					m_oControlMouseDownOn.MouseUp( vMousePosInControlSpace,nButton );

					//12/18/2004 Chris Hill  A click up event is also a click event
					baButtons = new bool[ 3 ];
					baButtons[ nButton ] = true;
					MouseClicked( vMousePosInMenuSpace,baButtons );
				}

				if( m_odDelegate_MouseUp != null )
				{
					m_odDelegate_MouseUp( vMousePosInMenuSpace,nButton );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.MouseMoved";
			DSBaseControl oControl = null;
			Vector2 vMousePosInControlSpace;

			try
			{
				if( m_bBeingDragged == true )
				{
					Pos += ( vMousePosInMenuSpace - m_vMenuDraggingPoint );
				}
				else
				{
					oControl = GetControlAt( vMousePosInMenuSpace );

					if( oControl != null )
					{
						vMousePosInControlSpace = vMousePosInMenuSpace - oControl.Pos;
						oControl.MouseMoved( vMousePosInControlSpace,baButtons );

						//Chris 9c
						if( oControl != m_oControlMouseOver )
						{
							if( m_oControlMouseOver != null )
							{
								m_oControlMouseOver.OnMouseExit();
								m_oControlMouseOver = null;
							}
							m_oControlMouseOver = oControl;
							m_oControlMouseOver.OnMouseEnter();
						}
					}
					else if( m_oControlMouseOver != null )
					{
						m_oControlMouseOver.OnMouseExit();
						m_oControlMouseOver = null;
					}
				}

				if( m_odDelegate_MouseMoved != null )
				{
					m_odDelegate_MouseMoved( vMousePosInMenuSpace,baButtons );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseClicked( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.MouseUp";
			Vector2 vMousePosInControlSpace;
			DSBaseControl oControlUpOn = null;

			try
			{
				oControlUpOn = GetControlAt( vMousePosInMenuSpace );

				if( oControlUpOn != null )
				{
					if( m_oControlMouseDownOn.Name.Equals( oControlUpOn.Name ) == true )
					{
						vMousePosInControlSpace = vMousePosInMenuSpace - m_oControlMouseDownOn.Pos;
						m_oControlMouseDownOn.MouseClicked( vMousePosInControlSpace,baButtons );
					}
				}

				if( m_odDelegate_MouseClicked != null )
				{
					m_odDelegate_MouseClicked( vMousePosInMenuSpace,baButtons );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.KeyboardKeyDown";

			try
			{
				if( m_oControlWithFocus != null )
				{
					m_oControlWithFocus.KeyboardKeyDown( oKey,oState );
				}

				if( m_odDelegate_KeyDown != null )
				{
					m_odDelegate_KeyDown( oKey,oState );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.KeyboardKeyUp";

			try
			{
				if( m_oControlWithFocus != null )
				{
					m_oControlWithFocus.KeyboardKeyUp( oKey,oState );
				}

				if( m_odDelegate_KeyUp != null )
				{
					m_odDelegate_KeyUp( oKey,oState );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//These methods register the callback function the user of the class wishes.  
		public void RegisterDelegate_MouseDown( DelegateMouseDown odMouseDown )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseDown";

			try
			{
				m_odDelegate_MouseDown += odMouseDown;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_MouseUp( DelegateMouseUp odMouseUp )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseUp";

			try
			{
				m_odDelegate_MouseUp += odMouseUp;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_MouseMoved( DelegateMouseMoved odMouseMoved )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseMoved";

			try
			{
				m_odDelegate_MouseMoved += odMouseMoved;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public void RegisterDelegate_MouseClicked( DelegateMouseClicked odMouseClicked )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseClicked";

			try
			{
				m_odDelegate_MouseClicked += odMouseClicked;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_KeyDown( DelegateKeyDown odKeyDown )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_KeyDown";

			try
			{
				m_odDelegate_KeyDown += odKeyDown;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_KeyUp( DelegateKeyUp odKeyUp )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_KeyUp";

			try
			{
				m_odDelegate_KeyUp += odKeyUp;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public virtual void Dispose()
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.Dispose";

			try
			{
				m_oControls = null;

				m_oControlMouseDownOn = null;

				m_oControlWithFocus = null;

				m_odDelegate_MouseDown		= null;
				m_odDelegate_MouseUp		= null;
				m_odDelegate_MouseMoved		= null;
				m_odDelegate_MouseClicked	= null;
				m_odDelegate_KeyDown		= null;
				m_odDelegate_KeyUp			= null;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}





		public void DrawText(string text,  System.Drawing.Rectangle rect, bool shadow,BlendColor oFontColor,DrawTextFormat textFormat )
		{
			// No need to draw fully transparant layers
			//if (element.FontColor.Current.Alpha == 0)
			 if (oFontColor.Current.Alpha == 0)
				return; // Nothing to do

			System.Drawing.Rectangle screenRect = rect;
			screenRect.Offset((int)m_vPos.X, (int)m_vPos.Y);

			// If caption is enabled, offset the Y position by its height.
//			if (hasCaption)
//				screenRect.Offset(0, captionHeight);

			// Set the identity transform
//			DialogResourceManager.GetGlobalInstance().Sprite.Transform = Matrix.Identity;

			// Get the font node here
			//FontNode fNode = GetFont(element.FontIndex);
			if (shadow)
			{
				// Render the text shadowed
				System.Drawing.Rectangle shadowRect = screenRect;
				shadowRect.Offset(1, 1);
				//fNode.Font.DrawText(DialogResourceManager.GetGlobalInstance().Sprite, text,
				//	shadowRect, element.textFormat, unchecked((int)0xff000000));
				//m_oDSGraphicsWrapper.FontArial.DrawText( null,text,shadowRect, element.textFormat, unchecked((int)0xff000000) );
				m_oDSGraphicsWrapper.FontArial.DrawText( null,text,shadowRect, textFormat, unchecked((int)0xff000000) );
			}

			//fNode.Font.DrawText(DialogResourceManager.GetGlobalInstance().Sprite, text,
			//	screenRect, element.textFormat, element.FontColor.Current.ToArgb());
			m_oDSGraphicsWrapper.FontArial.DrawText( null,text,screenRect, textFormat, oFontColor.Current.ToArgb() );
			//m_oDSGraphicsWrapper.FontArial.DrawText( null,text,screenRect, element.textFormat, element.FontColor.Current.ToArgb() );
		}
		/// <summary>Draw a sprite</summary>
		public void DrawSprite( System.Drawing.Rectangle rect,BlendColor oCurrentColor,System.Drawing.Rectangle oRect )
		{
			// No need to draw fully transparant layers
			//if (element.TextureColor.Current.Alpha == 0)
			if (oCurrentColor.Current.Alpha == 0)				
				return; // Nothing to do

			System.Drawing.Rectangle texRect = oRect;//element.textureRect;
			System.Drawing.Rectangle screenRect = rect;
			screenRect.Offset( (int)m_vPos.X,(int)m_vPos.Y );

			// If caption is enabled, offset the Y position by its height.
//			if (hasCaption)
//				screenRect.Offset(0, captionHeight);

			// Get the texture
			//TextureNode tNode = GetTexture(element.TextureIndex);
			float scaleX = (float)screenRect.Width / (float)texRect.Width;
			float scaleY = (float)screenRect.Height / (float)texRect.Height;

			// Set the scaling transform
			//DialogResourceManager.GetGlobalInstance().Sprite.Transform = Matrix.Scaling(scaleX, scaleY, 1.0f);
			m_oDSGraphicsWrapper.SpriteEngine.Transform = Matrix.Scaling(scaleX, scaleY, 1.0f);
            
			// Calculate the position
			Vector3 pos = new Vector3(screenRect.Left, screenRect.Top, 0.0f);
			pos.X /= scaleX;
			pos.Y /= scaleY;


			DarkStrideToolbox.LoadedTexture oTexture = 
						DSResourceManager.GetGlobalInstance().GetLoadedTexture( "0" );//element.TextureKey );


			// Finally draw the sprite
			m_oDSGraphicsWrapper.SpriteEngine.Begin(Microsoft.DirectX.Direct3D.SpriteFlags.AlphaBlend );
			m_oDSGraphicsWrapper.SpriteEngine.Draw( oTexture.oTexture,texRect, 
										new Vector3(), pos, 
										oCurrentColor.Current.ToArgb()); 
										//element.TextureColor.Current.ToArgb()); 
			m_oDSGraphicsWrapper.SpriteEngine.End();
			//DialogResourceManager.GetGlobalInstance().Sprite.Draw(tNode.Texture, texRect, new Vector3(), pos, element.TextureColor.Current.ToArgb()); 
		}
		/// <summary>Draw's some text</summary>
		public void DrawText(string text,  System.Drawing.Rectangle rect,BlendColor oFontColor,DrawTextFormat textFormat) { this.DrawText(text,  rect, false,oFontColor,textFormat ); }
		/// <summary>Draw a rectangle</summary>
		public void DrawRectangle(System.Drawing.Rectangle rect, ColorValue color)
		{
			// Offset the rectangle
			rect.Offset((int)m_vPos.X, (int)m_vPos.Y);

			// If caption is enabled, offset the Y position by its height
			//if (hasCaption)
			//	rect.Offset(0, captionHeight);

			// Get the integer value of the color
			int realColor = color.ToArgb();
			// Create some vertices
			CustomVertex.TransformedColoredTextured[] verts = {
																  new CustomVertex.TransformedColoredTextured((float)rect.Left - 0.5f, (float)rect.Top -0.5f, 0.5f, 1.0f, realColor, 0, 0),
																  new CustomVertex.TransformedColoredTextured((float)rect.Right - 0.5f, (float)rect.Top -0.5f, 0.5f, 1.0f, realColor, 0, 0),
																  new CustomVertex.TransformedColoredTextured((float)rect.Right - 0.5f, (float)rect.Bottom -0.5f, 0.5f, 1.0f, realColor, 0, 0),
																  new CustomVertex.TransformedColoredTextured((float)rect.Left - 0.5f, (float)rect.Bottom -0.5f, 0.5f, 1.0f, realColor, 0, 0),
			};

			// Get the device
			//Device device = SampleFramework.Device;

			// Since we're doing our own drawing here, we need to flush the sprites
			m_oDSGraphicsWrapper.SpriteEngine.Flush();
			//DialogResourceManager.GetGlobalInstance().Sprite.Flush();
			// Preserve the devices current vertex declaration
			using (VertexDeclaration decl = m_oDSGraphicsWrapper.Direct3DDevice.VertexDeclaration)
			{
				// Set the vertex format
				m_oDSGraphicsWrapper.Direct3DDevice.VertexFormat = CustomVertex.TransformedColoredTextured.Format;

				// Set some texture states
				m_oDSGraphicsWrapper.Direct3DDevice.TextureState[0].ColorOperation = TextureOperation.SelectArg2;
				m_oDSGraphicsWrapper.Direct3DDevice.TextureState[0].AlphaOperation = TextureOperation.SelectArg2;

				// Draw the rectangle
				m_oDSGraphicsWrapper.Direct3DDevice.DrawUserPrimitives(PrimitiveType.TriangleFan, 2, verts);

				// Reset some texture states
				m_oDSGraphicsWrapper.Direct3DDevice.TextureState[0].ColorOperation = TextureOperation.Modulate;
				m_oDSGraphicsWrapper.Direct3DDevice.TextureState[0].AlphaOperation = TextureOperation.Modulate;

				// Restore the vertex declaration
				m_oDSGraphicsWrapper.Direct3DDevice.VertexDeclaration = decl;
			}
		}

		/// <summary>
		/// Request that this control has focus
		/// </summary>
		public static void RequestFocus(DSBaseControl control)
		{

			if (!control.CanHaveFocus)
				return; // Can't have focus

			if (controlFocus != null)
				controlFocus.OnFocusOut();

			// Set the control focus now
			control.OnFocusIn();
			controlFocus = control;
		}
		/// <summary>
		/// Clears focus of the dialog
		/// </summary>
		public static void ClearFocus()
		{
			if (controlFocus != null)
			{
				controlFocus.OnFocusOut();
				controlFocus = null;
			}
		}

		/*public void SetDefaultElement(ControlType ctype, uint index, Element e)
		{
			// If this element already exists, just update it
			for (int i = 0; i < defaultElementList.Count; i++)
			{
				ElementHolder holder = (ElementHolder)defaultElementList[i];
				if ( (holder.ControlType == ctype) &&
					(holder.ElementIndex == index) )
				{
					// Found it, update it
					holder.Element = e.Clone();
					defaultElementList[i] = holder;
					return;
				}
			}

			// Couldn't find it, add a new entry
			ElementHolder newEntry = new ElementHolder();
			newEntry.ControlType = ctype;
			newEntry.ElementIndex = index;
			newEntry.Element = e.Clone();

			// Add it now
			defaultElementList.Add(newEntry);
		}*/
	/*	private void InitializeDefaultElements()
		{
			//SetTexture(0, "UI\\DXUTControls.dds");
			//SetFont(0, "Arial", 14, FontWeight.Normal);
			//m_oDSGraphicsWrapper.LoadTexture( "0","UI\\DXUTControls.dds" );
			

			//-------------------------------------
			// Element for the caption
			//-------------------------------------
			captionElement = new Element();
			captionElement.SetFont(0, WhiteColorValue, DrawTextFormat.Left | DrawTextFormat.VerticalCenter);
			captionElement.SetTexture(0, new System.Drawing.Rectangle(17,269,224,18));
			captionElement.TextureColor.States[(int)ControlState.Normal] = WhiteColorValue;
			captionElement.FontColor.States[(int)ControlState.Normal] = WhiteColorValue;
			// Pre-blend as we don't need to transition the state
			captionElement.TextureColor.Blend(ControlState.Normal, 10.0f);
			captionElement.FontColor.Blend(ControlState.Normal, 10.0f);

			Element e = new Element();

			//-------------------------------------
			// StaticText
			//-------------------------------------
			e.SetFont(0);
			e.FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.75f, 0.75f, 0.75f, 0.75f);
			// Assign the element
			SetDefaultElement(ControlType.StaticText, DSLabel.TextElement, e);

			//-------------------------------------
			// Button - Button
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(0,0,136,54));
			//e.SetFont(0);
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
			e.TextureColor.States[(int)ControlState.Pressed] = new ColorValue(1.0f, 1.0f, 1.0f, 0.85f);
			e.FontColor.States[(int)ControlState.MouseOver] = BlackColorValue;
			// Assign the element
			SetDefaultElement(ControlType.Button, DSButton.ButtonLayer, e);

			//-------------------------------------
			// Button - Fill Layer
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(136,0,136,54), TransparentWhite);
			e.TextureColor.States[(int)ControlState.MouseOver] = new ColorValue(1.0f, 1.0f, 1.0f, 0.6f);
			e.TextureColor.States[(int)ControlState.Pressed] = new ColorValue(0,0,0, 0.25f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.05f);
			// Assign the element
			SetDefaultElement(ControlType.Button, DSButton.FillLayer, e);


			//-------------------------------------
			// CheckBox - Box
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(0,54,27,27));
			e.SetFont(0, WhiteColorValue, DrawTextFormat.Left | DrawTextFormat.VerticalCenter);
			e.FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.8f);
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.8f);
			e.TextureColor.States[(int)ControlState.Pressed] = WhiteColorValue;
			// Assign the element
			SetDefaultElement(ControlType.CheckBox, Checkbox.BoxLayer, e);

			//-------------------------------------
			// CheckBox - Check
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(27,54,27,27));
			// Assign the element
			SetDefaultElement(ControlType.CheckBox, Checkbox.CheckLayer, e);

			//-------------------------------------
			// RadioButton - Box
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(54,54,27,27));
			e.SetFont(0, WhiteColorValue, DrawTextFormat.Left | DrawTextFormat.VerticalCenter);
			e.FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.8f);
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.8f);
			e.TextureColor.States[(int)ControlState.Pressed] = WhiteColorValue;
			// Assign the element
			SetDefaultElement(ControlType.RadioButton, RadioButton.BoxLayer, e);

			//-------------------------------------
			// RadioButton - Check
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(81,54,27,27));
			// Assign the element
			SetDefaultElement(ControlType.RadioButton, RadioButton.CheckLayer, e);

			//-------------------------------------
			// ComboBox - Main
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(7,81, 240, 42));
			e.SetFont(0);
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(0.8f, 0.8f, 0.8f, 0.55f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(0.95f, 0.95f, 0.95f, 0.6f);
			e.TextureColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.25f);
			e.FontColor.States[(int)ControlState.MouseOver] = new ColorValue(0,0,0,1.0f);
			e.FontColor.States[(int)ControlState.Pressed] = new ColorValue(0,0,0,1.0f);
			e.FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.8f);
			// Assign the element
			SetDefaultElement(ControlType.ComboBox, ComboBox.MainLayer, e);

			//-------------------------------------
			// ComboBox - Button
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(272,0, 53, 49));
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
			e.TextureColor.States[(int)ControlState.Pressed] = new ColorValue(0.55f, 0.55f, 0.55f, 1.0f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.75f);
			e.TextureColor.States[(int)ControlState.Disabled] = new ColorValue(1.0f, 1.0f, 1.0f, 0.25f);
			// Assign the element
			SetDefaultElement(ControlType.ComboBox, ComboBox.ComboButtonLayer, e);

			//-------------------------------------
			// ComboBox - Dropdown
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(7,123,234,142));
			e.SetFont(0, BlackColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
			// Assign the element
			SetDefaultElement(ControlType.ComboBox, ComboBox.DropdownLayer, e);

			//-------------------------------------
			// ComboBox - Selection
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(7,266,234,23));
			e.SetFont(0, WhiteColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
			// Assign the element
			SetDefaultElement(ControlType.ComboBox, ComboBox.SelectionLayer, e);

			//-------------------------------------
			// Slider - Track
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(1,290,279,41));
			e.TextureColor.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
			e.TextureColor.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.75f);
			e.TextureColor.States[(int)ControlState.Disabled] = new ColorValue(1.0f, 1.0f, 1.0f, 0.25f);
			// Assign the element
			SetDefaultElement(ControlType.Slider, Slider.TrackLayer, e);

			//-------------------------------------
			// Slider - Button
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(248,55,41,41));
			// Assign the element
			SetDefaultElement(ControlType.Slider, Slider.ButtonLayer, e);

			//-------------------------------------
			// Scrollbar - Track
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(243,144,22,11));
			// Assign the element
			SetDefaultElement(ControlType.Scrollbar, ScrollBar.TrackLayer, e);

			//-------------------------------------
			// Scrollbar - Up Arrow
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(243,124,22,20));
			e.TextureColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 1.0f);
			// Assign the element
			SetDefaultElement(ControlType.Scrollbar, ScrollBar.UpButtonLayer, e);

			//-------------------------------------
			// Scrollbar - Down Arrow
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(243,155,22,21));
			e.TextureColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 1.0f);
			// Assign the element
			SetDefaultElement(ControlType.Scrollbar, ScrollBar.DownButtonLayer, e);

			//-------------------------------------
			// Scrollbar - Button
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(266,123,20,44));
			// Assign the element
			SetDefaultElement(ControlType.Scrollbar, ScrollBar.ThumbLayer, e);


			//-------------------------------------
			// EditBox
			//-------------------------------------
			// Element assignment:
			//   0 - text area
			//   1 - top left border
			//   2 - top border
			//   3 - top right border
			//   4 - left border
			//   5 - right border
			//   6 - lower left border
			//   7 - lower border
			//   8 - lower right border
			e.SetFont(0, BlackColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
            
			// Assign the styles
			e.SetTexture("0",0, new System.Drawing.Rectangle(14,90,227,23));
			SetDefaultElement(ControlType.EditBox, EditBox.TextLayer, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(8,82,6,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopLeftBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(14,82,227,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(241,82,5,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopRightBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(8,90,6,23));
			SetDefaultElement(ControlType.EditBox, EditBox.LeftBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(241,90,5,23));
			SetDefaultElement(ControlType.EditBox, EditBox.RightBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(8,113,6,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerLeftBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(14,113,227,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerBorder, e);
			e.SetTexture("0",0, new System.Drawing.Rectangle(241,113,5,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerRightBorder, e);


			//-------------------------------------
			// Listbox - Main
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(13,124,228,141));
			e.SetFont(0, BlackColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
			// Assign the element
			SetDefaultElement(ControlType.ListBox, ListBox.MainLayer, e);

			//-------------------------------------
			// Listbox - Selection
			//-------------------------------------
			e.SetTexture("0",0, new System.Drawing.Rectangle(17,269,224,18));
			e.SetFont(0, WhiteColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
			// Assign the element
			SetDefaultElement(ControlType.ListBox, ListBox.SelectionLayer, e);
		}*/

		/// <summary>Clears the radio button group</summary>
		public void ClearRadioButtonGroup(int groupIndex)
		{
			DSBaseControl oLoopBaseCtrl = null;
			DSRadioButton oRadioButton = new DSRadioButton( null,null );

			// Find all radio buttons with the given group number
			for( int i=0 ; i<m_oControls.Count ; i++ )
			{
				oLoopBaseCtrl = (DSBaseControl)m_oControls.GetByIndex( i );
				if( oLoopBaseCtrl.GetType() == oRadioButton.GetType() )
				{
					oRadioButton = (DSRadioButton)oLoopBaseCtrl;
					if( oRadioButton.ButtonGroup == groupIndex )
					{
						oRadioButton.SetChecked( false,false );
					}
				}
			}
		}

		/// <summary>Clears the combo box of all items</summary>
		public void ClearComboBox(int id)
		{
			//Chris
			//ComboBox comboBox = GetComboBox(id);
			//if (comboBox == null)
			//	return;

			//comboBox.Clear();
		}



		#region Properties
		public Vector2 Size
		{
			get
			{
				return( m_vSize );
			}
			set
			{
				m_vSize = value;
			}
		}
		public Vector2 Pos
		{
			get
			{
				return( m_vPos );
			}
			set
			{
				m_vPos = value;
			}
		}
		public string Name
		{
			get
			{
				return( m_sName );
			}
			set
			{
				m_sName = value;
			}
		}
		public string TextureKey
		{
			get
			{
				return( m_sTextureKey );
			}
			set
			{
				m_sTextureKey = value;
			}
		}
		public bool IsModal
		{
			get
			{
				return( m_bIsModal );
			}
			set
			{
				m_bIsModal = value;
			}
		}
		public bool CanBeDragged
		{
			get
			{
				return( m_bCanBeDragged );
			}
			set
			{
				m_bCanBeDragged = value;
			}
		}
		public string MouseCursorTextureKey
		{
			get
			{
				return( m_sMouseCursorTextureKey );
			}
			set
			{
				m_sMouseCursorTextureKey = value;
			}
		}
		public DSBaseControl ControlWithFocus
		{
			get
			{
				return( m_oControlWithFocus );
			}
		}
		public DSGraphicsWrapper DSGraphicsWrapper
		{
			get
			{
				return( m_oDSGraphicsWrapper );
			}
			set
			{
				m_oDSGraphicsWrapper = value;
			}
		}
		public SortedList Controls
		{
			get
			{
				return( m_oControls );
			}
			set
			{
				m_oControls = value;
			}
		}
		public string Text
		{
			get
			{
				return( m_sText );
			}
			set
			{
				m_sText = value;
			}
		}
		#endregion
	};
	#endregion

	#region Control Classes
	#region Old Controls
	/*
	public class DSTextControl			: DSBaseControl
	{
		#region Properties
		private string m_sText = "";
		private float m_fLastUpdateTime = 0;
		private bool m_bCurrentlyRenderingCursor = false;
		private int m_nCursorLocation = 0;
		#endregion


		public DSTextControl( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.DSTextControl";

			try
			{
				base.MouseCursorTextureKey = "System_MouseCursor_IBar";				
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.Render";
			string sTempText = "";
			float nTextX = 0;
			float nTextY = 0;
			Vector2 vGap = new Vector2( 1,1 );

			try
			{
				base.Render( oMenus,oMenu );

				//12/11/2004 Chris Hill  Adjust the size of the control to fix the text.
				this.Size = new Vector2( ( GetNumCharsWide() * this.DSGraphicsWrapper.FontSize.X ) + 8,
					( GetNumCharsHigh() * this.DSGraphicsWrapper.FontSize.Y ) + 3 );

				//Render the basic box
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos,this.Pos+oMenu.Pos + this.Size,System.Drawing.Color.White ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos,this.Pos+oMenu.Pos + this.Size - vGap,System.Drawing.Color.DarkGray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap,this.Pos+oMenu.Pos + this.Size - vGap,System.Drawing.Color.LightGray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap,this.Pos+oMenu.Pos + this.Size - vGap - vGap,System.Drawing.Color.Gray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap + vGap,this.Pos+oMenu.Pos + this.Size - vGap - vGap,System.Drawing.Color.White ); 

				//Update our cursor state
				UpdateCursorState( oMenu );

				//Draw our cursor onto the field
				sTempText = GetTextToShow( oMenu );

				//Draw the text
				nTextX = this.Pos.X + oMenu.Pos.X + 4.0f;
				nTextY = this.Pos.Y + oMenu.Pos.Y + 1.5f;//this.Size.Y / 2.0f - (float)(this.DSGraphicsWrapper.FontSize.Y) / 2.0f;
				this.DSGraphicsWrapper.RenderText( nTextX,nTextY,this.FontColor,sTempText );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		private void UpdateCursorState( DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.UpdateCursorState";
			float fNewTime = 0;

			try
			{
				//Are we the focus??
				if( oMenu.ControlWithFocus != null )
				{
					if( oMenu.ControlWithFocus.Name.Equals( this.Name ) == true )
					{
						fNewTime = DXUtil.Timer( DirectXTimer.GetApplicationTime );
						if( fNewTime - m_fLastUpdateTime > 0.5f )
						{
							m_bCurrentlyRenderingCursor = !m_bCurrentlyRenderingCursor;
							m_fLastUpdateTime = fNewTime;
						}
					}
				}
				else if( m_bCurrentlyRenderingCursor == true )
				{
					m_bCurrentlyRenderingCursor = false;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		//12/12/2004 Chris Hill  This function gets the string we can display so that the
		//cursor shows up along with only the text that should be visible.
		public string GetTextToShow( DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.GetTextToShow";
			bool bIAmTheFocus = false;
			string sTempText = "";
			string[] saLines = null;
			string sCursor = "_";
			int nStartPos = 0;			
			int nStopPos = 0;
			int nDistInOnLine = 0;
			int nLineTotal = 0;
			int nLineOn = 0;

			try
			{
				//Are we the focus??
				if( oMenu.ControlWithFocus != null )
				{
					bIAmTheFocus = oMenu.ControlWithFocus.Name.Equals( this.Name );
				}
				//Chris  For now we just hard code the location.  Later we'll allow it to move.
				m_nCursorLocation = m_sText.Length;

				//Draw our cursor onto the field
				if( bIAmTheFocus == false )
				{
					sCursor = "";
				}
				else
				{
					if( m_bCurrentlyRenderingCursor == true )
					{
						sCursor = "|";
					}
				}
				sTempText = m_sText.Substring( 0,m_nCursorLocation ) + 
					sCursor + 
					m_sText.Substring( m_nCursorLocation );


				saLines = DSMisc.Split( sTempText,"\n" );

				//Figure out what line were on and how far into that line we are
				while( nLineOn < saLines.Length )
				{
					if( nLineTotal + saLines[ nLineOn ].Length >= m_nCursorLocation )
					{
						nDistInOnLine = m_nCursorLocation - nLineTotal;
						break;
					}

					nLineTotal += saLines[ nLineOn ].Length + 1;
					nLineOn++;
				}
				if( nLineOn >= saLines.Length )
				{
					nLineOn--;
				}

				//In this scenario their is text further to the left of the line... so we show half in half
				if( nDistInOnLine < saLines[ nLineOn ].Length - 1 )
				{
					nStartPos = DSMisc.Max( 0,nDistInOnLine - GetNumCharsWide() / 2 );
					nStopPos = nStartPos + GetNumCharsWide();
				}
					//In this scenario their is more text than their is line but nothing to the right of the cursor
				else if( nDistInOnLine >= saLines[ nLineOn ].Length - 1 && nDistInOnLine + 1 > GetNumCharsWide() )
				{
					nStartPos = nDistInOnLine + 1 - GetNumCharsWide();
					nStopPos = nDistInOnLine + 1;
				}
					//Otherwise we can show the entire line
				else
				{
					nStartPos = 0;
					nStopPos = GetNumCharsWide();
				}

				//No go through and reassemble the text we will display into one string
				sTempText = "";
				for( int i=DSMisc.Max( 0,nLineOn - GetNumCharsHigh() + 1 ) ; i<=nLineOn ; i++ )
				{
					if( saLines[ i ].Length > nStopPos )
					{	
						sTempText += saLines[ i ].Substring( nStartPos,nStopPos - nStartPos );
					}
					else if( nStartPos > saLines[ i ].Length )
					{
						sTempText += "\n";
					}
					else
					{
						sTempText += saLines[ i ].Substring( nStartPos );
					}
					
					if( i + 1 <= nLineOn )
					{
						sTempText += "\n";
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sTempText );
		}


		public int GetNumCharsWide()
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.GetNumCharsWide";
			int nNumChars = 0;

			try
			{
				nNumChars = (int)DSMisc.Max( 
					1,
					(long)( ( this.Size.X - 8 ) / this.DSGraphicsWrapper.FontSize.X ) 
					);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nNumChars );
		}
		public int GetNumCharsHigh()
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.GetNumCharsHigh";
			int nNumChars = 0;

			try
			{
				nNumChars = (int)DSMisc.Max( 
					1,
					(long)( ( this.Size.Y - 3 )/ this.DSGraphicsWrapper.FontSize.Y ) 
					);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nNumChars );
		}


		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.KeyboardKeyDown";
			string sTemp = "";

			try
			{
				base.KeyboardKeyUp( oKey,oState );
				sTemp = DSMisc.KeyToChar( oKey,oState );

				//Chris
				//if okey = key.Decimal then its actually delete

				//Backspace
				if( oKey == Key.BackSpace )
				{
					if( m_sText.Length > 0 )
					{
						m_sText = m_sText.Substring( 0,m_sText.Length - 1 );
					}
				}
				else 
				{
					m_sText += sTemp;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		#region Properties
		public string Text
		{
			get
			{
				return( m_sText );
			}
			set
			{
				m_sText = value;
			}
		}

		#endregion
	};
	public class DSListBoxControl		: DSBaseControl
	{
		#region Properties
		private bool m_bSorted = false;
		private ArrayList m_oListItems = new ArrayList();
		private ArrayList m_oListKeys = new ArrayList();
		private string m_sKeyOfFirstItemVisible = "";
		private string m_sKeyOfSelectedItem = "";
		private DSSlideControl m_oSlideBar = null;
		private long m_nNextFreeKey = 0;
		#endregion


		public DSListBoxControl()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.DSListBoxControl";

			try
			{
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.Render";
			string sTempText = "";
			bool bIAmTheFocus = false;
			int nCharsWide = GetNumCharsWide();
			int nCharsHigh = GetNumCharsHigh();
			int nIndexOfSelectedItem = 0;
			int nIndexOfFirstItem = 0;
			ArrayList oSortedListItems = new ArrayList();
			ArrayList oSortedListKeys = new ArrayList();
			float nTextX = 0;
			float nTextY = 0;
			Vector2 vGap = new Vector2( 1,1 );
			Vector2 vStart;
			Vector2 vStop;

			try
			{
				base.Render( oMenus,oMenu );

				//Are we the focus??
				if( oMenu.ControlWithFocus != null )
				{
					bIAmTheFocus = oMenu.ControlWithFocus.Name.Equals( this.Name );
				}

				//Render the basic box
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos				,this.Pos+oMenu.Pos + this.Size				,System.Drawing.Color.White ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos				,this.Pos+oMenu.Pos + this.Size - vGap		,System.Drawing.Color.DarkGray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap		,this.Pos+oMenu.Pos + this.Size - vGap		,System.Drawing.Color.LightGray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap		,this.Pos+oMenu.Pos + this.Size - vGap * 2	,System.Drawing.Color.Gray ); 
				this.DSGraphicsWrapper.Render2DRect( this.Pos+oMenu.Pos + vGap * 2	,this.Pos+oMenu.Pos + this.Size - vGap * 2	,System.Drawing.Color.White ); 

				//Get the relivant data
				GetListOfItems( ref oSortedListKeys,ref oSortedListItems,ref nIndexOfFirstItem,ref nIndexOfSelectedItem );

				//Get the text thats visible on the screen
				for( int i=0 ; i<nCharsHigh && i<oSortedListItems.Count ; i++ )
				{
					if( ((string)oSortedListItems[ nIndexOfFirstItem + i ]).Length > nCharsWide )
					{
						sTempText += ((string)oSortedListItems[ nIndexOfFirstItem + i ]).Substring( 0,nCharsWide ) + "\n";
					}
					else
					{
						sTempText += ((string)oSortedListItems[ nIndexOfFirstItem + i ]) + "\n";						
					}
				}

				//Draw the text that isn't selected
				nTextX = this.Pos.X + oMenu.Pos.X + 4.0f;
				nTextY = this.Pos.Y + oMenu.Pos.Y + 1.5f;
				this.DSGraphicsWrapper.RenderText( nTextX,nTextY,this.FontColor,sTempText );
	
				//Is an item selected?  Is it visible now?
				if( nIndexOfSelectedItem != -1 && 
					nIndexOfSelectedItem >= nIndexOfFirstItem && nIndexOfSelectedItem <= nIndexOfFirstItem + nCharsHigh - 1 )
				{
					//Draw the selection box
					vStart = this.Pos + oMenu.Pos + vGap + vGap;
					vStop = this.Pos+oMenu.Pos + this.Size - vGap - vGap;
					//We have to calculate stop first because it references stop which will then change
					vStop = new Vector2(	vStop.X  - 1,
						vStart.Y - 1 + ( nIndexOfSelectedItem - nIndexOfFirstItem + 1 ) * base.DSGraphicsWrapper.FontSize.Y );
					vStart = new Vector2(	vStart.X + 1,
						vStart.Y + 1 + ( nIndexOfSelectedItem - nIndexOfFirstItem ) * base.DSGraphicsWrapper.FontSize.Y );
					this.DSGraphicsWrapper.Render2DRect( vStart,vStop,System.Drawing.Color.DarkBlue ); 

					//Get the text to display
					if( ((string)oSortedListItems[ nIndexOfSelectedItem ]).Length > nCharsWide )
					{
						sTempText = ((string)oSortedListItems[ nIndexOfSelectedItem ]).Substring( 0,nCharsWide );
					}
					else
					{
						sTempText = (string)oSortedListItems[ nIndexOfSelectedItem ];
					}

					//Draw the text that is selected
					nTextX = this.Pos.X + oMenu.Pos.X + 4.0f;
					nTextY = this.Pos.Y + oMenu.Pos.Y + 1.5f + ( nIndexOfSelectedItem - nIndexOfFirstItem ) * base.DSGraphicsWrapper.FontSize.Y;
					this.DSGraphicsWrapper.RenderText( nTextX,nTextY,System.Drawing.Color.White,sTempText );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void InitializeWithMenu( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.InitializeWithMenu";
			long nSize = 0;

			try
			{
				//12/11/2004 Chris Hill  Adjust the size of the control to fix the text.
				this.Size = new Vector2( ( GetNumCharsWide() * this.DSGraphicsWrapper.FontSize.X ) + 8,
					( GetNumCharsHigh() * this.DSGraphicsWrapper.FontSize.Y ) + 3 );

				nSize = Convert.ToInt64( DSMisc.Min( base.Size.X,20.0f ) );

				m_oSlideBar = (DSSlideControl)oMenu.AddControl( new DSSlideControl(),base.Name + "SlideBar",
					new Vector2( this.Pos.X + this.Size.X - nSize,this.Pos.Y ),
					new Vector2( nSize,this.Size.Y ) );
				m_oSlideBar.RegisterDelegate_Change( new DSSlideControl.DelegateChange( this.sldListBox_Change ) );

				this.Size = new Vector2( this.Size.X - nSize,this.Size.Y );

				m_oSlideBar.Max = DSMisc.Max( m_oListItems.Count - GetNumCharsHigh(),0 );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public static void RenderButton( DSGraphicsWrapper oGraphicsWrapper,Vector2 vUpperLeft,Vector2 vLowerRight,
			int nGapSize,bool bHasFocus,bool bDepressed,bool bUseBlackBorderIfNeeded )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.RenderButton";
			Vector2 vGap = new Vector2( nGapSize,nGapSize );

			try
			{
				//Normal
				if( bHasFocus == false )
				{
					oGraphicsWrapper.Render2DRect( vUpperLeft				,vLowerRight				,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft				,vLowerRight - vGap			,System.Drawing.Color.LightGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap - vGap	,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Down
				else if( bDepressed == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
					
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Focus
				else if( bHasFocus == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
					
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap					,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap - vGap			,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap			,System.Drawing.Color.DarkGray );
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap - vGap	,System.Drawing.Color.LightGray );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		private void GetListOfItems( ref ArrayList oaKeys,ref ArrayList oaValues,ref int nIndexOfFirstItem,ref int nIndexOfSelectedItem )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetListOfItems";
			bool[] oKeySorted = new bool[ m_oListItems.Count ];
			string sCurrentLowKey = "";
			string sCurrentLowValue = "";

			try
			{
				//Create our return data objects
				oaValues = new ArrayList();
				oaKeys = new ArrayList();
				//12/19/2004 Chris Hill  Their is always a first item but their isn't always
				//a selected item so default the first item to 0 and the selected item to nothing.
				nIndexOfFirstItem = 0;
				nIndexOfSelectedItem = -1;

				//If we need to sort the array we do it here
				if( m_bSorted == true )
				{
					for( int nCurItem=0 ; nCurItem<m_oListItems.Count ; nCurItem++ )
					{
						//Find the lowest text thats left
						sCurrentLowKey = "";
						sCurrentLowValue = "";
						for( int i=0 ; i<m_oListItems.Count ; i++ )
						{
							if( oKeySorted[ i ] == false && 
								( sCurrentLowValue.CompareTo( m_oListItems[ i ].ToString() ) < 0 || sCurrentLowValue.Length == 0 ) )
							{
								sCurrentLowKey = (string)m_oListKeys[ i ];
								sCurrentLowValue = m_oListItems[ i ].ToString();
								oKeySorted[ i ] = true;
							}
						}

						//Now check to see if this is the key that was at the top of the list or selected
						if( m_sKeyOfFirstItemVisible.CompareTo( sCurrentLowKey ) == 0 )
						{
							nIndexOfFirstItem = nCurItem;
						}
						if( m_sKeyOfSelectedItem.CompareTo( sCurrentLowKey ) == 0 )
						{
							nIndexOfSelectedItem = nCurItem;
						}

						//Now copy over the new item
						oaValues.Add( sCurrentLowValue );
						oaKeys.Add( sCurrentLowKey );
					}
				}
				else
				{
					//Copy over stright from the old list to the new list as it is
					for( int i=0 ; i<m_oListItems.Count ; i++ )
					{
						oaValues.Add( m_oListItems[ i ].ToString() );
						oaKeys.Add( (string)m_oListKeys[ i ] );

						//Now check to see if this is the key that was at the top of the list or selected
						if( m_sKeyOfFirstItemVisible.CompareTo( (string)oaKeys[ i ] ) == 0 )
						{
							nIndexOfFirstItem = i;
						}
						if( m_sKeyOfSelectedItem.CompareTo( (string)oaKeys[ i ] ) == 0 )
						{
							nIndexOfSelectedItem = i;
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public int GetItemCount()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetItemCount";
			int nItemCount = 0;

			try
			{
				nItemCount = m_oListItems.Count;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nItemCount );
		}

		public int GetNumCharsWide()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetNumCharsWide";
			int nNumChars = 0;

			try
			{
				nNumChars = (int)DSMisc.Max( 
					1,
					(long)( ( this.Size.X - 8 ) / this.DSGraphicsWrapper.FontSize.X ) 
					);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nNumChars );
		}
		public int GetNumCharsHigh()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetNumCharsHigh";
			int nNumChars = 0;

			try
			{
				nNumChars = (int)DSMisc.Max( 
					1,
					(long)( ( this.Size.Y - 3 )/ this.DSGraphicsWrapper.FontSize.Y ) 
					);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nNumChars );
		}


		public void AddItem( object oItem )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.AddItem";
			string sKey = "";

			try
			{
				sKey = "UniqueKey:" + m_nNextFreeKey.ToString();
				m_nNextFreeKey++;

				AddItem( oItem,sKey );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}		
		public void AddItem( object oItem,string sKey )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.AddItem";

			try
			{
				//Is this key already in the list?
				if( m_oListKeys.IndexOf( sKey ) != -1 )
				{
					//Yep.  So we can't do it.
					throw new System.Exception( "Key <" + sKey + "> already exists in the list." );
				}
				else
				{
					//Nope, so lets add it
					if( oItem == null )
					{
						m_oListItems.Add( "<Null Value>" );
					}
					else
					{
						m_oListItems.Add( oItem );
					}
					m_oListKeys.Add( sKey );
				}

				if( m_oSlideBar != null )
				{
					m_oSlideBar.Max = DSMisc.Max( m_oListItems.Count - GetNumCharsHigh(),0 );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public bool ContainsItem( string sKey )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.ContainsItem";
			bool bContainsItem = false;

			try
			{
				//Is this key in the list?
				if( m_oListKeys.IndexOf( sKey ) != -1 )
				{
					bContainsItem = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( bContainsItem );
		}
		public void RemoveItemIfFound( string sKey )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.RemoveItemIfFound";

			try
			{
				if( ContainsItem( sKey ) == true )
				{
					RemoveItem( sKey );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public void RemoveItem( string sKey )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.RemoveItem";
			int nIndex = -1;

			try
			{
				//Is this key in the list?
				nIndex = m_oListKeys.IndexOf( sKey );
				if( nIndex != -1 )
				{
					//Yep.  So lets remove it
					m_oListItems.RemoveAt( nIndex );
					m_oListKeys.RemoveAt( nIndex );					
				}
				else
				{
					throw new System.Exception( "Key <" + sKey + "> does not exists in the list." );
				}

				if( m_oSlideBar != null )
				{
					m_oSlideBar.Max = DSMisc.Max( m_oListItems.Count - GetNumCharsHigh(),0 );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void Clear()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.Clear";

			try
			{
				while( m_oListKeys.Count > 0 )
				{
					m_oListKeys.RemoveAt( 0 );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		//12/29/2004 Chris Hill  We need these calls to be able to know what is currently selected.
		public string GetSelectedKey()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetSelectedKey";
			string sRetVal = "";

			try
			{
				sRetVal = m_sKeyOfSelectedItem;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sRetVal );
		}
		public string GetSelectedText()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetSelectedText";
			int nIndex = -1;
			string sRetVal = "";

			try
			{
				nIndex = m_oListKeys.IndexOf( m_sKeyOfSelectedItem );
				sRetVal = m_oListItems[ nIndex ].ToString();
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sRetVal );
		}
		public object GetSelectedItem()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.GetSelectedItem";
			int nIndex = -1;
			object oRetVal = null;

			try
			{
				nIndex = m_oListKeys.IndexOf( m_sKeyOfSelectedItem );
				oRetVal = m_oListItems[ nIndex ];
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetVal );
		}


		public object Item( int nIndex )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.Item";
			object oRetVal = null;
			int nIndexOfSelectedItem = 0;
			int nIndexOfFirstItem = 0;
			ArrayList oSortedListItems = new ArrayList();
			ArrayList oSortedListKeys = new ArrayList();

			try
			{
				//Get the relivant data
				GetListOfItems( ref oSortedListKeys,ref oSortedListItems,ref nIndexOfFirstItem,ref nIndexOfSelectedItem );

				oRetVal = oSortedListItems[ nIndex ];
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( oRetVal );
		}

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.DSTextControl.KeyboardKeyDown";
			int nIndexOfSelectedItem = 0;
			int nIndexOfFirstItem = 0;
			int nNumCharsHigh = GetNumCharsHigh();
			ArrayList oSortedListItems = new ArrayList();
			ArrayList oSortedListKeys = new ArrayList();

			try
			{
				base.KeyboardKeyDown( oKey,oState );
				

				//Do we have anything in our list?  If not this is all meaningless
				if( m_oListItems.Count > 0 )
				{
					//Get the relivant data
					GetListOfItems( ref oSortedListKeys,ref oSortedListItems,ref nIndexOfFirstItem,ref nIndexOfSelectedItem );

					//They have hit the down key
					if( oKey == Key.Down || oKey == Key.DownArrow || oKey == Key.NumPad2 )
					{
						//If we have nothing selected then select the first item
						if( m_sKeyOfSelectedItem.Length == 0 )
						{
							nIndexOfSelectedItem = nIndexOfFirstItem;
						}
						else
						{
							//Move down one if we can
							if( nIndexOfSelectedItem < oSortedListItems.Count - 1 )
							{
								nIndexOfSelectedItem++;
							}
						}
					}
						//They have hit the up key
					else 
					{
						//If we have nothing selected then select the last item
						if( m_sKeyOfSelectedItem.Length == 0 )
						{
							nIndexOfSelectedItem = nIndexOfFirstItem + nNumCharsHigh - 1;
						}
						else
						{
							//Move down one if we can
							if( nIndexOfSelectedItem > 0 )
							{
								nIndexOfSelectedItem--;
							}
						}
					}

					//Did we change the index?
					if( nIndexOfSelectedItem != -1 )
					{
						//We've gone too far down
						if( nIndexOfSelectedItem >= nIndexOfFirstItem + nNumCharsHigh )
						{
							nIndexOfFirstItem = nIndexOfSelectedItem - nNumCharsHigh + 1;
						}
							//We've gone too far up
						else if( nIndexOfSelectedItem < nIndexOfFirstItem )
						{
							nIndexOfFirstItem = nIndexOfSelectedItem;
						}

						//Get the key of the item we choose to select and thats visible
						m_sKeyOfSelectedItem = (string)oSortedListKeys[ nIndexOfSelectedItem ];
						m_sKeyOfFirstItemVisible = (string)oSortedListKeys[ nIndexOfFirstItem ];
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseClicked( Vector2 vMousePosInControlSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.MouseClicked";
			Vector2 vGap = new Vector2( 1,1 );
			ArrayList oSortedListKeys = null;
			ArrayList oSortedListItems = null;
			int nIndexOfFirstItem = -1;
			int nIndexOfSelectedItem = -1;
			int nIndex = -1;

			try
			{
				//First of all make sure the click occured within the white area
				if( vMousePosInControlSpace.X > vGap.X + vGap.X &&
					vMousePosInControlSpace.X < this.Size.X - vGap.X - vGap.X &&
					vMousePosInControlSpace.Y > vGap.Y + vGap.Y &&
					vMousePosInControlSpace.Y < this.Size.Y - vGap.Y - vGap.Y )
				{ 
					//Now determine which list item was clicked on
					GetListOfItems( ref oSortedListKeys,ref oSortedListItems,ref nIndexOfFirstItem,ref nIndexOfSelectedItem );
					nIndex = nIndexOfFirstItem + (int)( ( vMousePosInControlSpace.Y - vGap.Y - vGap.Y ) / base.DSGraphicsWrapper.FontSize.Y );

					//Now set the selected item
					if( nIndex >=0 && nIndex < oSortedListKeys.Count )
					{
						m_sKeyOfSelectedItem = (string)oSortedListKeys[ nIndex ];
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		private void sldListBox_Change()
		{
			const string sRoutineName = "DarkStrideToolbox.DSListBoxControl.sldListBox_Change";
			ArrayList oSortedListKeys = null;
			ArrayList oSortedListItems = null;
			int nIndexOfFirstItem = -1;
			int nIndexOfSelectedItem = -1;
			int nIndex = 0;

			try
			{
				//Now determine which list item was clicked on
				GetListOfItems( ref oSortedListKeys,ref oSortedListItems,ref nIndexOfFirstItem,ref nIndexOfSelectedItem );

				nIndex = (int)m_oSlideBar.Value;
				nIndex = DSMisc.Min( nIndex,oSortedListKeys.Count - GetNumCharsHigh() );
				nIndex = DSMisc.Max( nIndex,0 );

				m_sKeyOfFirstItemVisible = (string)oSortedListKeys[ nIndex ];
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		#region Properties
		public bool Sorted
		{
			get
			{
				return( m_bSorted );
			}
			set
			{
				m_bSorted = value;
			}
		}
		#endregion
	};
	public class DSButtonControl		: DSBaseControl
	{
		#region Properties
		private string m_sText = "";
		private bool m_bImDown = false;

		//Event/Delegate tracking
		private DelegateClick	m_odDelegate_Click;
		public delegate void DelegateClick();
		#endregion


		public DSButtonControl(){}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.Render";
			double nTextX = 0;
			double nTextY = 0;
			bool bHasFocus = false;
			bool bDown = false;

			try
			{
				base.Render( oMenus,oMenu );


				//Pick the original location to draw
				nTextX = this.Pos.X + oMenu.Pos.X + this.Size.X/2.0f - m_sText.Length * 4.0f;
				nTextY = this.Pos.Y + oMenu.Pos.Y + this.Size.Y/2.0f - 8.0f;


				//Down
				if( m_bImDown == true )
				{
					bDown = true;
					bHasFocus = true;

					nTextX += 2;
					nTextY += 2;
				}
					//Focus
				else if( oMenu.ControlWithFocus != null )
				{
					if( oMenu.ControlWithFocus.Name.Equals( this.Name ) == true )
					{
						bHasFocus = true;
					}
				}


				//12/19/2004 Chris Hill  Switched over to use a centralized drawing function.
				//11/16/2004 Chris Hill  Switched this over to use drawn menues not pictures of existing menus.
//				DSButtonControl.RenderButton(	this.DSGraphicsWrapper,
//					this.Pos + oMenu.Pos,this.Pos + oMenu.Pos + this.Size,
//					1,bHasFocus,bDown,true );
//
//				//11/16/2004 Chris Hill  Switched thsi from a scaled font to a normal font so it would look better.
//				this.DSGraphicsWrapper.RenderText( nTextX,nTextY,this.FontColor, m_sText );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				m_bImDown = true;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				m_bImDown = false;
				Click();

				if( m_odDelegate_Click != null )
				{
					m_odDelegate_Click();
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				base.KeyboardKeyDown( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.NumPadEnter || oKey == Microsoft.DirectX.DirectInput.Key.Return )
				{
					m_bImDown = true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyUp";

			try
			{
				base.KeyboardKeyUp( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.NumPadEnter || oKey == Microsoft.DirectX.DirectInput.Key.Return )
				{
					m_bImDown = false;

					Click();

					if( m_odDelegate_Click != null )
					{
						m_odDelegate_Click();
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//These methods register the callback function the user of the class wishes.  
		public void RegisterDelegate_Click( DelegateClick odClick )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_Click";

			try
			{
				m_odDelegate_Click += odClick;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void Click(){}


		public static void RenderButton( DSGraphicsWrapper oGraphicsWrapper,Vector2 vUpperLeft,Vector2 vLowerRight,
			int nGapSize,bool bHasFocus,bool bDepressed,bool bUseBlackBorderIfNeeded )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.RenderButton";
			Vector2 vGap = new Vector2( nGapSize,nGapSize );

			try
			{
				//Normal
				if( bHasFocus == false )
				{
					oGraphicsWrapper.Render2DRect( vUpperLeft			,vLowerRight				,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft			,vLowerRight - vGap			,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap	,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Down
				else if( bDepressed == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
					
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Focus
				else if( bHasFocus == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
					
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap					,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap - vGap			,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap			,System.Drawing.Color.DarkGray );
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap - vGap	,System.Drawing.Color.LightGray );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		#region Properties
		public string Text
		{
			get
			{
				return( m_sText );
			}
			set
			{
				m_sText = value;
			}
		}

		public bool ImDown
		{
			get
			{
				return( m_bImDown );
			}
			set
			{
				m_bImDown = value;
			}
		}
		#endregion
	};
	public class DSSlideControl			: DSBaseControl
	{
		#region Properties
		private long m_nValue = 0;
		private long m_nMin = 0;
		private long m_nMax = 100;
		private long m_nSmallJump = 1;
		private long m_nLargeJump = 5;
		private bool m_bDownOnBar = false;
		private Vector2 m_vWhereOnBar = new Vector2( 0.0f,0.0f );
		private Vector2 m_vMousePosInControlSpace = new Vector2( 0.0f,0.0f );

		//Event/Delegate tracking
		private DelegateChange m_odDelegate_Change;
		public delegate void DelegateChange();

		//12/22/2004 Chris Hill  These are the two buttons that control the up and down location.
		private DSListButtonControl m_oUpButton = null;
		private DSListButtonControl m_oDownButton = null;
		#endregion


		public DSSlideControl(){}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.Render";
			Vector2 vSize = new Vector2( 0.0f,0.0f );
			Vector2 vPos = new Vector2( 0.0f,0.0f );

			try
			{
				base.Render( oMenus,oMenu );

				//Start with the plain grey background
				this.DSGraphicsWrapper.Render2DRect( oMenu.Pos + this.Pos,oMenu.Pos + this.Pos + this.Size,System.Drawing.Color.LightSlateGray );
				//Now render the marker that tells us where we are
				GetMarkerInfo( ref vSize,ref vPos );
				DSButtonControl.RenderButton(	this.DSGraphicsWrapper,vPos + this.Pos + oMenu.Pos,vPos + vSize + this.Pos + oMenu.Pos,
					1,false,false,true );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void InitializeWithMenu( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.InitializeWithMenu";
			Vector2 vSize = new Vector2( 0.0f,0.0f );

			try
			{
				//Have we created the arrow buttons yet
				vSize = new Vector2( base.Size.X,base.Size.X );
				vSize.Y = DSMisc.Min( vSize.Y,base.Size.Y * .30f );

				m_oUpButton = (DSListButtonControl)oMenu.AddControl(	
					new DSListButtonControl(),base.Name + "_UpArrow",base.Pos,vSize );
				m_oUpButton.RegisterDelegate_Click( new DSButtonControl.DelegateClick( this.cmdUpArrow_Click ) );

				m_oDownButton = (DSListButtonControl)oMenu.AddControl(	
					new DSListButtonControl(),base.Name + "_DownArrow",
					new Vector2( base.Pos.X,base.Pos.Y + base.Size.Y - vSize.Y ), vSize );
				m_oDownButton.RegisterDelegate_Click( new DSButtonControl.DelegateClick( this.cmdDownArrow_Click ) );
				m_oDownButton.ArrowPointsUp = false;

				this.Pos = new Vector2( this.Pos.X,this.Pos.Y + vSize.Y );
				this.Size = new Vector2( this.Size.X,this.Size.Y - vSize.Y * 2.0f );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		private void cmdUpArrow_Click()
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.cmdUpArrow_Click";

			try
			{
				MoveUp( m_nSmallJump );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		private void cmdDownArrow_Click()
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.cmdDownArrow_Click";

			try
			{
				MoveDown( m_nSmallJump );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.MouseDown";
			Vector2 vSize = new Vector2( 0.0f,0.0f );
			Vector2 vPos = new Vector2( 0.0f,0.0f );

			try
			{
				//Now render the marker that tells us where we are
				GetMarkerInfo( ref vSize,ref vPos );

				if( vMousePosInControlSpace.Y >= vPos.Y && vMousePosInControlSpace.Y <= vPos.Y + vSize.Y )
				{
					m_bDownOnBar = true;
					m_vWhereOnBar = vMousePosInControlSpace - vPos;
					m_vMousePosInControlSpace = vMousePosInControlSpace;
				}
				else
				{
					m_bDownOnBar = false;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.MouseUp";
			Vector2 vSize = new Vector2( 0.0f,0.0f );
			Vector2 vPos = new Vector2( 0.0f,0.0f );
			long nJumpDist = 0;

			try
			{
				//Now render the marker that tells us where we are
				GetMarkerInfo( ref vSize,ref vPos );

				if( m_bDownOnBar == true )
				{
					nJumpDist = GetCurrentValue() - m_nValue;
					m_bDownOnBar = false;
				}
				else
				{
					nJumpDist = m_nLargeJump;

					//Now we need to know which way to jump
					GetMarkerInfo( ref vSize,ref vPos );
					if( vMousePosInControlSpace.Y <= vPos.Y + vSize.Y / 2.0f )
					{
						nJumpDist *= -1;
					}
				}

				//Go ahead and move
				if( nJumpDist > 0 )
				{
					MoveDown( nJumpDist );
				}
				else
				{
					MoveUp( nJumpDist );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseMoved( Vector2 vMousePosInControlSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.MouseMoved";

			try
			{
				if( m_bDownOnBar == true )
				{
					m_vMousePosInControlSpace = vMousePosInControlSpace;

					if( GetCurrentValue() != m_nValue )
					{
						Change();
						if( m_odDelegate_Change!= null )
						{
							m_odDelegate_Change();
						}
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public long GetCurrentValue()
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.GetCurrentValue";
			double nPercSize = 0.0;
			long nSize = 0;
			long nY = 0;
			long nRetVal = 0;
			long nNewPos = 0;

			try
			{
				//Now render the marker that tells us where we are
				nPercSize = 1.0f / ( (double)m_nMax - (double)m_nMin + 1.0f );
				nSize = Convert.ToInt64( DSMisc.Max( 1.0f,this.Size.Y * nPercSize ) );
				nY = Convert.ToInt64( this.Size.Y * nPercSize * ( m_nValue - m_nMin ) );

				if( m_bDownOnBar == true )
				{
					nNewPos = Convert.ToInt64( m_vMousePosInControlSpace.Y - m_vWhereOnBar.Y );
					nRetVal = Convert.ToInt64( (float)nNewPos / ( this.Size.Y * nPercSize ) );
				}
				else
				{
					nRetVal = m_nValue;
				}

				//Make sure its a valid value
				nRetVal = DSMisc.Min( m_nMax,nRetVal );
				nRetVal = DSMisc.Max( m_nMin,nRetVal );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( nRetVal );
		}

		private void GetMarkerInfo( ref Vector2 vSize,ref Vector2 vPos )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.GetMarkerInfo";
			double nPercSize = 0.0;
			long nPos = 0;

			try
			{
				//Find out where the cursor is
				nPos = GetCurrentValue();

				//Now render the marker that tells us where we are
				nPercSize = 1.0f / ( (double)m_nMax - (double)m_nMin + 1.0f );
				vSize = new Vector2( this.Size.X,Convert.ToInt64( DSMisc.Max( 1.0f,this.Size.Y * nPercSize ) ) );
				vPos  = new Vector2( 0,Convert.ToInt64( this.Size.Y * nPercSize * ( nPos - m_nMin ) ) );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//These methods register the callback function the user of the class wishes.  
		public void RegisterDelegate_Change( DelegateChange odChange )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.RegisterDelegate_Change";

			try
			{
				m_odDelegate_Change += odChange;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void Change(){}


		private void MoveUp( long nAmount )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.MoveUp";

			try
			{
				if( m_nMin < m_nValue )
				{
					m_nValue = DSMisc.Max( m_nMin,m_nValue - Math.Abs( nAmount ) );

					Change();
					if( m_odDelegate_Change!= null )
					{
						m_odDelegate_Change();
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		private void MoveDown( long nAmount )
		{
			const string sRoutineName = "DarkStrideToolbox.DSSlideControl.MoveDown";

			try
			{
				if( m_nMax > m_nValue )
				{
					m_nValue = DSMisc.Min( m_nMax,m_nValue + Math.Abs( nAmount ) );

					Change();
					if( m_odDelegate_Change!= null )
					{
						m_odDelegate_Change();
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		#region Properties
		public long Value
		{
			get
			{
				return( GetCurrentValue() );
			}
			set
			{
				m_nValue = value;
			}
		}
		public long Min
		{
			get
			{
				return( m_nMin );
			}
			set
			{
				m_nMin = value;
			}
		}
		public long Max
		{
			get
			{
				return( m_nMax );
			}
			set
			{
				m_nMax = value;
			}
		}
		#endregion
	};
	public class DSListButtonControl	: DSButtonControl
	{
		#region Properties
		private bool m_bArrowPointsUp = true;
		#endregion


		public DSListButtonControl(){}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListButtonControl.Render";
			double nTextX = 0;
			double nTextY = 0;
			bool bHasFocus = false;
			bool bDown = false;

			try
			{
				base.Render( oMenus,oMenu );


				//Pick the original location to draw
				nTextX = this.Pos.X + oMenu.Pos.X + this.Size.X/2.0f - base.Text.Length * 4.0f;
				nTextY = this.Pos.Y + oMenu.Pos.Y + this.Size.Y/2.0f - 8.0f;


				//Down
				if( base.ImDown == true )
				{
					bDown = true;
					bHasFocus = true;

					nTextX += 2;
					nTextY += 2;
				}
					//Focus
				else if( oMenu.ControlWithFocus != null )
				{
					if( oMenu.ControlWithFocus.Name.Equals( this.Name ) == true )
					{
						bHasFocus = true;
					}
				}


				//12/19/2004 Chris Hill  Switched over to use a centralized drawing function.
				//11/16/2004 Chris Hill  Switched this over to use drawn menues not pictures of existing menus.
				DSListButtonControl.RenderButton(	this.DSGraphicsWrapper,
					this.Pos + oMenu.Pos,this.Pos + oMenu.Pos + this.Size,
					1,bHasFocus,bDown,true );
				DSListButtonControl.RenderArrow(	this.DSGraphicsWrapper,
					this.Pos + oMenu.Pos,this.Pos + oMenu.Pos + this.Size,
					bDown,m_bArrowPointsUp );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public new static void RenderButton( DSGraphicsWrapper oGraphicsWrapper,Vector2 vUpperLeft,Vector2 vLowerRight,
			int nGapSize,bool bHasFocus,bool bDepressed,bool bUseBlackBorderIfNeeded )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListButtonControl.RenderButton";
			Vector2 vGap = new Vector2( nGapSize,nGapSize );

			try
			{
				//Normal
				if( bHasFocus == false )
				{
					oGraphicsWrapper.Render2DRect( vUpperLeft				,vLowerRight				,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft				,vLowerRight - vGap			,System.Drawing.Color.LightGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap - vGap	,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Down
				else if( bDepressed == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
				
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap			,System.Drawing.Color.DarkGray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap	,System.Drawing.Color.LightGray ); 
				}
					//Focus
				else if( bHasFocus == true )
				{
					if( bUseBlackBorderIfNeeded == true )
					{
						oGraphicsWrapper.Render2DRect( vUpperLeft,vLowerRight,System.Drawing.Color.Black ); 
					}
					else
					{
						//Adjust the start and stop positions because we don't use black lines
						vUpperLeft -= vGap;
						vLowerRight += vGap;
					}
					
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap					,System.Drawing.Color.Gray ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap		,vLowerRight - vGap - vGap			,System.Drawing.Color.White ); 
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap			,System.Drawing.Color.DarkGray );
					oGraphicsWrapper.Render2DRect( vUpperLeft + vGap + vGap	,vLowerRight - vGap - vGap - vGap	,System.Drawing.Color.LightGray );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public static void RenderArrow( DSGraphicsWrapper oGraphicsWrapper,Vector2 vUpperLeft,Vector2 vLowerRight,
			bool bDepressed,bool bArrowPointsUp )
		{
			const string sRoutineName = "DarkStrideToolbox.DSListButtonControl.RenderArrow";
			Vector2 vStart;
			Vector2 vStop;
			long nArrow = 0;
			long nArrowMovement = 0;

			try
			{
				//Down
				if( bDepressed == true )
				{
					//This makes it look like the black arrow moves
					nArrowMovement = 1;
				}				

				//Draw the black arrow on the button.  It should be roughly 1/3rd of the dimensions.
				nArrow = Convert.ToInt64( DSMisc.Min( vLowerRight.X - vUpperLeft.X,vLowerRight.Y - vUpperLeft.Y ) * 0.33f );
				for( long i=0 ; i<nArrow / 2 ; i++ )
				{
					if( bArrowPointsUp == true )
					{
						vStart = new Vector2(	vUpperLeft.X + nArrow + i + nArrowMovement,
							vLowerRight.Y - nArrow * 1.20f - i - 1 + nArrowMovement );
						vStop =	new Vector2(	vLowerRight.X - nArrow - i + nArrowMovement,
							vLowerRight.Y - nArrow * 1.20f - i + nArrowMovement );
					}
					else
					{
						vStart = new Vector2(	vUpperLeft.X + nArrow + i + nArrowMovement,
							vUpperLeft.Y + nArrow * 1.20f + i + nArrowMovement );
						vStop =	new Vector2(	vLowerRight.X - nArrow - i + nArrowMovement,
							vUpperLeft.Y + nArrow * 1.20f + i + 1 + nArrowMovement );
					}
					oGraphicsWrapper.Render2DRect( vStart,vStop,System.Drawing.Color.Black ); 
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		#region Properties
		public bool ArrowPointsUp
		{
			get
			{
				return( m_bArrowPointsUp );
			}
			set
			{
				m_bArrowPointsUp = value;
			}
		}
		#endregion
	};
	public class DSLabelControl			: DSBaseControl
	{
		#region Properties
		private string m_sText = "";

		//Event/Delegate tracking
		private DelegateClick	m_odDelegate_Click;
		public delegate void DelegateClick();
		#endregion


		public DSLabelControl(){}


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSLabelControl.Render";
			double nTextX = 0;
			double nTextY = 0;

			try
			{
				base.Render( oMenus,oMenu );


				//Pick the original location to draw
				nTextX = this.Pos.X + oMenu.Pos.X;
				nTextY = this.Pos.Y + oMenu.Pos.Y + this.Size.Y/2.0f - 8.0f;

				this.DSGraphicsWrapper.RenderText( nTextX,nTextY,this.FontColor,m_sText );
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//These methods register the callback function the user of the class wishes.  
		public void RegisterDelegate_Click( DelegateClick odClick )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_Click";

			try
			{
				m_odDelegate_Click += odClick;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void Click(){}



		#region Properties
		public string Text
		{
			get
			{
				return( m_sText );
			}
			set
			{
				m_sText = value;
			}
		}

		#endregion
	};*/
	#endregion

	public class DSBaseControl
	{
		private float m_fElapsedTime = 0;
		private float m_fAppTime = 0;
		protected bool isMouseOver;
		protected DSMenus m_oMenus = null;
		protected DSMenu m_oMenu = null;

		#region Properties
		private Vector2 m_vSize;
		private Vector2 m_vPos;
		private string m_sName = "";
		private string m_sMouseCursorTextureKey = "";
		private System.Drawing.Color m_oFontColor = System.Drawing.Color.Black;
		private DSGraphicsWrapper m_oDSGraphicsWrapper = null;

		//Event/Delegate tracking
		private DelegateMouseWheelMoved	m_odDelegate_MouseWheelMoved = null;
		private DelegateMouseDown		m_odDelegate_MouseDown = null;
		private DelegateMouseUp			m_odDelegate_MouseUp = null;
		private DelegateMouseMoved		m_odDelegate_MouseMoved = null;
		private DelegateMouseClicked	m_odDelegate_MouseClicked = null;
		private DelegateKeyDown			m_odDelegate_KeyDown = null;
		private DelegateKeyUp			m_odDelegate_KeyUp = null;
		public delegate void DelegateMouseWheelMoved( long nDirection );
		public delegate void DelegateMouseDown( Vector2 vMousePosInControlSpace,long nButton );
		public delegate void DelegateMouseUp( Vector2 vMousePosInControlSpace,long nButton );
		public delegate void DelegateMouseMoved( Vector2 vMousePosInControlSpace,bool[] baButtons );
		public delegate void DelegateMouseClicked( Vector2 vMousePosInControlSpace,bool[] baButtons );
		public delegate void DelegateKeyDown( Key oKey,bool[] oState );
		public delegate void DelegateKeyUp( Key oKey,bool[] oState );

		//12/24/2004 Chris Hill  This will help us define child controls if neccessary... but only once.
		private bool m_bHaveInitedMenus = false;
		#endregion

		/// <summary>Called when mouse goes over the control</summary>
		public virtual void OnMouseEnter() { isMouseOver = true;}
		/// <summary>Called when mouse leaves the control</summary>
		public virtual void OnMouseExit() { isMouseOver = false;}

		public DSBaseControl( DSMenus oMenus,DSMenu oMenu )
		{
			//controlType = ControlType.Button;
			m_oMenus = oMenus;
			m_oMenu = oMenu;
			controlId = 0;
			index = 0;

			enabled = true;
			visible = true;
			isMouseOver = false;
			hasFocus = false;
			isDefault = false;

			controlX = 0; controlY = 0; width = 0; height = 0;
		}
		public DSBaseControl( DSGraphicsWrapper oDSGraphicsWrapper )
		{
			const string sRoutineName = "DarkStrideToolbox.DSBaseControl.DSBaseControl";

			try
			{
				m_oDSGraphicsWrapper = oDSGraphicsWrapper;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public virtual void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.DSBaseControl.Render";

			try
			{
				if( m_bHaveInitedMenus == false )
				{
					m_bHaveInitedMenus = true;
					InitializeWithMenu( oMenus,oMenu );					
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}			
		}

		public virtual string GetCurrentCursorTextureKey( Vector2 vMousePosInControlSpace )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.GetCurrentCursorTextureKey";
			string sRetVal = "";

			try
			{
				sRetVal = m_sMouseCursorTextureKey;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}

			return( sRetVal );
		}

		public virtual void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.DSBaseControl.FrameMove";

			try
			{
				if( m_bHaveInitedMenus == false )
				{
					m_bHaveInitedMenus = true;
					InitializeWithMenu( oMenus,oMenu );					
				}

				m_fElapsedTime = fElapsedTime;
				m_fAppTime = fAppTime;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}

		//12/24/2004 Chris Hill  This function is usefull if you need to create new controls within the control.
		public virtual void InitializeWithMenu( DSMenus oMenus,DSMenu oMenu ){}


		//Mouse functions to be overwritten by the user
		public virtual void MouseWheelMoved( long nDirection )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.MouseWheelMoved";

			try
			{
				if( m_odDelegate_MouseWheelMoved != null )
				{
					m_odDelegate_MouseWheelMoved( nDirection );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.MouseDown";

			try
			{
				if( m_odDelegate_MouseDown != null )
				{
					m_odDelegate_MouseDown( vMousePosInControlSpace,nButton );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.MouseUp";

			try
			{
				if( m_odDelegate_MouseUp != null )
				{
					m_odDelegate_MouseUp( vMousePosInControlSpace,nButton );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseMoved( Vector2 vMousePosInControlSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.MouseMoved";

			try
			{
				if( m_odDelegate_MouseMoved != null )
				{
					m_odDelegate_MouseMoved( vMousePosInControlSpace,baButtons );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public virtual void MouseClicked( Vector2 vMousePosInControlSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.MouseClicked";

			try
			{
				if( m_odDelegate_MouseClicked != null )
				{
					m_odDelegate_MouseClicked( vMousePosInControlSpace,baButtons );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.KeyboardKeyDown";

			try
			{
				if( m_odDelegate_KeyDown != null )
				{
					m_odDelegate_KeyDown( oKey,oState );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public virtual void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.BaseControl.KeyboardKeyUp";

			try
			{
				if( m_odDelegate_KeyUp != null )
				{
					m_odDelegate_KeyUp( oKey,oState );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		//These methods register the callback function the user of the class wishes.  
		public void RegisterDelegate_MouseDown( DelegateMouseDown odMouseDown )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseDown";

			try
			{
				m_odDelegate_MouseDown += odMouseDown;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_MouseUp( DelegateMouseUp odMouseUp )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseUp";

			try
			{
				m_odDelegate_MouseUp += odMouseUp;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_MouseMoved( DelegateMouseMoved odMouseMoved )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseMoved";

			try
			{
				m_odDelegate_MouseMoved += odMouseMoved;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public void RegisterDelegate_MouseClicked( DelegateMouseClicked odMouseClicked )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_MouseClicked";

			try
			{
				m_odDelegate_MouseClicked += odMouseClicked;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_KeyDown( DelegateKeyDown odKeyDown )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_KeyDown";

			try
			{
				m_odDelegate_KeyDown += odKeyDown;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public void RegisterDelegate_KeyUp( DelegateKeyUp odKeyUp )
		{
			const string sRoutineName = "DarkStrideToolbox.DSMenu.RegisterDelegate_KeyUp";

			try
			{
				m_odDelegate_KeyUp += odKeyUp;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


















		#region Instance data
		//protected DSMenu parentDialog; // Parent container
		public uint index; // Index within the control list
		public bool isDefault;

		// Protected members
		protected object localUserData; // User specificied data
		protected bool visible;
		//		protected bool isMouseOver;
		protected bool hasFocus;
		protected int controlId; // ID Number
//		protected ControlType controlType; // Control type, set in constructor
		protected System.Windows.Forms.Keys hotKey; // Controls hotkey
		protected bool enabled; // Enabled/disabled flag
		//protected System.Drawing.Rectangle boundingBox; // Rectangle defining the active region of the control

		protected int controlX,controlY,width,height; // Size, scale, and positioning members

		protected ArrayList elementList = new ArrayList(); // All display elements
		#endregion




		/// <summary>Initialize the control</summary>
		public virtual void OnInitialize() {} // Nothing to do here
		//			/// <summary>Message Handler</summary>
		//			public virtual bool MsgProc(IntPtr hWnd, NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam) {return false;} // Nothing to do here
		//			/// <summary>Handle the keyboard data</summary>
		//			public virtual bool HandleKeyboard(NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam) {return false;} // Nothing to do here
		//			/// <summary>Handle the mouse data</summary>
		//			public virtual bool HandleMouse(NativeMethods.WindowMessage msg, System.Drawing.Point pt, IntPtr wParam, IntPtr lParam) {return false;} // Nothing to do here

		/// <summary>User specified data</summary>
		public object UserData { get { return localUserData; } set { localUserData = value; } }
		/// <summary>Can the control have focus</summary>
		public virtual bool CanHaveFocus { get { return false; } }
		/// <summary>Called when control gets focus</summary>
		public virtual void OnFocusIn() { hasFocus = true;}
		/// <summary>Called when control loses focus</summary>
		public virtual void OnFocusOut() { hasFocus = false;}
		/*		/// <summary>Called when mouse goes over the control</summary>
				public virtual void OnMouseEnter() { isMouseOver = true;}
				/// <summary>Called when mouse leaves the control</summary>
				public virtual void OnMouseExit() { isMouseOver = false;}*/
		/// <summary>Called when the control's hotkey is hit</summary>
		public virtual void OnHotKey() {} // Nothing to do here
		/// <summary>Does the control contain this point</summary>
		public virtual bool ContainsPoint(System.Drawing.Point oPointInMenuSpace ) 
		{ 
			if( oPointInMenuSpace.X >= m_vPos.X && oPointInMenuSpace.Y >= m_vPos.Y &&
				oPointInMenuSpace.X <= m_vPos.X + m_vSize.X &&
				oPointInMenuSpace.Y <= m_vPos.Y + m_vSize.Y )
			{
				return( true ); 
			}
			else
			{
				return( false ); 
			}			
		}
		/// <summary>Is the control enabled</summary>
		public virtual bool IsEnabled { get { return enabled; } set { enabled = value; } }
		/// <summary>Is the control visible</summary>
		public virtual bool IsVisible { get { return visible; } set { visible = value; } }
/*		/// <summary>Type of the control</summary>
		public virtual ControlType ControlType { get { return controlType; } }*/
		/// <summary>Unique ID of the control</summary>
		public virtual int ID { get { return controlId; } set { controlId = value; } }
		/// <summary>Called to set control's location</summary>
		public virtual void SetLocation(int x, int y) 
		{ 
			controlX = x; controlY = y;  
			this.Pos = new Vector2( x,y );
			UpdateRectangles();
		}
		/// <summary>Called to set control's size</summary>
		public virtual void SetSize(int w, int h) 
		{ 
			width = w; height = h;  
			this.Size = new Vector2( w,h );
			UpdateRectangles();
		}
		/// <summary>The controls hotkey</summary>
		public virtual System.Windows.Forms.Keys Hotkey { get { return hotKey; } set { hotKey = value; } }


		/// <summary>
		/// Updates the rectangles
		/// </summary>
		protected virtual void UpdateRectangles()
		{
			//boundingBox = new System.Drawing.Rectangle(controlX, controlY, width, height);
		}

















		#region Properties
		public virtual Vector2 Size
		{
			get
			{
				return( m_vSize );
			}
			set
			{
				m_vSize = value;
			}
		}
		public virtual Vector2 Pos
		{
			get
			{
				return( m_vPos );
			}
			set
			{
				m_vPos = value;
			}
		}
		public virtual string Name
		{
			get
			{
				return( m_sName );
			}
			set
			{
				m_sName = value;
			}
		}
		public virtual string MouseCursorTextureKey
		{
			get
			{
				return( m_sMouseCursorTextureKey );
			}
			set
			{
				m_sMouseCursorTextureKey = value;
			}
		}
		public System.Drawing.Color FontColor
		{
			get
			{
				return( m_oFontColor );
			}
			set
			{
				m_oFontColor = value;
			}
		}
		public DSGraphicsWrapper DSGraphicsWrapper 
		{
			get
			{
				return( m_oDSGraphicsWrapper );
			}
			set
			{
				m_oDSGraphicsWrapper = value;
			}
		}
		public bool HaveInitedMenus
		{
			get
			{
				return( m_bHaveInitedMenus );
			}
		}
		public virtual float ElapsedTime
		{
			get
			{
				return( m_fElapsedTime );
			}
		}
		public virtual float AppTime
		{
			get
			{
				return( m_fAppTime );
			}
		}
		#endregion
	};	
	#endregion


	public enum ControlState
	{
		Normal,
		Disabled,
		Hidden,
		Focus,
		MouseOver,
		Pressed,
		LastState // Should always be last
	}

	public struct BlendColor
	{
		public ColorValue[] States; // Modulate colors for all possible control states
		public ColorValue Current; // Current color

		/// <summary>Initialize the color blending</summary>
		public void Initialize(ColorValue defaultColor, ColorValue disabledColor, ColorValue hiddenColor)
		{
			// Create the array
			States = new ColorValue[(int)ControlState.LastState];
			for(int i = 0; i < States.Length; i++)
			{
				States[i] = defaultColor;
			}

			// Store the data
			States[(int)ControlState.Disabled] = disabledColor;
			States[(int)ControlState.Hidden] = hiddenColor;
			Current = hiddenColor;
		}
		/// <summary>Initialize the color blending</summary>
		public void Initialize(ColorValue defaultColor) { Initialize( defaultColor, new ColorValue(0.5f, 0.5f, 0.5f, 0.75f),new ColorValue()); }

		/// <summary>Blend the colors together</summary>
		public void Blend(ControlState state, float elapsedTime, float rate)
		{
			if ((States == null) || (States.Length == 0) )
				return; // Nothing to do

			ColorValue destColor = States[(int)state];
			Current = ColorOperator.Lerp(Current, destColor, 1.0f - (float)Math.Pow(rate, 30 * elapsedTime) );
		}
		/// <summary>Blend the colors together</summary>
		public void Blend(ControlState state, float elapsedTime) { Blend(state, elapsedTime, 0.7f); }
	}




	#region StaticText control
	public class DSLabel : DSBaseControl
	{		
		BlendColor m_oFontColor;
		private bool m_bFirstTime = true;
		public DrawTextFormat textFormat = DrawTextFormat.Center | DrawTextFormat.VerticalCenter;
		#region Properties
		public const int TextElement = 0;
		protected string m_sLabel;
		#endregion


		/// <summary>
		/// Create a new instance of a static text control
		/// </summary>
		public DSLabel( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
//			controlType = ControlType.StaticText;
			m_sLabel = string.Empty;
			elementList.Clear();
		}

		/// <summary>
		/// Render this control
		/// </summary>
		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			if (!IsVisible)
				return; // Nothing to do here

if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_oFontColor.Initialize( DSMenu.WhiteColorValue );
	m_oFontColor.States[(int)ControlState.Disabled] = new ColorValue(0.75f, 0.75f, 0.75f, 0.75f);
}

			ControlState state = ControlState.Normal;
			if (!IsEnabled)
				state = ControlState.Disabled;

			// Blend the element colors
			m_oFontColor.Blend(state, base.ElapsedTime);

			// Render with a shadow
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			m_oMenu.DrawText(m_sLabel,  boundingBox, true,m_oFontColor,textFormat );
		}




		#region Properties
		public string Label
		{
			get
			{
				return( m_sLabel );
			}
			set
			{
				m_sLabel = value;
			}
		}
		#endregion 
	}
	#endregion

	#region Button control

	/// <summary>
	/// Button control
	/// </summary>
	public class DSButton : DSLabel
	{
BlendColor m_oBackLayer_TextureState;
BlendColor m_oBackLayer_FontColor;
BlendColor m_oFillLayer_TextureState;
BlendColor m_oFillLayer_FontColor;
bool m_bFirstTime = true;
public string m_sTextureKey;
public System.Drawing.Rectangle m_oBackLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public System.Drawing.Rectangle m_oFillLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public new DrawTextFormat textFormat = DrawTextFormat.Center | DrawTextFormat.VerticalCenter;

		//Event/Delegate tracking
		private DelegateClick	m_odDelegate_Click;
		public delegate void DelegateClick();

		private float m_fElapsedTime = 0;
		public const int ButtonLayer = 0;
		public const int FillLayer = 1;
		protected bool isPressed;
		#region Event code
		public event EventHandler Click;
		/// <summary>Create new button instance</summary>
		protected void RaiseClickEvent(DSButton sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
//			if ( !wasTriggeredByUser)
//				return;

			if (Click != null)
				Click(sender, EventArgs.Empty);
		}
		#endregion


		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fElapsedTime = fElapsedTime;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}


		/// <summary>Create new button instance</summary>
		public DSButton( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
//			controlType = ControlType.Button;
			//parentDialog = parent;
			isPressed = false;
			hotKey = 0;
		}

		/// <summary>Can the button have focus</summary>
		public override bool CanHaveFocus { get { return IsVisible && IsEnabled; } }
		/// <summary>The hotkey for this button was pressed</summary>
		public override void OnHotKey()
		{
			RaiseClickEvent(this, true);
		}

		/// <summary>
		/// Will handle the keyboard strokes
		/// </summary>
		/// 

		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				//if (ContainsPoint(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y ) ) )
				//{
					// Pressed while inside the control
					isPressed = true;
					//NativeMethods.SetCapture(Parent.SampleFramework.Window);
					if (!hasFocus)
						DSMenu.RequestFocus(this);

					return;
				//}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isPressed)
				{
					isPressed = false;
					//NativeMethods.ReleaseCapture();
					//if (!parentDialog.IsUsingKeyboardInput)
						DSMenu.ClearFocus();

					// Button click
					//if (ContainsPoint(new Point( (int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
					//	RaiseClickEvent(this, true);


					Click(this,EventArgs.Empty);

					if( m_odDelegate_Click != null )
					{
						m_odDelegate_Click();
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		public override void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyUp( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space )
				{
					isPressed = false;
					RaiseClickEvent(this, true);

					//return true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyDown( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space)
				{
					isPressed = true;
					//return true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		/// <summary>
		/// Handle mouse messages from the buttons
		/// </summary>


		/// <summary>Render the button</summary>
	//	public override void Render(Microsoft.DirectX.Direct3D.Device device, float elapsedTime)


		public override void Render( DSMenus oMenus,DSMenu oMenu )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.Render";
			int offsetX = 0;
			int offsetY = 0;

			try
			{
if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_oBackLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oBackLayer_TextureState.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
	m_oBackLayer_TextureState.States[(int)ControlState.Pressed] = new ColorValue(1.0f, 1.0f, 1.0f, 0.85f);
	m_oBackLayer_TextureRect = new System.Drawing.Rectangle(0,0,136,54);
	m_sTextureKey = "0";
	m_oBackLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
	m_oBackLayer_FontColor.States[(int)ControlState.MouseOver] = DSMenu.BlackColorValue;

	m_oFillLayer_TextureState.Initialize( DSMenu.TransparentWhite );
	m_oFillLayer_TextureState.States[(int)ControlState.MouseOver] = new ColorValue(1.0f, 1.0f, 1.0f, 0.6f);
	m_oFillLayer_TextureState.States[(int)ControlState.Pressed] = new ColorValue(0,0,0, 0.25f);
	m_oFillLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.05f);
	m_oFillLayer_TextureRect = new System.Drawing.Rectangle(136,0,136,54);
	m_sTextureKey = "0";
	m_oFillLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
	m_oFillLayer_FontColor.States[(int)ControlState.MouseOver] = DSMenu.BlackColorValue;
}

				base.Render( oMenus,oMenu );

				ControlState state = ControlState.Normal;
				if (IsVisible == false)
				{
					state = ControlState.Hidden;
				}
				else if (IsEnabled == false)
				{
					state = ControlState.Disabled;
				}
				else if (isPressed)
				{
					state = ControlState.Pressed;
					offsetX = 1;
					offsetY = 2;
				}
				else if (isMouseOver)
				{
					state = ControlState.MouseOver;
					offsetX = -1;
					offsetY = -2;
				}
				else if (hasFocus)
				{
					state = ControlState.Focus;
				}

				// Background fill layer
				//Element e = elementList[DSButton.ButtonLayer] as Element;
				float blendRate = (state == ControlState.Pressed) ? 0.0f : 0.8f;
        
				Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
				System.Drawing.Rectangle buttonRect = boundingBox;
				buttonRect.Offset(offsetX, offsetY);
        
				// Blend current color
				//e.TextureColor.Blend(state, m_fElapsedTime, blendRate);
				m_oBackLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
				m_oBackLayer_FontColor.Blend(state, m_fElapsedTime, blendRate);
				//e.FontColor.Blend(state, m_fElapsedTime, blendRate);

				// Draw sprite/text of button
				m_oMenu.DrawSprite( buttonRect,m_oBackLayer_TextureState,m_oBackLayer_TextureRect);
				m_oMenu.DrawText(m_sLabel,  buttonRect,m_oBackLayer_FontColor,textFormat);


				// Main button
				//e = elementList[DSButton.FillLayer] as Element;
        
				// Blend current color
				//e.TextureColor.Blend(state, m_fElapsedTime, blendRate);
				//e.FontColor.Blend(state, m_fElapsedTime, blendRate);
				m_oFillLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
				m_oFillLayer_FontColor.Blend(state, m_fElapsedTime, blendRate);

				//m_oMenu.DrawSprite(e, buttonRect,e.TextureColor,e.textureRect );
				//m_oMenu.DrawText(m_sLabel, e, buttonRect,e.FontColor,e.textFormat );
				m_oMenu.DrawSprite( buttonRect,m_oFillLayer_TextureState,m_oFillLayer_TextureRect);
				m_oMenu.DrawText(m_sLabel,  buttonRect,m_oFillLayer_FontColor,textFormat);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

	}
	#endregion

	#region Checkbox Control
	/// <summary>
	/// Checkbox control
	/// </summary>
	public class DSCheckBox : DSButton
	{
BlendColor m_oBoxLayer_TextureState;
BlendColor m_oBoxLayer_FontColor;
BlendColor m_oCheckLayer_TextureState;
//BlendColor m_oCheckLayer_FontColor;
bool m_bFirstTime = true;
public string m_sTextureKey;
public System.Drawing.Rectangle m_oBoxLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public System.Drawing.Rectangle m_oCheckLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public new DrawTextFormat textFormat = DrawTextFormat.Left | DrawTextFormat.VerticalCenter;


		private float m_fElapsedTime = 0;
		public const int BoxLayer = 0;
		public const int CheckLayer = 1;
		#region Event code
		public event EventHandler Changed;
		/// <summary>Create new button instance</summary>
		protected void RaiseChangedEvent(DSCheckBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			// Fire both the changed and clicked event
			base.RaiseClickEvent(sender, wasTriggeredByUser);
			if (Changed != null)
				Changed(sender, EventArgs.Empty);
		}
		#endregion
		protected System.Drawing.Rectangle buttonRect;
		protected System.Drawing.Rectangle textRect;
		protected bool isBoxChecked;

		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fElapsedTime = fElapsedTime;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}


		/// <summary>
		/// Create new checkbox instance
		/// </summary>
		public DSCheckBox( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			//controlType = ControlType.CheckBox;
			isBoxChecked = false;
			//parentDialog = parent;
		}

		/// <summary>
		/// Checked property
		/// </summary>
		public virtual bool IsChecked
		{
			get { return isBoxChecked; }
			set { SetCheckedInternal(value, false); }
		}
		/// <summary>
		/// Sets the checked state and fires the event if necessary
		/// </summary>
		protected virtual void SetCheckedInternal(bool ischecked, bool fromInput)
		{
			isBoxChecked = ischecked;
			RaiseChangedEvent(this, fromInput);
		}

		/// <summary>
		/// Override hotkey to fire event
		/// </summary>
		public override void OnHotKey()
		{
			SetCheckedInternal(!isBoxChecked, true);
		}

		/// <summary>
		/// Does the control contain the point?
		/// </summary>
		public override bool ContainsPoint(System.Drawing.Point pt)
		{
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			return (boundingBox.Contains(pt) || buttonRect.Contains(pt));
		}
		/// <summary>
		/// Update the rectangles
		/// </summary>
		protected void UpdateRectangles()
		{
			// Update base first
			//base.UpdateRectangles();

			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			// Update the two rects
			buttonRect = boundingBox;
			buttonRect = new System.Drawing.Rectangle(boundingBox.Location,
				new System.Drawing.Size(boundingBox.Height, boundingBox.Height));

			textRect = boundingBox;
			textRect.Offset((int) (1.25f * buttonRect.Width), 0);
		}

		/// <summary>
		/// Render the checkbox control
		/// </summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			ControlState state = ControlState.Normal;
			if (IsVisible == false)
				state = ControlState.Hidden;
			else if (IsEnabled == false)
				state = ControlState.Disabled;
			else if (isPressed)
				state = ControlState.Pressed;
			else if (isMouseOver)
				state = ControlState.MouseOver;
			else if (hasFocus)
				state = ControlState.Focus;
 
if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_oBoxLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oBoxLayer_TextureState.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
	m_oBoxLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.8f);
	m_oBoxLayer_TextureState.States[(int)ControlState.Pressed] = DSMenu.WhiteColorValue;
	m_oBoxLayer_TextureRect = new System.Drawing.Rectangle(0,54,27,27);
	m_sTextureKey = "0";
	m_oBoxLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
	m_oBoxLayer_FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.8f);;

	m_oCheckLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	//m_oCheckLayer_TextureState.States[(int)ControlState.MouseOver] = new ColorValue(1.0f, 1.0f, 1.0f, 0.6f);
	//m_oCheckLayer_TextureState.States[(int)ControlState.Pressed] = new ColorValue(0,0,0, 0.25f);
	//m_oCheckLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.05f);
	m_oCheckLayer_TextureRect = new System.Drawing.Rectangle(27,54,27,27);
	m_sTextureKey = "0";
	//m_oCheckLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
	//m_oCheckLayer_FontColor.States[(int)ControlState.MouseOver] = DSMenu.BlackColorValue;
}


			//Element e = elementList[Checkbox.BoxLayer] as Element;
			float blendRate = (state == ControlState.Pressed) ? 0.0f : 0.8f;
            
			// Blend current color
			//e.TextureColor.Blend(state, m_fElapsedTime, blendRate);
			//e.FontColor.Blend(state, m_fElapsedTime, blendRate);
			m_oBoxLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oBoxLayer_FontColor.Blend(state, m_fElapsedTime, blendRate);

			// Draw sprite/text of checkbox
			m_oMenu.DrawSprite( buttonRect,m_oBoxLayer_TextureState,m_oBoxLayer_TextureRect );
			m_oMenu.DrawText(base.Label,  textRect,m_oBoxLayer_FontColor,textFormat );

			if (!isBoxChecked)
				state = ControlState.Hidden;

			//e = elementList[Checkbox.CheckLayer] as Element;
			// Blend current color
			//e.TextureColor.Blend(state, m_fElapsedTime, blendRate);
			m_oCheckLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);

			// Draw sprite of checkbox
			m_oMenu.DrawSprite( buttonRect,m_oCheckLayer_TextureState,m_oCheckLayer_TextureRect );
		}

		/// <summary>
		/// Handle the keyboard for the checkbox
		/// </summary>
		public override void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyUp( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space )
				{
					if (isPressed)
					{
						isPressed = false;
						SetCheckedInternal(!isBoxChecked, true);
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyDown( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space)
				{
					isPressed = true;
					//return true;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		/// <summary>
		/// Handle mouse messages from the checkbox
		/// </summary>
		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				// Pressed while inside the control
				isPressed = true;
				//NativeMethods.SetCapture(Parent.SampleFramework.Window);
				if ( (!hasFocus) )//&& (parentDialog.IsUsingKeyboardInput) )
					DSMenu.RequestFocus(this);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isPressed)
				{
					isPressed = false;
					//NativeMethods.ReleaseCapture();

					// Button click
					//if (ContainsPoint(pt))
					//{
						SetCheckedInternal(!isBoxChecked, true);
					//}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

	}
	#endregion
	
	#region RadioButton Control
	/// <summary>
	/// Radio button control
	/// </summary>
	public class DSRadioButton : DSCheckBox
	{
		protected int buttonGroupIndex;


		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			base.Render( oMenus, oMenu );
m_oBoxLayer_TextureRect = new System.Drawing.Rectangle(54,54,27,27);
m_oCheckLayer_TextureRect = new System.Drawing.Rectangle(81,54,27,27);
		}


		/// <summary>
		/// Create new radio button instance
		/// </summary>
		public DSRadioButton( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			//controlType = ControlType.RadioButton;
			//parentDialog = parent;
		}

		/// <summary>
		/// Button Group property
		/// </summary>
		public int ButtonGroup
		{
			get { return buttonGroupIndex; }
			set { buttonGroupIndex = value; }
		}

		/// <summary>
		/// Sets the check state and potentially clears the group
		/// </summary>
		public void SetChecked(bool ischecked, bool clear)
		{
			SetCheckedInternal(ischecked, clear, false); 
		}

		/// <summary>
		/// Sets the checked state and fires the event if necessary
		/// </summary>
		protected virtual void SetCheckedInternal(bool ischecked, bool clearGroup, bool fromInput)
		{
			isBoxChecked = ischecked;
			RaiseChangedEvent(this, fromInput);
		}

		/// <summary>
		/// Override hotkey to fire event
		/// </summary>
		public override void OnHotKey()
		{
			SetCheckedInternal(true, true);
		}

		/// <summary>
		/// Handle mouse messages from the radio button
		/// </summary>
		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				//if (ContainsPoint(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y ) ) )
				//{
				// Pressed while inside the control
				isPressed = true;
				//NativeMethods.SetCapture(Parent.SampleFramework.Window);
				if (!hasFocus)
					DSMenu.RequestFocus(this);

				return;
				//}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isPressed)
				{
					isPressed = false;

					m_oMenu.ClearRadioButtonGroup(buttonGroupIndex);
					isBoxChecked = !isBoxChecked;

					RaiseChangedEvent(this, true);
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		/// <summary>
		/// Handle the keyboard for the checkbox
		/// </summary>
		public override void KeyboardKeyUp( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyUp( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space )
				{
					isPressed = false;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				base.KeyboardKeyDown( oKey,oState );

				if( oKey == Microsoft.DirectX.DirectInput.Key.Space)
				{
					isPressed = false;
					m_oMenu.ClearRadioButtonGroup(buttonGroupIndex);
					isBoxChecked = !isBoxChecked;

					RaiseChangedEvent(this, true);
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

	}
	#endregion

	#region Scrollbar control
	/// <summary>
	/// A scroll bar control
	/// </summary>
	public class DSScrollBar : DSBaseControl
	{
BlendColor m_oTrackLayer_TextureState;
BlendColor m_oUpArrowLayer_TextureState;
BlendColor m_oDownArrowLayer_TextureState;
BlendColor m_oThumbLayer_TextureState;

public System.Drawing.Rectangle m_oTrackLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public System.Drawing.Rectangle m_oUpArrowLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public System.Drawing.Rectangle m_oDownArrowLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public System.Drawing.Rectangle m_oThumbLayer_TextureRect; // Bounding rectangle of this element on the composite texture

bool m_bFirstTime = true;
public string m_sTextureKey;

		private float m_fElapsedTime = 0;
		public const int TrackLayer = 0;
		public const int UpButtonLayer = 1;
		public const int DownButtonLayer = 2;
		public const int ThumbLayer = 3;
		protected const int MinimumThumbSize = 8;
		#region Instance Data
		protected bool showingThumb;
		protected System.Drawing.Rectangle upButtonRect;
		protected System.Drawing.Rectangle downButtonRect;
		protected System.Drawing.Rectangle trackRect;
		protected System.Drawing.Rectangle thumbRect;
		protected int position; // Position of the first displayed item
		protected int pageSize; // How many items are displayable in one page
		protected int start; // First item
		protected int end; // The index after the last item
		private int thumbOffsetY;
		private bool isDragging;
		#endregion



		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fElapsedTime = fElapsedTime;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}



		/// <summary>
		/// Creates a new instance of the scroll bar class
		/// </summary>
		public DSScrollBar( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			// Store parent and control type
			//controlType = ControlType.Scrollbar;
			//parentDialog = parent;

			// Set default properties
			showingThumb = true;
			upButtonRect = System.Drawing.Rectangle.Empty;
			downButtonRect = System.Drawing.Rectangle.Empty;
			trackRect = System.Drawing.Rectangle.Empty;
			thumbRect = System.Drawing.Rectangle.Empty;

			position = 0;
			pageSize = 1;
			start = 0;
			end = 1;
		}

		/// <summary>
		/// Update all of the rectangles
		/// </summary>
		protected override void UpdateRectangles()
		{
			// Get the bounding box first
			//base.UpdateRectangles();

			// Make sure buttons are square
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			upButtonRect = new System.Drawing.Rectangle(boundingBox.Location,
				new System.Drawing.Size(boundingBox.Width, boundingBox.Width));

			downButtonRect = new System.Drawing.Rectangle(boundingBox.Left, boundingBox.Bottom - boundingBox.Width,
				boundingBox.Width, boundingBox.Width);

			trackRect = new System.Drawing.Rectangle(upButtonRect.Left, upButtonRect.Bottom, 
				upButtonRect.Width, downButtonRect.Top - upButtonRect.Bottom);

			thumbRect = upButtonRect;

			UpdateThumbRectangle();
		}

		/// <summary>
		/// Position of the track
		/// </summary>
		public int TrackPosition
		{
			get { return position; }
			set { position = value; Cap(); UpdateThumbRectangle(); }
		}
		/// <summary>
		/// Size of a 'page'
		/// </summary>
		public int PageSize
		{
			get { return pageSize; }
			set { pageSize = value; Cap(); UpdateThumbRectangle(); }
		}

		/// <summary>Clips position at boundaries</summary>
		protected void Cap()
		{
			if (position < start || end - start <= pageSize)
			{
				position = start;
			}
			else if (position + pageSize > end)
				position = end - pageSize;
		}

		/// <summary>Compute the dimension of the scroll thumb</summary>
		protected void UpdateThumbRectangle()
		{
			if (end - start > pageSize)
			{
				int thumbHeight = Math.Max(trackRect.Height * pageSize / (end-start), MinimumThumbSize);
				int maxPosition = end - start - pageSize;
				thumbRect.Location = new System.Drawing.Point(thumbRect.Left,
					trackRect.Top + (position - start) * (trackRect.Height - thumbHeight) / maxPosition);
				thumbRect.Size = new System.Drawing.Size(thumbRect.Width, thumbHeight);
				showingThumb = true;
			}
			else
			{
				// No content to scroll
				thumbRect.Height = 0;
				showingThumb = false;
			}
		}

		/// <summary>Scrolls by delta items.  A positive value scrolls down, while a negative scrolls down</summary>
		public void Scroll(int delta)
		{
			// Perform scroll
			position += delta;
			// Cap position
			Cap();
			// Update thumb rectangle
			UpdateThumbRectangle();
		}

		/// <summary>Shows an item</summary>
		public void ShowItem(int index)
		{
			// Cap the index
			if (index < 0)
				index = 0;

			if (index >= end)
				index = end - 1;

			// Adjust the position to show this item
			if (position > index)
				position = index;
			else if (position + pageSize <= index)
				position = index - pageSize + 1;

			// Update thumbs again
			UpdateThumbRectangle();
		}

		/// <summary>Sets the track range</summary>
		public void SetTrackRange(int startRange, int endRange)
		{
			start = startRange; end = endRange;
			Cap();
			UpdateThumbRectangle();
		}

		/// <summary>Render the scroll bar control</summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			ControlState state = ControlState.Normal;
			if (IsVisible == false)
				state = ControlState.Hidden;
			else if ( (IsEnabled == false) || (showingThumb == false) )
				state = ControlState.Disabled;
			else if (isMouseOver)
				state = ControlState.MouseOver;
			else if (hasFocus)
				state = ControlState.Focus;

if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_sTextureKey = "0";

	m_oTrackLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oTrackLayer_TextureRect = new System.Drawing.Rectangle(243,144,22,11);

	m_oUpArrowLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oUpArrowLayer_TextureState.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 1.0f);
	m_oUpArrowLayer_TextureRect = new System.Drawing.Rectangle(243,124,22,20);

	m_oDownArrowLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oDownArrowLayer_TextureState.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 1.0f);
	m_oDownArrowLayer_TextureRect = new System.Drawing.Rectangle(243,155,22,21);

	m_oThumbLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oThumbLayer_TextureRect = new System.Drawing.Rectangle(266,123,20,44);
}

			float blendRate = (state == ControlState.Pressed) ? 0.0f : 0.8f;

			// Track 
			m_oTrackLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( trackRect,m_oTrackLayer_TextureState,m_oTrackLayer_TextureRect );

			// Up arrow
			m_oUpArrowLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( upButtonRect,m_oUpArrowLayer_TextureState,m_oUpArrowLayer_TextureRect );

			// Down arrow
			m_oDownArrowLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( downButtonRect,m_oDownArrowLayer_TextureState,m_oDownArrowLayer_TextureRect );

			// Thumb button
			m_oThumbLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( thumbRect,m_oThumbLayer_TextureState,m_oThumbLayer_TextureRect );
		}

		/// <summary>Stores data for a combo box item</summary>
		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				//NativeMethods.SetCapture(Parent.SampleFramework.Window);

				// Check for on up button
				if (upButtonRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y) ))
				{
					if (position > start)
						--position;
					UpdateThumbRectangle();
					return;
				}

				// Check for on down button
				if (downButtonRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				{
					if (position + pageSize < end)
						++position;
					UpdateThumbRectangle();
					return ;
				}

				// Check for click on thumb
				if (thumbRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				{
					isDragging = true;
					thumbOffsetY = (int)vMousePosInControlSpace.Y - thumbRect.Top;
					return ;
				}

				// check for click on track
				if (thumbRect.Left <= vMousePosInControlSpace.X &&
					thumbRect.Right > vMousePosInControlSpace.X)
				{
					if (thumbRect.Top > vMousePosInControlSpace.Y &&
						trackRect.Top <= vMousePosInControlSpace.Y)
					{
						Scroll(-(pageSize-1));
						return ;
					}
					else if (thumbRect.Bottom <= vMousePosInControlSpace.Y &&
						trackRect.Bottom > vMousePosInControlSpace.Y)
					{
						Scroll(pageSize-1);
						return ;
					}
				}
			

			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				isDragging = false;
				//NativeMethods.ReleaseCapture();
				UpdateThumbRectangle();
				//break;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isDragging)
				{
					// Calculate new bottom and top of thumb rect
					int bottom = thumbRect.Bottom + ((int)vMousePosInMenuSpace.Y - thumbOffsetY - thumbRect.Top);
					int top = (int)vMousePosInMenuSpace.Y - thumbOffsetY;
					thumbRect = new System.Drawing.Rectangle(thumbRect.Left, top, thumbRect.Width, bottom - top);
					if (thumbRect.Top < trackRect.Top)
						thumbRect.Offset(0, trackRect.Top - thumbRect.Top);
					else if (thumbRect.Bottom > trackRect.Bottom)
						thumbRect.Offset(0, trackRect.Bottom - thumbRect.Bottom);

					// Compute first item index based on thumb position
					int maxFirstItem = end - start - pageSize; // Largest possible index for first item
					int maxThumb = trackRect.Height - thumbRect.Height; // Largest possible thumb position

					position = start + (thumbRect.Top - trackRect.Top +
						maxThumb / (maxFirstItem * 2) ) * // Shift by half a row to avoid last row covered
						maxFirstItem / maxThumb;

					return ;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
	}
	#endregion

	#region ComboBox Control
	/// <summary>Stores data for a combo box item</summary>
	public struct ComboBoxItem
	{
		public string ItemText;
		public object ItemData;
		public System.Drawing.Rectangle ItemRect;
		public bool IsItemVisible;
	}

	/// <summary>Combo box control</summary>
	public class DSComboBox : DSButton
	{
BlendColor m_oMainLayer_TextureState;
BlendColor m_oMainLayer_FontColor;
public System.Drawing.Rectangle m_oMainLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textMainFormat = DrawTextFormat.Center | DrawTextFormat.VerticalCenter;

BlendColor m_oButtonLayer_TextureState;
public System.Drawing.Rectangle m_oButtonLayer_TextureRect; // Bounding rectangle of this element on the composite texture

BlendColor m_oDropdownLayer_TextureState;
BlendColor m_oDropdownLayer_FontColor;
public System.Drawing.Rectangle m_oDropdownLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textDropdownFormat = DrawTextFormat.Left | DrawTextFormat.VerticalCenter;

BlendColor m_oSelectionLayer_TextureState;
BlendColor m_oSelectionLayer_FontColor;
public System.Drawing.Rectangle m_oSelectionLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textSelectionFormat = DrawTextFormat.Left | DrawTextFormat.VerticalCenter;

bool m_bFirstTime = true;
public string m_sTextureKey = "0";

		private float m_fElapsedTime = 0;
		public const int MainLayer = 0;
		public const int ComboButtonLayer = 1;
		public const int DropdownLayer = 2;
		public const int SelectionLayer = 3;
		#region Event code
		public event EventHandler Changed;
		/// <summary>Create new button instance</summary>
		protected void RaiseChangedEvent(DSComboBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			// Fire both the changed and clicked event
			base.RaiseClickEvent(sender, wasTriggeredByUser);
			if (Changed != null)
				Changed(sender, EventArgs.Empty);
		}
		#endregion
		private bool isScrollBarInit;

		#region Instance data
		protected int selectedIndex;
		protected int focusedIndex;
		protected int dropHeight;
		protected DSScrollBar scrollbarControl;
		protected int scrollWidth;
		protected bool isComboOpen;
		protected System.Drawing.Rectangle textRect;
		protected System.Drawing.Rectangle buttonRect;
		protected System.Drawing.Rectangle dropDownRect;
		protected System.Drawing.Rectangle dropDownTextRect;
		protected ArrayList itemList;
		#endregion


		public override bool ContainsPoint(Point oPointInMenuSpace)
		{
			if( isComboOpen == true && dropDownRect.Contains(oPointInMenuSpace) == true )
			{
				return( true );
			}
			else
			{
				if( oPointInMenuSpace.X >= this.Pos.X && oPointInMenuSpace.Y >= this.Pos.Y &&
					oPointInMenuSpace.X <= this.Pos.X + this.Size.X &&
					oPointInMenuSpace.Y <= this.Pos.Y + this.Size.Y )
				{
					return( true ); 
				}
				else
				{
					return( false ); 
				}
			}

			//return base.ContainsPoint (oPointInMenuSpace);
		}


		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fElapsedTime = fElapsedTime;

				if( isScrollBarInit == true )
				{
					scrollbarControl.FrameMove( oMenus,oMenu,fElapsedTime,fAppTime );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}


		/// <summary>Create new combo box control</summary>
		public DSComboBox( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			// Store control type and parent dialog
			//controlType = ControlType.ComboBox;
			//parentDialog = parent;
			// Create the scrollbar control too
			scrollbarControl = new DSScrollBar(oMenus,oMenu);

			// Set some default items
			dropHeight = 100;
			scrollWidth = 16;
			selectedIndex = -1;
			focusedIndex = -1;
			isScrollBarInit = false;

			// Create the item list array
			itemList = new ArrayList();
		}

		/// <summary>Update the rectangles for the combo box control</summary>
		protected override void UpdateRectangles()
		{
			// Get bounding box
			//base.UpdateRectangles();

			// Update the bounding box for the items
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			buttonRect = new System.Drawing.Rectangle(boundingBox.Right - boundingBox.Height, boundingBox.Top,
				boundingBox.Height, boundingBox.Height);

			textRect = boundingBox;
			textRect.Size = new System.Drawing.Size(textRect.Width - buttonRect.Width, textRect.Height);

			dropDownRect = textRect;
			dropDownRect.Offset(0, (int)(0.9f * textRect.Height));
			dropDownRect.Size = new System.Drawing.Size(dropDownRect.Width - scrollWidth, dropDownRect.Height + dropHeight);

			// Scale it down slightly
			System.Drawing.Point loc = dropDownRect.Location;
			System.Drawing.Size size = dropDownRect.Size;

			loc.X += (int)(0.1f * dropDownRect.Width);
			loc.Y += (int)(0.1f * dropDownRect.Height);
			size.Width -= (2 * (int)(0.1f * dropDownRect.Width));
			size.Height -= (2 * (int)(0.1f * dropDownRect.Height));

			dropDownTextRect = new System.Drawing.Rectangle(loc, size);

			// Update the scroll bars rects too
			scrollbarControl.SetLocation(dropDownRect.Right, dropDownRect.Top + 2);
			scrollbarControl.SetSize(scrollWidth, dropDownRect.Height - 2);

			//Chris
			//FontNode fNode = DialogResourceManager.GetGlobalInstance().GetFontNode((int)(elementList[2] as Element).FontIndex);
			//if ((fNode != null) && (fNode.Height > 0))
			//{
				//scrollbarControl.PageSize = (int)(dropDownTextRect.Height / fNode.Height);
				scrollbarControl.PageSize = (int)(dropDownTextRect.Height / DSResourceManager.GetGlobalInstance().m_oFontSize.Y);
			
				// The selected item may have been scrolled off the page.
				// Ensure that it is in page again.
				scrollbarControl.ShowItem(selectedIndex);
			//}
		}

		/// <summary>Sets the drop height of this control</summary>
		public void SetDropHeight(int height) { dropHeight = height; UpdateRectangles(); }
		/// <summary>Sets the scroll bar width of this control</summary>
		public void SetScrollbarWidth(int width) { scrollWidth = width; UpdateRectangles(); }
		/// <summary>Can this control have focus</summary>
		public override bool CanHaveFocus { get { return (IsVisible && IsEnabled); } }
		/// <summary>Number of items current in the list</summary>
		public int NumberItems { get { return itemList.Count; } }
		/// <summary>Indexer for items in the list</summary>
		public ComboBoxItem this[int index]
		{
			get { return (ComboBoxItem)itemList[index]; }
		}

		/// <summary>Initialize the scrollbar control here</summary>
		public override void OnInitialize()
		{
//			m_oMenu.InitializeControl(scrollbarControl);
		}

		/// <summary>Called when focus leaves the control</summary>
		public override void OnFocusOut()
		{
			// Call base first
			base.OnFocusOut ();
			isComboOpen = false;
		}
		/// <summary>Called when the control's hotkey is pressed</summary>
		public override void OnHotKey()
		{
			if (isComboOpen)
				return; // Nothing to do yet

			if (selectedIndex == -1)
				return; // Nothing selected

			selectedIndex++;
			if (selectedIndex >= itemList.Count)
				selectedIndex = 0;

			focusedIndex = selectedIndex;
			RaiseChangedEvent(this, true);
		}


		/// <summary>Called when the control should handle the mouse</summary>
		public override void MouseWheelMoved( long nDirection )
		{
			//Chris
			//int zdelta = (short)NativeMethods.HiWord((uint)wParam.ToInt32()) / DSMenu.WheelDelta;
			int zdelta = (int)nDirection;
			if (isComboOpen)
			{
				scrollbarControl.Scroll(-zdelta * System.Windows.Forms.SystemInformation.MouseWheelScrollLines);
			}
			else
			{
				if (zdelta > 0)
				{
					if (focusedIndex > 0)
					{
						focusedIndex--;
						selectedIndex = focusedIndex;
						if (!isComboOpen)
						{
							RaiseChangedEvent(this, true);
						}
					}
				}
				else
				{
					if (focusedIndex +1 < NumberItems)
					{
						focusedIndex++;
						selectedIndex = focusedIndex;
						if (!isComboOpen)
						{
							RaiseChangedEvent(this, true);
						}
					}
				}
			}
		}
		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				//if (ContainsPoint(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				if( vMousePosInControlSpace.Y < this.Size.Y )
				{
					// Pressed while inside the control
					isPressed = true;
					//NativeMethods.SetCapture(Parent.SampleFramework.Window);

					if (!hasFocus)
						DSMenu.RequestFocus(this);

					// Toggle dropdown
					if (hasFocus)
					{
						isComboOpen = !isComboOpen;
						if (!isComboOpen)
						{
							//if (!parentDialog.IsUsingKeyboardInput)
								DSMenu.ClearFocus();
						}
					}

					return ;
				}

				// Perhaps this click is within the dropdown
				if (isComboOpen && dropDownRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				{
					// Determine which item has been selected
					for (int i = scrollbarControl.TrackPosition; i < itemList.Count; i++)
					{
						ComboBoxItem cbi = (ComboBoxItem)itemList[i];
						if (cbi.IsItemVisible && cbi.ItemRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
						{
							selectedIndex = focusedIndex = i;
							RaiseChangedEvent(this, true);

							isComboOpen = false;

							//if (!parentDialog.IsUsingKeyboardInput)
								DSMenu.ClearFocus();

							break;
						}
					}
					return ;
				}
				// Mouse click not on main control or in dropdown, fire an event if needed
				if (isComboOpen)
				{
					focusedIndex = selectedIndex;
					RaiseChangedEvent(this, true);
					isComboOpen = false;
				}

				// Make sure the control is no longer 'pressed'
				isPressed = false;

				// Release focus if appropriate
				//if (!parentDialog.IsUsingKeyboardInput)
					DSMenu.ClearFocus();
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isPressed )//&& ContainsPoint(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				{
					// Button click
					isPressed = false;
					//NativeMethods.ReleaseCapture();
					return ;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isComboOpen && dropDownRect.Contains(new Point((int)vMousePosInMenuSpace.X,(int)vMousePosInMenuSpace.Y)))
				{
					// Determine which item has been selected
					for (int i = 0; i < itemList.Count; i++)
					{
						ComboBoxItem cbi = (ComboBoxItem)itemList[i];
						if (cbi.IsItemVisible && cbi.ItemRect.Contains(new Point((int)vMousePosInMenuSpace.X,(int)vMousePosInMenuSpace.Y)))
						{
							focusedIndex = i;
						}
					}
					return ;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		

		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";
			const uint RepeatMask = (0x40000000);

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if( oKey == Microsoft.DirectX.DirectInput.Key.Return )
				{
					if (isComboOpen)
					{
						if (selectedIndex != focusedIndex)
						{
							selectedIndex = focusedIndex;
							RaiseChangedEvent(this, true);
						}
						isComboOpen = false;

						//if (!Parent.IsUsingKeyboardInput)
							DSMenu.ClearFocus();

						return ;
					}
			
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.F4 )
				{
					//Chris
					// Filter out auto repeats
					//if ((lParam.ToInt32() & RepeatMask) != 0)
					//	return ;

					isComboOpen = !isComboOpen;
					if (!isComboOpen)
					{
						RaiseChangedEvent(this, true);

						//if (!Parent.IsUsingKeyboardInput)
							DSMenu.ClearFocus();
					}

					return ;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Left || oKey == Microsoft.DirectX.DirectInput.Key.Up )
				{
					if (focusedIndex > 0)
					{
						focusedIndex--;
						selectedIndex = focusedIndex;
						if (!isComboOpen)
							RaiseChangedEvent(this, true);
					}
					return ;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Right || oKey == Microsoft.DirectX.DirectInput.Key.Down )
				{
					if (focusedIndex + 1 < (int)NumberItems)
					{
						focusedIndex++;
						selectedIndex = focusedIndex;
						if (!isComboOpen)
							RaiseChangedEvent(this, true);
					}
					return ;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		/// <summary>Called when the control should be rendered</summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			ControlState state = ControlState.Normal;
			if (!isComboOpen)
				state = ControlState.Hidden;
if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_sTextureKey = "0";

	m_oMainLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oMainLayer_TextureState.States[(int)ControlState.Normal] = new ColorValue(0.8f, 0.8f, 0.8f, 0.55f);
	m_oMainLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(0.95f, 0.95f, 0.95f, 0.6f);
	m_oMainLayer_TextureState.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.25f);
	m_oMainLayer_TextureRect = new System.Drawing.Rectangle(7,81, 240, 42);
	m_oMainLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
	m_oMainLayer_FontColor.States[(int)ControlState.MouseOver] = new ColorValue(0,0,0,1.0f);
	m_oMainLayer_FontColor.States[(int)ControlState.Pressed] = new ColorValue(0,0,0,1.0f);
	m_oMainLayer_FontColor.States[(int)ControlState.Disabled] = new ColorValue(0.8f, 0.8f, 0.8f, 0.8f);

	m_oButtonLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oButtonLayer_TextureState.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
	m_oButtonLayer_TextureState.States[(int)ControlState.Pressed] = new ColorValue(0.55f, 0.55f, 0.55f, 1.0f);
	m_oButtonLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.75f);
	m_oButtonLayer_TextureState.States[(int)ControlState.Disabled] = new ColorValue(1.0f, 1.0f, 1.0f, 0.25f);
	m_oButtonLayer_TextureRect = new System.Drawing.Rectangle(272,0, 53, 49);

	m_oDropdownLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oDropdownLayer_TextureRect = new System.Drawing.Rectangle(7,123,234,142);
	m_oDropdownLayer_FontColor.Initialize( DSMenu.BlackColorValue );

	m_oSelectionLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oSelectionLayer_TextureRect = new System.Drawing.Rectangle(7,266,234,23);
	m_oSelectionLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
}

			// Dropdown box
			//Element e = elementList[ComboBox.DropdownLayer] as Element;
            
			// If we have not initialized the scroll bar page size,
			// do that now.
			if (!isScrollBarInit)
			{
				//Chris
				//FontNode fNode = DialogResourceManager.GetGlobalInstance().GetFontNode((int)e.FontIndex);
				//if ((fNode != null) && (fNode.Height > 0))
					scrollbarControl.PageSize = (int)(dropDownTextRect.Height / DSResourceManager.GetGlobalInstance().m_oFontSize.Y);
				//else
				//	scrollbarControl.PageSize = dropDownTextRect.Height;

				isScrollBarInit = true;
			}

			if (isComboOpen)
				scrollbarControl.Render(m_oMenus,m_oMenu);

			//Drop down layer
			// Blend current color
			m_oDropdownLayer_TextureState.Blend(state, m_fElapsedTime);
			m_oDropdownLayer_FontColor.Blend(state, m_fElapsedTime);
			m_oMenu.DrawSprite( dropDownRect,m_oDropdownLayer_TextureState,m_oDropdownLayer_TextureRect );

			// Selection layer
			//Element selectionElement = elementList[ComboBox.SelectionLayer] as Element;
			m_oSelectionLayer_TextureState.Current = m_oDropdownLayer_TextureState.Current;
			m_oSelectionLayer_FontColor.Current = m_oSelectionLayer_FontColor.States[(int)ControlState.Normal];

			//Chris
			//FontNode font = DialogResourceManager.GetGlobalInstance().GetFontNode((int)e.FontIndex);
			int currentY = dropDownTextRect.Top;
			int remainingHeight = dropDownTextRect.Height;

			for (int i = scrollbarControl.TrackPosition; i < itemList.Count; i++)
			{
				ComboBoxItem cbi = (ComboBoxItem)itemList[i];

				// Make sure there's room left in the dropdown
				remainingHeight -= (int)DSResourceManager.GetGlobalInstance().m_oFontSize.Y;
				if (remainingHeight < 0)
				{
					// Not visible, store that item
					cbi.IsItemVisible = false;
					itemList[i] = cbi; // Store this back in list
					continue;
				}

				cbi.ItemRect = new System.Drawing.Rectangle(dropDownTextRect.Left, currentY,
					dropDownTextRect.Width, (int)DSResourceManager.GetGlobalInstance().m_oFontSize.Y);
				cbi.IsItemVisible = true;
				currentY += (int)DSResourceManager.GetGlobalInstance().m_oFontSize.Y;
				itemList[i] = cbi; // Store this back in list

				if (isComboOpen)
				{
					if (focusedIndex == i)
					{
						System.Drawing.Rectangle rect = new System.Drawing.Rectangle(
							dropDownRect.Left, cbi.ItemRect.Top - 2, dropDownRect.Width,
							cbi.ItemRect.Height + 4);
						m_oMenu.DrawSprite( rect,m_oSelectionLayer_TextureState,m_oSelectionLayer_TextureRect );
						m_oMenu.DrawText(cbi.ItemText,  cbi.ItemRect,m_oSelectionLayer_FontColor,textDropdownFormat );
					}
					else
					{
						m_oMenu.DrawText(cbi.ItemText,  cbi.ItemRect,m_oDropdownLayer_FontColor,textDropdownFormat );
					}
				}
			}

			int offsetX = 0;
			int offsetY = 0;

			state = ControlState.Normal;
			if (IsVisible == false)
				state = ControlState.Hidden;
			else if (IsEnabled == false)
				state = ControlState.Disabled;
			else if (isPressed)
			{
				state = ControlState.Pressed;
				offsetX = 1;
				offsetY = 2;
			}
			else if (isMouseOver)
			{
				state = ControlState.MouseOver;
				offsetX = -1;
				offsetY = -2;
			}
			else if (hasFocus)
				state = ControlState.Focus;

			float blendRate = (state == ControlState.Pressed) ? 0.0f : 0.8f;

		// Button
			// Blend current color
			m_oButtonLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
            
			System.Drawing.Rectangle windowRect = buttonRect;
			windowRect.Offset(offsetX, offsetY);
			// Draw sprite
			m_oMenu.DrawSprite( windowRect,m_oButtonLayer_TextureState,m_oButtonLayer_TextureRect );

			if (isComboOpen)
				state = ControlState.Pressed;

		// Main text box
			// Blend current color
			m_oMainLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMainLayer_FontColor.Blend(state, m_fElapsedTime, blendRate);

			// Draw sprite
			m_oMenu.DrawSprite( textRect,m_oMainLayer_TextureState,m_oMainLayer_TextureRect );

			if (selectedIndex >= 0 && selectedIndex < itemList.Count)
			{
				try
				{
					ComboBoxItem cbi = (ComboBoxItem)itemList[selectedIndex];
					m_oMenu.DrawText(cbi.ItemText,  textRect,m_oMainLayer_FontColor,textMainFormat );
				}
				catch {} // Ignore
			}

		}


		#region Item Controlling methods
		/// <summary>Adds an item to the combo box control</summary>
		public void AddItem(string text, object data)
		{
			if ((text == null) || (text.Length == 0))
				throw new ArgumentNullException("text", "You must pass in a valid item name when adding a new item.");

			// Create a new item and add it
			ComboBoxItem newitem = new ComboBoxItem();
			newitem.ItemText = text;
			newitem.ItemData = data;
			itemList.Add(newitem);

			// Update the scrollbar with the new range
			scrollbarControl.SetTrackRange(0, itemList.Count);

			// If this is the only item in the list, it should be selected
			if (NumberItems == 1)
			{
				selectedIndex = 0;
				focusedIndex = 0;
				RaiseChangedEvent(this, false);
			}
		}

		/// <summary>Removes an item at a particular index</summary>
		public void RemoveAt(int index)
		{
			// Remove the item
			itemList.RemoveAt(index);

			// Update the scrollbar with the new range
			scrollbarControl.SetTrackRange(0, itemList.Count);

			if (selectedIndex >= itemList.Count)
				selectedIndex = itemList.Count - 1;
		}

		/// <summary>Removes all items from the control</summary>
		public void Clear()
		{
			// clear the list
			itemList.Clear();

			// Update scroll bar and index
			scrollbarControl.SetTrackRange(0, 1);
			focusedIndex = selectedIndex = -1;
		}

		/// <summary>Determines whether this control contains an item</summary>
		public bool ContainsItem(string text, int start)
		{
			return (FindItem(text, start) != -1);
		}
		/// <summary>Determines whether this control contains an item</summary>
		public bool ContainsItem(string text) { return ContainsItem(text, 0); }

		/// <summary>Gets the data for the selected item</summary>
		public object GetSelectedData()
		{
			if (selectedIndex < 0)
				return null; // Nothing selected

			ComboBoxItem cbi = (ComboBoxItem)itemList[selectedIndex];
			return cbi.ItemData;
		}

		/// <summary>Gets the selected item</summary>
		public ComboBoxItem GetSelectedItem()
		{
			if (selectedIndex < 0)
				throw new ArgumentOutOfRangeException("selectedIndex", "No item selected.");

			return (ComboBoxItem)itemList[selectedIndex];
		}

		/// <summary>Gets the data for an item</summary>
		public object GetItemData(string text)
		{
			int index = FindItem(text);
			if (index == -1)
				return null; // no item

			ComboBoxItem cbi = (ComboBoxItem)itemList[index];
			return cbi.ItemData;
		}

		/// <summary>Finds an item in the list and returns the index</summary>
		protected int FindItem(string text, int start)
		{
			if ((text == null) || (text.Length == 0))
				return -1;

			for(int i = start; i < itemList.Count; i++)
			{
				ComboBoxItem cbi = (ComboBoxItem)itemList[i];
				if (string.Compare(cbi.ItemText, text, true) == 0)
				{
					return i;
				}
			}

			// Never found it
			return -1;
		}
		/// <summary>Finds an item in the list and returns the index</summary>
		protected int FindItem(string text) { return FindItem(text, 0); }

		/// <summary>Sets the selected item by index</summary>
		public void SetSelected(int index)
		{
			if (index >= NumberItems)
				throw new ArgumentOutOfRangeException("index", "There are not enough items in the list to select this index.");

			focusedIndex = selectedIndex = index;
			RaiseChangedEvent(this, false);
		}

		/// <summary>Sets the selected item by text</summary>
		public void SetSelected(string text)
		{
			if ((text == null) || (text.Length == 0))
				throw new ArgumentNullException("text", "You must pass in a valid item name when adding a new item.");

			int index = FindItem(text);
			if (index == -1)
				throw new InvalidOperationException("This item could not be found.");

			focusedIndex = selectedIndex = index;
			RaiseChangedEvent(this, false);
		}

		/// <summary>Sets the selected item by data</summary>
		public void SetSelectedByData(object data)
		{
			for (int index = 0; index < itemList.Count; index++)
			{
				ComboBoxItem cbi = (ComboBoxItem)itemList[index];
				if (cbi.ItemData.ToString().Equals(data.ToString()))
				{
					focusedIndex = selectedIndex = index;
					RaiseChangedEvent(this, false);
				}
			}

			// Could not find this item.  Uncomment line below for debug information
			//System.Diagnostics.Debugger.Log(9,string.Empty, "Could not find an object with this data.\r\n");
		}

		#endregion
	}
	#endregion
	
	#region Slider Control
	/// <summary>Slider control</summary>
	public class DSSlider : DSBaseControl
	{
bool m_bFirstTime = true;
public string m_sTextureKey;

BlendColor m_oButtonLayer_TextureState;
BlendColor m_oButtonLayer_FontColor;
public System.Drawing.Rectangle m_oButtonLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textButtonFormat = DrawTextFormat.Left | DrawTextFormat.VerticalCenter;

BlendColor m_oTrackLayer_TextureState;
BlendColor m_oTrackLayer_FontColor;
public System.Drawing.Rectangle m_oTrackLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textTrackFormat = DrawTextFormat.Left | DrawTextFormat.VerticalCenter;

		public const int TrackLayer = 0;
		public const int ButtonLayer = 1;
		#region Instance Data
		public event EventHandler ValueChanged;
		protected int currentValue; 
		protected int maxValue;
		protected int minValue;
        
		protected int dragX; // Mouse position at the start of the drag
		protected int dragOffset; // Drag offset from the center of the button
		protected int buttonX;

		protected bool isPressed;
		protected System.Drawing.Rectangle buttonRect;
		private float m_fElapsedTime = 0;

		/// <summary>Slider's can always have focus</summary>
		public override bool CanHaveFocus { get { return true; }}

		/// <summary>Current value of the slider</summary>
		protected void RaiseValueChanged(DSSlider sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			if (ValueChanged != null)
				ValueChanged(sender, EventArgs.Empty);
		}
		/// <summary>Current value of the slider</summary>
		public int Value { get { return currentValue; } set { SetValueInternal(value, false); } }
		/// <summary>Sets the range of the slider</summary>
		public void SetRange(int min, int max)
		{
			minValue = min;
			maxValue = max;
			SetValueInternal(currentValue, false);
		}

		/// <summary>Sets the value internally and fires the event if needed</summary>
		protected void SetValueInternal(int newValue, bool fromInput)
		{
			// Clamp to the range
			newValue = Math.Max(minValue, newValue);
			newValue = Math.Min(maxValue, newValue);
			if (newValue == currentValue)
				return;

			// Update the value, the rects, then fire the events if necessar
			currentValue = newValue; 
			UpdateRectangles();
			RaiseValueChanged(this, fromInput);
		}
		#endregion


		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fElapsedTime = fElapsedTime;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}



		/// <summary>Create new button instance</summary>
		public DSSlider( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			//controlType = ControlType.Slider;
			//parentDialog = parent;

			isPressed = false;
			minValue = 0;
			maxValue = 100;
			currentValue = 50;
		}

		/// <summary>Does the control contain this point?</summary>
		public override bool ContainsPoint(System.Drawing.Point pt)
		{
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			return boundingBox.Contains(pt) || buttonRect.Contains(pt);
		}

		/// <summary>Update the rectangles for the control</summary>
		protected override void UpdateRectangles()
		{
			// First get the bounding box
			base.UpdateRectangles ();

			// Create the button rect
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			buttonRect = boundingBox;
			buttonRect.Width = buttonRect.Height; // Make it square

			// Offset it 
			buttonRect.Offset(-buttonRect.Width / 2, 0);
			buttonX = (int)((currentValue - minValue) * (float)boundingBox.Width / (maxValue - minValue) );
			buttonRect.Offset(buttonX, 0);
		}

		/// <summary>Gets a value from a position</summary>
		public int ValueFromPosition(int x)
		{
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			float valuePerPixel = ((float)(maxValue - minValue) / (float)boundingBox.Width);
			return (int)(0.5f + minValue + valuePerPixel * (x - boundingBox.Left));
		}


		/// <summary>Handle mouse input input</summary>
		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );

				if (!IsEnabled || !IsVisible)
					return;

				if (buttonRect.Contains(new Point((int)vMousePosInControlSpace.X+(int)this.Pos.X,(int)vMousePosInControlSpace.Y+(int)this.Pos.Y) ))
				{
					// Pressed while inside the control
					isPressed = true;
					//NativeMethods.SetCapture(Parent.SampleFramework.Window);

					dragX = (int)vMousePosInControlSpace.X;
					dragOffset = buttonX - dragX;
					if (!hasFocus)
						DSMenu.RequestFocus(this);
                        
					return ;
				}
				if (boundingBox.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y)))
				{
					if (vMousePosInControlSpace.X > buttonX + controlX)
					{
						SetValueInternal(currentValue + 1, true);
						return ;
					}
					if (vMousePosInControlSpace.X < buttonX + controlX)
					{
						SetValueInternal(currentValue - 1, true);
						return ;
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				isPressed = false;
				//NativeMethods.ReleaseCapture();
				DSMenu.ClearFocus();
				//RaiseValueChanged(this, true);
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isPressed)
				{
					SetValueInternal(ValueFromPosition(controlX + (int)vMousePosInMenuSpace.X + dragOffset), true);
					return ;
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		/// <summary>Handle keyboard input</summary>
		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if( oKey == Microsoft.DirectX.DirectInput.Key.Home )
				{
					SetValueInternal(minValue, true);
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.End )
				{
					SetValueInternal(maxValue, true);
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Prior ||
						 oKey == Microsoft.DirectX.DirectInput.Key.Left ||
						 oKey == Microsoft.DirectX.DirectInput.Key.Up )
				{
					SetValueInternal(currentValue - 1, true);
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Next ||
						 oKey == Microsoft.DirectX.DirectInput.Key.Right ||
						 oKey == Microsoft.DirectX.DirectInput.Key.Down )
				{
						SetValueInternal(currentValue + 1, true);
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

    
		/// <summary>Render the slider</summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );

if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_sTextureKey = "0";

	m_oButtonLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oButtonLayer_TextureRect = new System.Drawing.Rectangle(248,55,41,41);

	m_oTrackLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
	m_oTrackLayer_TextureState.States[(int)ControlState.Normal] = new ColorValue(1.0f, 1.0f, 1.0f, 0.55f);
	m_oTrackLayer_TextureState.States[(int)ControlState.Focus] = new ColorValue(1.0f, 1.0f, 1.0f, 0.75f);
	m_oTrackLayer_TextureState.States[(int)ControlState.Disabled] = new ColorValue(1.0f, 1.0f, 1.0f, 0.25f);
	m_oTrackLayer_TextureRect = new System.Drawing.Rectangle(1,290,279,41);
}

			ControlState state = ControlState.Normal;
			if (IsVisible == false)
			{
				state = ControlState.Hidden;
			}
			else if (IsEnabled == false)
			{
				state = ControlState.Disabled;
			}
			else if (isPressed)
			{
				state = ControlState.Pressed;
			}
			else if (isMouseOver)
			{
				state = ControlState.MouseOver;
			}
			else if (hasFocus)
			{
				state = ControlState.Focus;
			}

			float blendRate = (state == ControlState.Pressed) ? 0.0f : 0.8f;

			//Element e = elementList[Slider.TrackLayer] as Element;
            
			// Blend current color
			m_oTrackLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( boundingBox,m_oTrackLayer_TextureState,m_oTrackLayer_TextureRect );

			//e = elementList[Slider.ButtonLayer] as Element;
			// Blend current color
			m_oButtonLayer_TextureState.Blend(state, m_fElapsedTime, blendRate);
			m_oMenu.DrawSprite( buttonRect,m_oButtonLayer_TextureState,m_oButtonLayer_TextureRect );
		}
	}
	#endregion

	#region Listbox Control
	/// <summary>Style of the list box</summary>
	public enum ListBoxStyle
	{
		SingleSelection,
		Multiselection,
	}

	/// <summary>Stores data for a list box item</summary>
	public struct ListBoxItem
	{
		public string ItemText;
		public object ItemData;
		public System.Drawing.Rectangle ItemRect;
		public bool IsItemSelected;
	}
	/// <summary>List box control</summary>
	public class DSListBox : DSBaseControl
	{
private string m_sTextureKey = "";
private bool m_bFirstTime = true;

BlendColor m_oMainLayer_TextureState;
BlendColor m_oMainLayer_FontColor;
public System.Drawing.Rectangle m_oMainLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textMainFormat = DrawTextFormat.Left | DrawTextFormat.Top;

BlendColor m_oSelectionLayer_TextureState;
BlendColor m_oSelectionLayer_FontColor;
public System.Drawing.Rectangle m_oSelectionLayer_TextureRect; // Bounding rectangle of this element on the composite texture
public DrawTextFormat textSelectionFormat = DrawTextFormat.Left | DrawTextFormat.Top;

		private float m_fElapsedTime = 0;
		private float m_fAppTime = 0;
		public const int MainLayer = 0;
		public const int SelectionLayer = 1;

		#region Event code
		public event EventHandler ContentsChanged;
		public event EventHandler DoubleClick;
		public event EventHandler Selection;
		/// <summary>Raises the contents changed event</summary>
		protected void RaiseContentsChangedEvent(DSListBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			// Fire the event
			if (ContentsChanged != null)
				ContentsChanged(sender, EventArgs.Empty);
		}
		/// <summary>Raises the double click event</summary>
		protected void RaiseDoubleClickEvent(DSListBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			// Fire the event
			if (DoubleClick != null)
				DoubleClick(sender, EventArgs.Empty);
		}
		/// <summary>Raises the selection event</summary>
		protected void RaiseSelectionEvent(DSListBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			// Fire the event
			if (Selection != null)
				Selection(sender, EventArgs.Empty);
		}
		#endregion

		#region Instance data
		private bool isScrollBarInit;
		protected System.Drawing.Rectangle textRect; // Text rendering bound
		protected System.Drawing.Rectangle selectionRect; // Selection box bound
		protected DSScrollBar scrollbarControl; 
		protected int scrollWidth;
		protected int border;
		protected int margin;
		protected int textHeight; // Height of a single line of text
		protected int selectedIndex;
		protected int selectedStarted;
		protected bool isDragging;
		protected ListBoxStyle style;
 
		protected ArrayList itemList;
		#endregion


		public override void FrameMove( DSMenus oMenus,DSMenu oMenu,float fElapsedTime,float fAppTime )
		{
			const string sRoutineName = "DarkStrideToolbox.Button.FrameMove";

			try
			{
				m_fAppTime = fAppTime;
				m_fElapsedTime = fElapsedTime;

				if( isScrollBarInit == true )
				{
					scrollbarControl.FrameMove( oMenus,oMenu,fElapsedTime,fAppTime );
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}	
		}



		/// <summary>Create new button instance</summary>
		public DSListBox( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			// Store control type and parent dialog
			//controlType = ControlType.ListBox;
			//parentDialog = parent;
			// Create the scrollbar control too
			scrollbarControl = new DSScrollBar( m_oMenus,m_oMenu );

			// Set some default items
			style = ListBoxStyle.SingleSelection;
			scrollWidth = 16;
			selectedIndex = -1;
			selectedStarted = 0;
			isDragging = false;
			margin = 5;
			border = 6;
			textHeight = 0;
			isScrollBarInit = false;

			// Create the item list array
			itemList = new ArrayList();
		}

		/// <summary>Update the rectangles for the list box control</summary>
		protected override void UpdateRectangles()
		{
			// Get bounding box
			base.UpdateRectangles();

			// Calculate the size of the selection rectangle
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			selectionRect = boundingBox;
			selectionRect.Width -= scrollWidth;
			selectionRect.Inflate(-border, -border);
			textRect = selectionRect;
			textRect.Inflate(-margin, 0);

			// Update the scroll bars rects too
			scrollbarControl.SetLocation(boundingBox.Right - scrollWidth, boundingBox.Top);
			scrollbarControl.SetSize(scrollWidth, height);

			//FontNode fNode = DialogResourceManager.GetGlobalInstance().GetFontNode((int)(elementList[0] as Element).FontIndex);
			//if ((fNode != null) && (fNode.Height > 0))
			//{
				scrollbarControl.PageSize = (int)(textRect.Height / (int)DSResourceManager.GetGlobalInstance().m_oFontSize.Y);

				// The selected item may have been scrolled off the page.
				// Ensure that it is in page again.
				scrollbarControl.ShowItem(selectedIndex);
			//}
		}
		/// <summary>Sets the scroll bar width of this control</summary>
		public void SetScrollbarWidth(int width) { scrollWidth = width; UpdateRectangles(); }
		/// <summary>Can this control have focus</summary>
		public override bool CanHaveFocus { get { return (IsVisible && IsEnabled); } }
		/// <summary>Sets the style of the listbox</summary>
		public ListBoxStyle Style { get { return style; } set { style = value; } } 
		/// <summary>Number of items current in the list</summary>
		public int NumberItems { get { return itemList.Count; } }
		/// <summary>Indexer for items in the list</summary>
		public ListBoxItem this[int index]
		{
			get { return (ListBoxItem)itemList[index]; }
		}

		/// <summary>Initialize the scrollbar control here</summary>
		public override void OnInitialize()
		{
			//m_oMenu.InitializeControl();
			scrollbarControl.OnInitialize();
		}


		/// <summary>Called when the control needs to handle the keyboard</summary>
		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if( oKey == Microsoft.DirectX.DirectInput.Key.Up || 
					oKey == Microsoft.DirectX.DirectInput.Key.Down ||
					oKey == Microsoft.DirectX.DirectInput.Key.Next ||
					oKey == Microsoft.DirectX.DirectInput.Key.Prior ||
					oKey == Microsoft.DirectX.DirectInput.Key.Home ||
					oKey == Microsoft.DirectX.DirectInput.Key.End )
				{
					// If no items exists, do nothing
					if (itemList.Count == 0)
						return ;

					int oldSelected = selectedIndex;

					// Adjust selectedIndex
					if( oKey == Microsoft.DirectX.DirectInput.Key.Up ){--selectedIndex;}
					if( oKey == Microsoft.DirectX.DirectInput.Key.Down ){++selectedIndex;}
					if( oKey == Microsoft.DirectX.DirectInput.Key.Next ){selectedIndex += scrollbarControl.PageSize - 1;}
					if( oKey == Microsoft.DirectX.DirectInput.Key.Prior ){selectedIndex -= scrollbarControl.PageSize - 1;}
					if( oKey == Microsoft.DirectX.DirectInput.Key.Home ){selectedIndex = 0;}
					if( oKey == Microsoft.DirectX.DirectInput.Key.End ){selectedIndex = itemList.Count - 1;}

					// Clamp the item
					if (selectedIndex < 0)
						selectedIndex = 0;
					if (selectedIndex >= itemList.Count)
						selectedIndex = itemList.Count - 1;

					// Did the selection change?
					if (oldSelected != selectedIndex)
					{
						if (style == ListBoxStyle.Multiselection)
						{
							// Clear all selection
							for(int i = 0; i < itemList.Count; i++)
							{
								ListBoxItem lbi = (ListBoxItem)itemList[i];
								lbi.IsItemSelected = false;
								itemList[i] = lbi;
							}
//Chris
							// Is shift being held down?
							bool shiftDown = false;
							//((NativeMethods.GetAsyncKeyState((int)System.Windows.Forms.Keys.ShiftKey) & 0x8000) != 0);

							if (shiftDown)
							{
								// Select all items from the start selection to current selected index
								int end = Math.Max(selectedStarted, selectedIndex);
								for(int i = Math.Min(selectedStarted, selectedIndex); i <= end; ++i)
								{
									ListBoxItem lbi = (ListBoxItem)itemList[i];
									lbi.IsItemSelected = true;
									itemList[i] = lbi;
								}
							}
							else
							{
								ListBoxItem lbi = (ListBoxItem)itemList[selectedIndex];
								lbi.IsItemSelected = true;
								itemList[selectedIndex] = lbi;

								// Update selection start
								selectedStarted = selectedIndex;
							}

						}
						else // Update selection start
							selectedStarted = selectedIndex;

						// adjust scrollbar
						scrollbarControl.ShowItem(selectedIndex);
						RaiseSelectionEvent(this, true);
					}
				}

			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		/// <summary>Called when the control should handle the mouse</summary>
		public override void MouseWheelMoved( long nDirection )
		{
			const int ShiftModifier = 0x0004;
			const int ControlModifier = 0x0008;

			if (!IsEnabled || !IsVisible)
				return ; // Nothing to do

			// First acquire focus
			//Chris
			//if (msg == NativeMethods.WindowMessage.LeftButtonDown)
			//	if (!hasFocus)
			//		DSMenu.RequestFocus(this);


			// Let the scroll bar handle it first
			//if (scrollbarControl.HandleMouse(msg, pt, wParam, lParam))
			//return ;


			//case NativeMethods.WindowMessage.MouseWheel:
			//{
			int lines = System.Windows.Forms.SystemInformation.MouseWheelScrollLines;
			//Chris
			int scrollAmount = 1;//(int)(NativeMethods.HiWord((uint)wParam.ToInt32()) / DSMenu.WheelDelta * lines);
			scrollbarControl.Scroll(-scrollAmount);
			//break;
			//}
		}

		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				// Check for clicks in the text area
				if (itemList.Count > 0 && selectionRect.Contains(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y )))
				{
					// Compute the index of the clicked item
					int clicked = 0;
					if (textHeight > 0)
						clicked = scrollbarControl.TrackPosition + ((int)vMousePosInControlSpace.Y - textRect.Top) / textHeight;
					else
						clicked = -1;

					// Only proceed if the click falls ontop of an item
					if (clicked >= scrollbarControl.TrackPosition &&
						clicked < itemList.Count &&
						clicked < scrollbarControl.TrackPosition + scrollbarControl.PageSize )
					{
						//NativeMethods.SetCapture(Parent.SampleFramework.Window);
						isDragging = true;

						//Chris
						// If this is a double click, fire off an event and exit
						// since the first click would have taken care of the selection
						// updating.
						//if (msg == NativeMethods.WindowMessage.LeftButtonDoubleClick)
						//{
						//	RaiseDoubleClickEvent(this, true);
						//	return ;
						//}

						selectedIndex = clicked;
						//Chris
						//if ( (wParam.ToInt32() & ShiftModifier) == 0)
						//	selectedStarted = selectedIndex; // Shift isn't down

						// If this is a multi-selection listbox, update per-item
						// selection data.
						if (style == ListBoxStyle.Multiselection)
						{
							// Determine behavior based on the state of Shift and Ctrl
							ListBoxItem selectedItem = (ListBoxItem)itemList[selectedIndex];
							//Chris
							/*if ((wParam.ToInt32() & (ShiftModifier | ControlModifier)) == ControlModifier)
							{
								// Control click, reverse the selection
								selectedItem.IsItemSelected = !selectedItem.IsItemSelected;
								itemList[selectedIndex] = selectedItem;
							}
							else if ((wParam.ToInt32() & (ShiftModifier | ControlModifier)) == ShiftModifier)
							{
								// Shift click. Set the selection for all items
								// from last selected item to the current item.
								// Clear everything else.
								int begin = Math.Min(selectedStarted, selectedIndex);
								int end = Math.Max(selectedStarted, selectedIndex);
							
								// Unselect everthing before the beginning
								for(int i = 0; i < begin; ++i)
								{
									ListBoxItem lb = (ListBoxItem)itemList[i];
									lb.IsItemSelected = false;
									itemList[i] = lb;
								}
								// unselect everything after the end
								for(int i = end + 1; i < itemList.Count; ++i)
								{
									ListBoxItem lb = (ListBoxItem)itemList[i];
									lb.IsItemSelected = false;
									itemList[i] = lb;
								}
							
								// Select everything between
								for(int i = begin; i <= end; ++i)
								{
									ListBoxItem lb = (ListBoxItem)itemList[i];
									lb.IsItemSelected = true;
									itemList[i] = lb;
								}
							}
							else if ((wParam.ToInt32() & (ShiftModifier | ControlModifier)) == (ShiftModifier | ControlModifier))
							{
								// Control-Shift-click.

								// The behavior is:
								//   Set all items from selectedStarted to selectedIndex to
								//     the same state as selectedStarted, not including selectedIndex.
								//   Set selectedIndex to selected.
								int begin = Math.Min(selectedStarted, selectedIndex);
								int end = Math.Max(selectedStarted, selectedIndex);

								// The two ends do not need to be set here.
								bool isLastSelected = ((ListBoxItem)itemList[selectedStarted]).IsItemSelected;

								for (int i = begin + 1; i < end; ++i)
								{
									ListBoxItem lb = (ListBoxItem)itemList[i];
									lb.IsItemSelected = isLastSelected;
									itemList[i] = lb;
								}

								selectedItem.IsItemSelected = true;
								itemList[selectedIndex] = selectedItem;

								// Restore selectedIndex to the previous value
								// This matches the Windows behavior

								selectedIndex = selectedStarted;
							}
							else
							{
								// Simple click.  Clear all items and select the clicked
								// item.
								for(int i = 0; i < itemList.Count; ++i)
								{
									ListBoxItem lb = (ListBoxItem)itemList[i];
									lb.IsItemSelected = false;
									itemList[i] = lb;
								}
								selectedItem.IsItemSelected = true;
								itemList[selectedIndex] = selectedItem;
							}*/
						} // End of multi-selection case
						RaiseSelectionEvent(this, true);
					}
					return ;
				}

			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				isDragging = false;

				if (selectedIndex != -1)
				{
					// Set all items between selectedStarted and selectedIndex to
					// the same state as selectedStarted
					int end = Math.Max(selectedStarted, selectedIndex);
					for (int i = Math.Min(selectedStarted, selectedIndex) + 1; i < end; ++i)
					{
						ListBoxItem lb = (ListBoxItem)itemList[i];
						lb.IsItemSelected = ((ListBoxItem)itemList[selectedStarted]).IsItemSelected;
						itemList[i] = lb;
					}
					ListBoxItem lbs = (ListBoxItem)itemList[selectedIndex];
					lbs.IsItemSelected = ((ListBoxItem)itemList[selectedStarted]).IsItemSelected;
					itemList[selectedIndex] = lbs;

					// If selectedStarted and selectedIndex are not the same,
					// the user has dragged the mouse to make a selection.
					// Notify the application of this.
					if (selectedIndex != selectedStarted)
						RaiseSelectionEvent(this, true);
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isDragging)
				{
					// compute the index of the item below the cursor
					int itemIndex = -1;
					if (textHeight > 0)
						itemIndex = scrollbarControl.TrackPosition + ((int)vMousePosInMenuSpace.Y - textRect.Top) / textHeight;

					// Only proceed if the cursor is on top of an item
					if (itemIndex >= scrollbarControl.TrackPosition &&
						itemIndex < itemList.Count &&
						itemIndex < scrollbarControl.TrackPosition + scrollbarControl.PageSize)
					{
						selectedIndex = itemIndex;
						RaiseSelectionEvent(this, true);
					}
					else if (itemIndex < scrollbarControl.TrackPosition)
					{
						// User drags the mouse above window top
						scrollbarControl.Scroll(-1);
						selectedIndex = scrollbarControl.TrackPosition;
						RaiseSelectionEvent(this, true);
					}
					else if (itemIndex >= scrollbarControl.TrackPosition + scrollbarControl.PageSize)
					{
						// User drags the mouse below the window bottom
						scrollbarControl.Scroll(1);
						selectedIndex = Math.Min(itemList.Count, scrollbarControl.TrackPosition + scrollbarControl.PageSize - 1);
						RaiseSelectionEvent(this, true);
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}


		/// <summary>Called when the control should be rendered</summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			if (!IsVisible)
				return; // Nothing to render
            
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );


if( m_bFirstTime == true )
{
	m_bFirstTime = false;
	m_sTextureKey = "0";

	m_oMainLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oMainLayer_TextureRect = new System.Drawing.Rectangle(13,124,228,141);	
	m_oMainLayer_FontColor.Initialize( DSMenu.BlackColorValue );

	m_oSelectionLayer_TextureState.Initialize( DSMenu.WhiteColorValue );
	m_oSelectionLayer_TextureRect = new System.Drawing.Rectangle(17,269,224,18);
	m_oSelectionLayer_FontColor.Initialize( DSMenu.WhiteColorValue );
}

			//Element e = elementList[ListBox.MainLayer] as Element;

			// Blend current color
			m_oMainLayer_TextureState.Blend(ControlState.Normal, m_fElapsedTime);
			m_oMainLayer_FontColor.Blend(ControlState.Normal, m_fElapsedTime);
            
			//Element selectedElement = elementList[ListBox.SelectionLayer] as Element;

			// Blend current color
			m_oSelectionLayer_TextureState.Blend(ControlState.Normal, m_fElapsedTime);
			m_oSelectionLayer_FontColor.Blend(ControlState.Normal, m_fElapsedTime);

			m_oMenu.DrawSprite( boundingBox,m_oMainLayer_TextureState,m_oMainLayer_TextureRect );

			// Render the text
			if (itemList.Count > 0)
			{
				// Find out the height of a single line of text
				System.Drawing.Rectangle rc = textRect;
				System.Drawing.Rectangle sel = selectionRect;
				int nFontSize = (int)( DSResourceManager.GetGlobalInstance().m_oFontSize.Y );
				rc.Height = nFontSize;//(int)(DialogResourceManager.GetGlobalInstance().GetFontNode((int)e.FontIndex).Height);
				textHeight = rc.Height;

				// If we have not initialized the scroll bar page size,
				// do that now.
				if (!isScrollBarInit)
				{
					if (textHeight > 0)
						scrollbarControl.PageSize = (int)(textRect.Height / textHeight);
					else
						scrollbarControl.PageSize = textRect.Height;

					isScrollBarInit = true;
				}
				rc.Width = textRect.Width;
				for (int i = scrollbarControl.TrackPosition; i < itemList.Count; ++i)
				{
					if (rc.Bottom > textRect.Bottom)
						break;

					ListBoxItem lb = (ListBoxItem)itemList[i];

					// Determine if we need to render this item with the
					// selected element.
					bool isSelectedStyle = false;

					if ( (selectedIndex == i) && (style == ListBoxStyle.SingleSelection) )
						isSelectedStyle = true;
					else if (style == ListBoxStyle.Multiselection)
					{
						if (isDragging && ( ( i >= selectedIndex && i < selectedStarted) || 
							(i <= selectedIndex && i > selectedStarted) ) )
						{
							ListBoxItem selStart = (ListBoxItem)itemList[selectedStarted];
							isSelectedStyle = selStart.IsItemSelected;
						}
						else
							isSelectedStyle = lb.IsItemSelected;
					}

					// Now render the text
					if (isSelectedStyle)
					{
						sel.Location = new System.Drawing.Point(sel.Left, rc.Top); 
						sel.Height = rc.Height;
						m_oMenu.DrawSprite( sel,m_oSelectionLayer_TextureState,m_oSelectionLayer_TextureRect );
						m_oMenu.DrawText(lb.ItemText,  rc,m_oSelectionLayer_FontColor ,textSelectionFormat );
					}
					else
						m_oMenu.DrawText(lb.ItemText, rc,m_oMainLayer_FontColor, textMainFormat );

					rc.Offset(0, textHeight);
				}
			}

			// Render the scrollbar finally
			scrollbarControl.Render( m_oMenus,m_oMenu );
		}

        
		#region Item Controlling methods
		/// <summary>Adds an item to the list box control</summary>
		public void AddItem(string text, object data)
		{
			if ((text == null) || (text.Length == 0))
				throw new ArgumentNullException("text", "You must pass in a valid item name when adding a new item.");

			// Create a new item and add it
			ListBoxItem newitem = new ListBoxItem();
			newitem.ItemText = text;
			newitem.ItemData = data;
			newitem.IsItemSelected = false;
			itemList.Add(newitem);

			// Update the scrollbar with the new range
			scrollbarControl.SetTrackRange(0, itemList.Count);
		}
		/// <summary>Inserts an item to the list box control</summary>
		public void InsertItem(int index, string text, object data)
		{
			if ((text == null) || (text.Length == 0))
				throw new ArgumentNullException("text", "You must pass in a valid item name when adding a new item.");

			// Create a new item and insert it
			ListBoxItem newitem = new ListBoxItem();
			newitem.ItemText = text;
			newitem.ItemData = data;
			newitem.IsItemSelected = false;
			itemList.Insert(index, newitem);

			// Update the scrollbar with the new range
			scrollbarControl.SetTrackRange(0, itemList.Count);
		}

		/// <summary>Removes an item at a particular index</summary>
		public void RemoveAt(int index)
		{
			// Remove the item
			itemList.RemoveAt(index);

			// Update the scrollbar with the new range
			scrollbarControl.SetTrackRange(0, itemList.Count);

			if (selectedIndex >= itemList.Count)
				selectedIndex = itemList.Count - 1;

			RaiseSelectionEvent(this, true);
		}

		/// <summary>Removes all items from the control</summary>
		public void Clear()
		{
			// clear the list
			itemList.Clear();

			// Update scroll bar and index
			scrollbarControl.SetTrackRange(0, 1);
			selectedIndex = -1;
		}

		/// <summary>
		/// For single-selection listbox, returns the index of the selected item.
		/// For multi-selection, returns the first selected item after the previousSelected position.
		/// To search for the first selected item, the app passes -1 for previousSelected.  For
		/// subsequent searches, the app passes the returned index back to GetSelectedIndex as.
		/// previousSelected.
		/// Returns -1 on error or if no item is selected.
		/// </summary>
		public int GetSelectedIndex(int previousSelected)
		{
			if (previousSelected < -1)
				return -1;

			if (style == ListBoxStyle.Multiselection)
			{
				// Multiple selections enabled.  Search for the next item with the selected flag
				for (int i = previousSelected + 1; i < itemList.Count; ++i)
				{
					ListBoxItem lbi = (ListBoxItem)itemList[i];
					if (lbi.IsItemSelected)
						return i;
				}

				return -1;
			}
			else
			{
				// Single selection
				return selectedIndex;
			}
		}
		/// <summary>Gets the selected item</summary>
		public ListBoxItem GetSelectedItem(int previousSelected)
		{
			return (ListBoxItem)itemList[GetSelectedIndex(previousSelected)];
		}
		/// <summary>Gets the selected item</summary>
		public ListBoxItem GetSelectedItem() { return GetSelectedItem(-1); }

		/// <summary>Sets the border and margin sizes</summary>
		public void SetBorder(int borderSize, int marginSize)
		{
			border = borderSize;
			margin = marginSize;
			UpdateRectangles();
		}

		/// <summary>Selects this item</summary>
		public void SelectItem(int newIndex)
		{
			if (itemList.Count == 0)
				return; // If no items exist there's nothing to do

			int oldSelected = selectedIndex;

			// Select the new item
			selectedIndex = newIndex;

			// Clamp the item
			if (selectedIndex < 0)
				selectedIndex = 0;
			if (selectedIndex > itemList.Count)
				selectedIndex = itemList.Count - 1;

			// Did the selection change?
			if (oldSelected != selectedIndex)
			{
				if (style == ListBoxStyle.Multiselection)
				{
					ListBoxItem lbi = (ListBoxItem)itemList[selectedIndex];
					lbi.IsItemSelected = true;
					itemList[selectedIndex] = lbi;
				}

				// Update selection start
				selectedStarted = selectedIndex;

				// adjust scrollbar
				scrollbarControl.ShowItem(selectedIndex);
			}
			RaiseSelectionEvent(this, true);
		}
		#endregion
	}
	#endregion

	#region EditBox
	/// <summary>A basic edit box</summary>
	public class DSEditBox : DSBaseControl
	{
bool m_bFirstTime = true;
public string m_sTextureKey = "0";

BlendColor m_oMainLayer_FontColor;
public DrawTextFormat textMainFormat = DrawTextFormat.Center | DrawTextFormat.VerticalCenter;

BlendColor[] m_oTextureState = new BlendColor[ 8 ];
public System.Drawing.Rectangle[] m_oTextureRect = new System.Drawing.Rectangle[ 8 ]; // Bounding rectangle of this element on the composite texture

		#region Element layers
		public const int TextLayer = 0;
		public const int TopLeftBorder = 1;
		public const int TopBorder = 2;
		public const int TopRightBorder = 3;
		public const int LeftBorder = 4;
		public const int RightBorder = 5;
		public const int LowerLeftBorder = 6;
		public const int LowerBorder = 7;
		public const int LowerRightBorder = 8;
		#endregion

		private float m_fElapsedTime = 0;
		#region Event code
		public event EventHandler Changed;
		public event EventHandler Enter;
		/// <summary>Raises the changed event</summary>
		protected void RaiseChangedEvent(DSEditBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			if (Changed != null)
				Changed(sender, EventArgs.Empty);
		}
		/// <summary>Raises the Enter event</summary>
		protected void RaiseEnterEvent(DSEditBox sender, bool wasTriggeredByUser)
		{
			// Discard events triggered programatically if these types of events haven't been
			// enabled
			if ( !wasTriggeredByUser)
				return;

			if (Enter != null)
				Enter(sender, EventArgs.Empty);
		}
		#endregion

		#region Class Data
		protected System.Windows.Forms.RichTextBox textData; // Text data
		protected int border; // Border of the window
		protected int spacing; // Spacing between the text and the edge of border
		protected System.Drawing.Rectangle textRect; // Bounding rectangle for the text
		protected System.Drawing.Rectangle[] elementRects = new System.Drawing.Rectangle[9];
		protected double blinkTime; // Caret blink time in milliseconds
		protected double lastBlink; // Last timestamp of caret blink
		protected bool isCaretOn; // Flag to indicate whether caret is currently visible
		protected int caretPosition; // Caret position, in characters
		protected bool isInsertMode; // If true, control is in insert mode. Else, overwrite mode.
		protected int firstVisible;  // First visible character in the edit control
		protected ColorValue textColor; // Text color
		protected ColorValue selectedTextColor; // Selected Text color
		protected ColorValue selectedBackColor; // Selected background color
		protected ColorValue caretColor; // Caret color

		// Mouse-specific
		protected bool isMouseDragging; // True to indicate the drag is in progress

		protected static bool isHidingCaret; // If true, we don't render the caret.
        
		#endregion

		#region Simple overrides/properties/methods
		/// <summary>Can the edit box have focus</summary>
		/*public override bool CanHaveFocus { get { return (IsVisible && IsEnabled); } }*/
		/// <summary>Update the spacing</summary>
		public void SetSpacing(int space) { spacing = space; UpdateRectangles(); }
		/// <summary>Update the border</summary>
		public void SetBorderWidth(int b) { border = b; UpdateRectangles(); }
		/// <summary>Update the text color</summary>
		public void SetTextColor(ColorValue color) { textColor = color; }
		/// <summary>Update the text selected color</summary>
		public void SetSelectedTextColor(ColorValue color) { selectedTextColor = color; }
		/// <summary>Update the selected background color</summary>
		public void SetSelectedBackColor(ColorValue color) { selectedBackColor = color; }
		/// <summary>Update the caret color</summary>
		public void SetCaretColor(ColorValue color) { caretColor = color; }

		/// <summary>Get or sets the text</summary>
		public string Text { get { return textData.Text; } set { SetText(value, false); } }
		/// <summary>Gets a copy of the text</summary>
		public string GetCopyText() { return textData.Text.Clone() as string; }
		#endregion

		/// <summary>Creates a new edit box control</summary>
		public DSEditBox( DSMenus oMenus,DSMenu oMenu ) : base( oMenus,oMenu )
		{
			//controlType = ControlType.EditBox;
			//parentDialog = parent;

			border = 5; // Default border
			spacing = 4; // default spacing
			isCaretOn = true;

			textData = new System.Windows.Forms.RichTextBox();
			// Create the control
			textData.Visible = true;
			textData.Font = new System.Drawing.Font("Arial", 8.0f);
			textData.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
			textData.Multiline = false;
			textData.Text = string.Empty;
			textData.MaxLength = ushort.MaxValue; // 65k characters should be plenty
			textData.WordWrap = false;
			// Now create the control
			textData.CreateControl();

			isHidingCaret = false;
			firstVisible = 0;
			blinkTime = .53f;//NativeMethods.GetCaretBlinkTime() * 0.001f;
			lastBlink = 0;//FrameworkTimer.GetAbsoluteTime();
			textColor = new ColorValue(0.06f, 0.06f, 0.06f, 1.0f);
			selectedTextColor = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f);
			selectedBackColor = new ColorValue(0.15f, 0.196f, 0.36f, 1.0f);
			caretColor = new ColorValue(0, 0, 0, 1.0f);
			caretPosition = textData.SelectionStart = 0;
			isInsertMode = true;
			isMouseDragging = false;
		}

		/// <summary>Set the caret to a character position, and adjust the scrolling if necessary</summary>
		protected void PlaceCaret(int pos)
		{
			// Store caret position
			caretPosition = pos;

			// First find the first visible char
			for (int i = 0; i < textData.Text.Length; i++)
			{
				System.Drawing.Point p = textData.GetPositionFromCharIndex(i);
				if (p.X >= 0) 
				{
					firstVisible = i; // This is the first visible character
					break;
				}
			}

			// if the new position is smaller than the first visible char 
			// we'll need to scroll
			if (firstVisible > caretPosition)
				firstVisible = caretPosition;
		}

		/// <summary>Clears the edit box</summary>
		public void Clear()
		{
			textData.Text = string.Empty;
			PlaceCaret(0);
			textData.SelectionStart = 0;
		}
		/// <summary>Sets the text for the control</summary>
		public void SetText(string text, bool selected)
		{
			if (text == null)
				text = string.Empty;

			textData.Text = text;
			textData.SelectionStart = text.Length;
			// Move the care to the end of the text
			PlaceCaret(text.Length);
			textData.SelectionStart = (selected) ? 0 : caretPosition;
			FocusText();
		}
		/// <summary>Deletes the text that is currently selected</summary>
		protected void DeleteSelectionText()
		{
			int first = Math.Min(caretPosition, textData.SelectionStart);
			int last = Math.Max(caretPosition, textData.SelectionStart);
			// Update caret and selection
			PlaceCaret(first);
			// Remove the characters
			textData.Text = textData.Text.Remove(first, (last-first));
			textData.SelectionStart = caretPosition;
			FocusText();
		}
		/// <summary>Updates the rectangles used by the control</summary>
		protected override void UpdateRectangles()
		{
			// Get the bounding box first
			base.UpdateRectangles ();

			// Update text rect
			Rectangle boundingBox = new Rectangle( (int)this.Pos.X,(int)this.Pos.Y,(int)this.Size.X,(int)this.Size.Y );
			textRect = boundingBox;
			// First inflate by border to compute render rects
			textRect.Inflate(-border, -border);
            
			// Update the render rectangles
			elementRects[0] = textRect;
			elementRects[1] = new System.Drawing.Rectangle(boundingBox.Left, boundingBox.Top, (textRect.Left - boundingBox.Left), (textRect.Top - boundingBox.Top));
			elementRects[2] = new System.Drawing.Rectangle(textRect.Left, boundingBox.Top, textRect.Width, (textRect.Top - boundingBox.Top));
			elementRects[3] = new System.Drawing.Rectangle(textRect.Right, boundingBox.Top, (boundingBox.Right - textRect.Right), (textRect.Top - boundingBox.Top));
			elementRects[4] = new System.Drawing.Rectangle(boundingBox.Left, textRect.Top, (textRect.Left - boundingBox.Left), textRect.Height);
			elementRects[5] = new System.Drawing.Rectangle(textRect.Right, textRect.Top, (boundingBox.Right - textRect.Right), textRect.Height);
			elementRects[6] = new System.Drawing.Rectangle(boundingBox.Left, textRect.Bottom, (textRect.Left - boundingBox.Left), (boundingBox.Bottom - textRect.Bottom));
			elementRects[7] = new System.Drawing.Rectangle(textRect.Left, textRect.Bottom, textRect.Width, (boundingBox.Bottom - textRect.Bottom));
			elementRects[8] = new System.Drawing.Rectangle(textRect.Right, textRect.Bottom, (boundingBox.Right - textRect.Right), (boundingBox.Bottom - textRect.Bottom));            

			// Inflate further by spacing
			textRect.Inflate(-spacing, -spacing);

			// Make the underlying rich text box the same size
			textData.Size = textRect.Size;
		}

		/// <summary>Copy the selected text to the clipboard</summary>
		protected void CopyToClipboard()
		{
			// Copy the selection text to the clipboard
			if (caretPosition != textData.SelectionStart)
			{
				int first = Math.Min(caretPosition, textData.SelectionStart);
				int last = Math.Max(caretPosition, textData.SelectionStart);
				// Set the text to the clipboard
				System.Windows.Forms.Clipboard.SetDataObject(textData.Text.Substring(first, (last-first)));
			}

		}
		/// <summary>Paste the clipboard data to the control</summary>
		protected void PasteFromClipboard()
		{
			// Get the clipboard data
			System.Windows.Forms.IDataObject clipData = System.Windows.Forms.Clipboard.GetDataObject();
			// Does the clipboard have string data?
			if (clipData.GetDataPresent(System.Windows.Forms.DataFormats.StringFormat))
			{
				// Yes, get that data
				string clipString = clipData.GetData(System.Windows.Forms.DataFormats.StringFormat) as string;
				// find any new lines, remove everything after that
				int index;
				if ((index = clipString.IndexOf("\n")) > 0)
				{
					clipString = clipString.Substring(0, index-1);
				}

				// Insert that into the text data
				textData.Text = textData.Text.Insert(caretPosition, clipString);
				caretPosition += clipString.Length;
				textData.SelectionStart = caretPosition;
				FocusText();
			}
		}
		/// <summary>Reset's the caret blink time</summary>
		protected void ResetCaretBlink()
		{
			isCaretOn = true;
			lastBlink = FrameworkTimer.GetAbsoluteTime();
		}

		/// <summary>Update the caret when focus is in</summary>
		public override void OnFocusIn()
		{
			base.OnFocusIn();
			ResetCaretBlink();
		}

		/// <summary>Updates focus to the backing rich textbox so it updates it's state</summary>
		private void FocusText()
		{
			// Because of a design issue with the rich text box control that is used as 
			// the backing store for this control, the 'scrolling' mechanism built into
			// the control will only work if the control has focus.  Setting focus to the 
			// control here would work, but would cause a bad 'flicker' of the application.

			// Therefore, the automatic horizontal scrolling is turned off by default.  To 
			// enable it turn this define on.
#if (SCROLL_CORRECTLY)
            NativeMethods.SetFocus(textData.Handle);
            NativeMethods.SetFocus(Parent.SampleFramework.Window);
#endif
		}



		/// <summary>Handle keyboard input to the edit box</summary>
		public override void KeyboardKeyDown( Key oKey,bool[] oState )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.KeyboardKeyDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				
				
					bool isHandled = false;

				if( oKey == Microsoft.DirectX.DirectInput.Key.End ||
					oKey == Microsoft.DirectX.DirectInput.Key.Home )
				{
					// Move the caret
					if( oKey == Microsoft.DirectX.DirectInput.Keys.End)
					{
						PlaceCaret(textData.Text.Length);
					}
					else
					{
						PlaceCaret(0);
					}
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == false &&
						oState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == false )
					{
						// Shift is not down. Update selection start along with caret
						textData.SelectionStart = caretPosition;
						FocusText();
					}

					ResetCaretBlink();
					isHandled = true;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Insert )
				{
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true ||
					    oState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true )
					{
						// Control insert -> Copy to clipboard
						CopyToClipboard();
					}
					else if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == false &&
							 oState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == false )
					{
						// Shift insert -> Paste from clipboard
						PasteFromClipboard();
					}
					else
					{
						// Toggle insert mode
						isInsertMode = !isInsertMode;
					}
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Delete )
				{
					// Check to see if there is a text selection
					if (caretPosition != textData.SelectionStart)
					{
						DeleteSelectionText();
						RaiseChangedEvent(this, true);
					}
					else
					{
						if (caretPosition < textData.Text.Length)
						{
							// Deleting one character
							textData.Text = textData.Text.Remove(caretPosition, 1);
							RaiseChangedEvent(this, true);
						}
					}
					ResetCaretBlink();
					isHandled = true;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Left )
				{
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true ||
					    oState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true )
					{
						// Control is down. Move the caret to a new item instead of a character.
					}
					else if (caretPosition > 0)
						PlaceCaret(caretPosition - 1); // Move one to the left

					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == false &&
					    oState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == false )
					{
						// Shift is not down. Update selection
						// start along with the caret.
						textData.SelectionStart = caretPosition;
						FocusText();
					}
					ResetCaretBlink();
					isHandled = true;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Right )
				{
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftControl ] == true ||
						oState[ (int)Microsoft.DirectX.DirectInput.Key.RightControl ] == true )
					{
						// Control is down. Move the caret to a new item
						// instead of a character.
					}
					else if (caretPosition < textData.Text.Length)
					{
						PlaceCaret(caretPosition + 1); // Move one to the left
					}
					if( oState[ (int)Microsoft.DirectX.DirectInput.Key.LeftShift ] == false &&
						oState[ (int)Microsoft.DirectX.DirectInput.Key.RightShift ] == false )
					{
						// Shift is not down. Update selection
						// start along with the caret.
						textData.SelectionStart = caretPosition;
						FocusText();
					}
					ResetCaretBlink();
					isHandled = true;
				}
				else if( oKey == Microsoft.DirectX.DirectInput.Key.Up ||
					     oKey == Microsoft.DirectX.DirectInput.Key.Down )
				{
					// Trap up and down arrows so that the dialog  does not switch focus to another control.
					isHandled = true;
				}
				else
				{				
					// Let the application handle escape
					//isHandled = ((System.Windows.Forms.Keys)wParam.ToInt32()) == System.Windows.Forms.Keys.Escape;

					if( oKey == Microsoft.DirectX.DirectInput.Key.Back )
					{
						// If there's a selection, treat this like a delete key.
						if (caretPosition != textData.SelectionStart)
						{
							DeleteSelectionText();
							RaiseChangedEvent(this, true);
						}
						else if (caretPosition > 0)
						{
							// Move the caret and delete the char
							textData.Text = textData.Text.Remove(caretPosition - 1, 1);
							PlaceCaret(caretPosition - 1);
							textData.SelectionStart = caretPosition;
							FocusText();
							RaiseChangedEvent(this, true);
						}

						ResetCaretBlink();
					}
					/*case 24: // Ctrl-X Cut
					case (int)System.Windows.Forms.Keys.Cancel: // Ctrl-C Copy
					{
						CopyToClipboard();

						// If the key is Ctrl-X, delete the selection too.
						if (charKey == 24)
						{
							DeleteSelectionText();
							RaiseChangedEvent(this, true);
						}

						break;
					}*/
					// Ctrl-V Paste
					/*case 22:
					{
						PasteFromClipboard();
						RaiseChangedEvent(this, true);
						break;
					}*/
					if( oKey == Microsoft.DirectX.DirectInput.Key.Return )
					{						
						// Invoke the event when the user presses Enter.
						RaiseEnterEvent(this, true);
					}
					// Ctrl-A Select All
					/*case 1:
					{
						if (textData.SelectionStart == caretPosition)
						{
							textData.SelectionStart = 0;
							PlaceCaret(textData.Text.Length);
						}
						break;
					}*/
					else
					{
						// If there's a selection and the user starts to type, the selection should
						// be deleted.
						if (caretPosition != textData.SelectionStart)
						{
							DeleteSelectionText();
						}
						// If we are in overwrite mode and there is already a char at the caret's position, simply replace it.
						// Otherwise, we insert the char as normal.
						if (!isInsertMode && caretPosition < textData.Text.Length)
						{
							// This isn't the most efficient way to do this, but it's simple
							// and shows the correct behavior
							char[] charData = textData.Text.ToCharArray();
							charData[caretPosition] = Convert.ToChar( DSMisc.KeyToChar( oKey,oState ) );// (char)wParam.ToInt32();
							textData.Text = new string(charData);
						}
						else
						{
							// Insert the char
							//char c = (char);//(char)wParam.ToInt32();
							textData.Text = textData.Text.Insert(caretPosition, DSMisc.KeyToChar( oKey,oState ));
						}

						// Move the caret and selection position now
						PlaceCaret(caretPosition + 1);
						textData.SelectionStart = caretPosition;
						FocusText();

						ResetCaretBlink();
						RaiseChangedEvent(this, true);
					}
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		/// <summary>Handle mouse messages</summary>
		public override void MouseUp( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				isPressed = false;
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseMoved( Vector2 vMousePosInMenuSpace,bool[] baButtons )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseUp";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				if (isMouseDragging)
				{
					// Determine the character corresponding to the coordinates
					int dragIndex = textData.GetCharIndexFromPosition(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y ));

					if (dragIndex < textData.Text.Length)
						PlaceCaret(dragIndex + 1);
					else
						PlaceCaret(dragIndex);
				}
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}

		public override void MouseDown( Vector2 vMousePosInControlSpace,long nButton )
		{
			const string sRoutineName = "DarkStrideToolbox.ButtonControl.MouseDown";

			try
			{
				if (!IsEnabled || !IsVisible)
					return;

				// We need a new point
				System.Drawing.Point p = new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y );
				p.X -= textRect.Left;
				p.Y -= textRect.Top;

				// Get focus first
				if (!hasFocus)
					DSMenu.RequestFocus(this);

				if (!ContainsPoint(new Point((int)vMousePosInControlSpace.X,(int)vMousePosInControlSpace.Y )))
					return ;

				isMouseDragging = true;
				NativeMethods.SetCapture(Parent.SampleFramework.Window);
				// Determine the character corresponding to the coordinates
				int index = textData.GetCharIndexFromPosition(p);

				System.Drawing.Point startPosition = textData.GetPositionFromCharIndex(index);

				if (p.X > startPosition.X && index < textData.Text.Length)
					PlaceCaret(index + 1);
				else
					PlaceCaret(index);
                    
				textData.SelectionStart = caretPosition;
				FocusText();
				ResetCaretBlink();
			}
			catch( System.Exception oEx )
			{
				throw new System.Exception( sRoutineName + " Failed.",oEx );
			}
		}



		/// <summary>Render the control</summary>
		public override void Render(DSMenus oMenus,DSMenu oMenu)
		{
			if (!IsVisible)
				return; // Nothing to render

if( m_bFirstTime == true )
{
	m_bFirstTime = false;

BlendColor m_oMainLayer_FontColor;
public DrawTextFormat textMainFormat = DrawTextFormat.Center | DrawTextFormat.VerticalCenter;

BlendColor[] m_oTextureState = new BlendColor[ 8 ];
public System.Drawing.Rectangle[] m_oTextureRect = new System.Drawing.Rectangle[ 8 ]; // Bounding rectangle of this element on the composite texture

Populate the layers
//		m_oMainLayer_TextureState.Initialize(DSMenu.WhiteColorValue);
//		m_oMainLayer_TextureRect = new System.Drawing.Rectangle(7,81, 240, 42);
//		m_oMainLayer_FontColor.Initialize( DSMenu.WhiteColorValue );

}

/*			//-------------------------------------
			// EditBox
			//-------------------------------------
			// Element assignment:
			//   0 - text area
			//   1 - top left border
			//   2 - top border
			//   3 - top right border
			//   4 - left border
			//   5 - right border
			//   6 - lower left border
			//   7 - lower border
			//   8 - lower right border
			e.SetFont(0, BlackColorValue, DrawTextFormat.Left | DrawTextFormat.Top);
            
			// Assign the styles
			e.SetTexture(0, new System.Drawing.Rectangle(14,90,227,23));
			SetDefaultElement(ControlType.EditBox, EditBox.TextLayer, e);
			e.SetTexture(0, new System.Drawing.Rectangle(8,82,6,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopLeftBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(14,82,227,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(241,82,5,8));
			SetDefaultElement(ControlType.EditBox, EditBox.TopRightBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(8,90,6,23));
			SetDefaultElement(ControlType.EditBox, EditBox.LeftBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(241,90,5,23));
			SetDefaultElement(ControlType.EditBox, EditBox.RightBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(8,113,6,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerLeftBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(14,113,227,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerBorder, e);
			e.SetTexture(0, new System.Drawing.Rectangle(241,113,5,8));
			SetDefaultElement(ControlType.EditBox, EditBox.LowerRightBorder, e);
*/

			// Render the control graphics
			for (int i = 0; i <= LowerRightBorder; ++i)
			{
				Element e = elementList[i] as Element;
				e.TextureColor.Blend(ControlState.Normal,m_fElapsedTime);
				parentDialog.DrawSprite(e, elementRects[i],e.TextureColor,e.textureRect );
			}
			//
			// Compute the X coordinates of the first visible character.
			//
			int xFirst = textData.GetPositionFromCharIndex(firstVisible).X;
			int xCaret = textData.GetPositionFromCharIndex(caretPosition).X;
			int xSel;

			if (caretPosition != textData.SelectionStart)
				xSel = textData.GetPositionFromCharIndex(textData.SelectionStart).X;
			else
				xSel = xCaret;

			// Render the selection rectangle
			System.Drawing.Rectangle selRect = System.Drawing.Rectangle.Empty;
			if (caretPosition != textData.SelectionStart)
			{
				int selLeft = xCaret, selRight = xSel;
				// Swap if left is beigger than right
				if (selLeft > selRight)
				{
					int temp = selLeft;
					selLeft = selRight;
					selRight = temp;
				}
				selRect = System.Drawing.Rectangle.FromLTRB(
					selLeft, textRect.Top, selRight, textRect.Bottom);
				selRect.Offset(textRect.Left - xFirst, 0);
				selRect.Intersect(textRect);
				Parent.DrawRectangle(selRect, selectedBackColor);
			}

			// Render the text
			Element textElement = elementList[TextLayer] as Element;
			textElement.FontColor.Current = textColor;
			parentDialog.DrawText(textData.Text.Substring(firstVisible), textElement, textRect,textElement.FontColor,textElement.textFormat );
            
			// Render the selected text
			if (caretPosition != textData.SelectionStart)
			{
				int firstToRender = Math.Max(firstVisible, Math.Min(textData.SelectionStart, caretPosition));
				int numToRender = Math.Max(textData.SelectionStart, caretPosition) - firstToRender;
				textElement.FontColor.Current = selectedTextColor;
				parentDialog.DrawText(textData.Text.Substring(firstToRender, numToRender), textElement, selRect,textElement.FontColor,textElement.textFormat );
			}

			//
			// Blink the caret
			//
			if(FrameworkTimer.GetAbsoluteTime() - lastBlink >= blinkTime)
			{
				isCaretOn = !isCaretOn;
				lastBlink = FrameworkTimer.GetAbsoluteTime();
			}

			//
			// Render the caret if this control has the focus
			//
			if( hasFocus && isCaretOn && !isHidingCaret )
			{
				// Start the rectangle with insert mode caret
				System.Drawing.Rectangle caretRect = textRect;
				caretRect.Width = 2;
				caretRect.Location = new System.Drawing.Point(
					caretRect.Left - xFirst + xCaret -1, 
					caretRect.Top);
                
				// If we are in overwrite mode, adjust the caret rectangle
				// to fill the entire character.
				if (!isInsertMode)
				{
					// Obtain the X coord of the current character
					caretRect.Width = 4;
				}

				parentDialog.DrawRectangle(caretRect, caretColor);
			}

		}
	}
	#endregion 
}

