using System;
using System.Collections;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

using DarkStrideToolbox;


namespace MetalMarines
{
	public enum enumAlertState
	{
		Rising,
		Fading
	}


	public class AlertManager
	{
		#region Properties 
		private const string m_cALERTMESHKEY = "AlertManager - $ Font";
		private const string m_cALERTFONTKEY = "Arial";
		private const double m_cRISINGFADEINTIMEINSECONDS = 1;
		private const double m_cRISINGTIMEINSECONDS = 15;
		private const double m_cFADETIMEINSECONDS = 2;
		private double m_nElapsedTime = 0;

		private ArrayList m_oAlerts = new ArrayList();
		private DSGameEngine m_oGameEngine = null;
		#endregion


		public AlertManager( DSGameEngine oGameEngine )
		{
			int nFontHeight = 0;
			Microsoft.DirectX.Direct3D.Font oNewFont = null;

			m_oGameEngine = oGameEngine;

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

		public void AddMessage( string sMessage )
		{
			Alert oNewAlert = new Alert();

			oNewAlert.Y = ((double)m_oGameEngine.ScreenHeight) * .8f;
			oNewAlert.Message = sMessage;
			oNewAlert.ElapsedTime = 0;

			m_oAlerts.Add( oNewAlert );
		}

		public void Advance( double nElapsedTime )
		{
			Alert oLoopAlert = null;
			long nFontBuffer = 4;


			//Rotate our icons
			m_nElapsedTime += nElapsedTime * 2;

			//Advance our individual alerts
			for( int i=0 ; i<m_oAlerts.Count ; i++ )
			{
				oLoopAlert = (Alert)m_oAlerts[ i ];

				oLoopAlert.ElapsedTime += nElapsedTime * 2;


				if( oLoopAlert.State == enumAlertState.Fading || oLoopAlert.Y > 90 )
				{
					oLoopAlert.Y -= nElapsedTime * 180 * 2;
				}
				if( i > 0 && oLoopAlert.Y < 
					((Alert)m_oAlerts[ i-1 ]).Y + DSResourceManager.GetGlobalInstance().GetFontSize().Y + nFontBuffer )
				{
					oLoopAlert.Y = ((Alert)m_oAlerts[ i-1 ]).Y + DSResourceManager.GetGlobalInstance().GetFontSize().Y + nFontBuffer;
				}

				if( oLoopAlert.State == enumAlertState.Rising &&
					oLoopAlert.ElapsedTime > m_cRISINGTIMEINSECONDS )
				{
					oLoopAlert.State = enumAlertState.Fading;
					oLoopAlert.ElapsedTime = 0;
				}
				else if( oLoopAlert.State == enumAlertState.Fading &&
						 oLoopAlert.ElapsedTime > m_cFADETIMEINSECONDS )
				{
					m_oAlerts.RemoveAt( i );
					i--;
				}
			}
		}

		public void RenderAfterForms()
		{
			Vector3 eyeLocation = new Vector3(0.0f,0*-5.0f,-20.0f);
			Vector3 lookAtPoint = new Vector3(0.2f*0, 0.0f,  0.0f);
			Alert oLoopAlert = null;
			Matrix oRotate = Matrix.Identity;
			int nAlpha = 0;


			m_oGameEngine.CaptureStateBlock( "Alerts Manager" );

			m_oGameEngine.Direct3DDevice.RenderState.Lighting = true;
			m_oGameEngine.Set3DCameraTransformView( eyeLocation,lookAtPoint,new Vector3(0,1,0 ) );
			m_oGameEngine.Direct3DDevice.Transform.Projection = Matrix.PerspectiveFovLH(.78f, 1, 1, 1000);
			m_oGameEngine.Direct3DDevice.SetTexture( 0,DSResourceManager.GetGlobalInstance().GetTexture( "Blue" ) );

			for( int i=0 ; i<m_oAlerts.Count ; i++ )
			{
				oLoopAlert = (Alert)m_oAlerts[ i ];

				if( oLoopAlert.State == enumAlertState.Fading )
				{
					nAlpha = Convert.ToInt32( 255 * ( 1 - ( oLoopAlert.ElapsedTime / m_cFADETIMEINSECONDS ) ) );
				}
				else if( oLoopAlert.State == enumAlertState.Rising )
				{
					if( oLoopAlert.ElapsedTime >= m_cRISINGFADEINTIMEINSECONDS )
					{
						nAlpha = 255;
					}
					else
					{
						nAlpha = Convert.ToInt32( 255 * ( oLoopAlert.ElapsedTime / m_cRISINGFADEINTIMEINSECONDS ) );
					}
				}

				DSResourceManager.GetGlobalInstance().GetFont( m_cALERTFONTKEY ).DrawText(
									m_oGameEngine.SpriteEngine,oLoopAlert.Message,
									new System.Drawing.Rectangle( 10-1,(int)oLoopAlert.Y-1,0,0 ), 
									Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip,
									System.Drawing.Color.FromArgb( nAlpha,0,0,0 ) );

				DSResourceManager.GetGlobalInstance().GetFont( m_cALERTFONTKEY ).DrawText(
									m_oGameEngine.SpriteEngine,oLoopAlert.Message,
									new System.Drawing.Rectangle( 10-1,(int)oLoopAlert.Y+1,0,0 ), 
									Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip,
									System.Drawing.Color.FromArgb( nAlpha,0,0,0 ) );

				DSResourceManager.GetGlobalInstance().GetFont( m_cALERTFONTKEY ).DrawText(
									m_oGameEngine.SpriteEngine,oLoopAlert.Message,
									new System.Drawing.Rectangle( 10+1,(int)oLoopAlert.Y-1,0,0 ), 
									Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip,
									System.Drawing.Color.FromArgb( nAlpha,0,0,0 ) );

				DSResourceManager.GetGlobalInstance().GetFont( m_cALERTFONTKEY ).DrawText(
									m_oGameEngine.SpriteEngine,oLoopAlert.Message,
									new System.Drawing.Rectangle( 10+1,(int)oLoopAlert.Y+1,0,0 ), 
									Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip,
									System.Drawing.Color.FromArgb( nAlpha,0,0,0 ) );

				DSResourceManager.GetGlobalInstance().GetFont( m_cALERTFONTKEY ).DrawText(
									m_oGameEngine.SpriteEngine,oLoopAlert.Message, 
									new System.Drawing.Rectangle( 10,(int)oLoopAlert.Y,0,0 ), 
									Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip,
									System.Drawing.Color.FromArgb( nAlpha,151,159,95 ) );
			}

			m_oGameEngine.ApplyStateBlock( "Alerts Manager" );
		}

		public void Clear()
		{
			m_oAlerts = new ArrayList();
		}



		#region Properties 
		public ArrayList Alerts
		{
			get
			{
				return( m_oAlerts );
			}
		}
		public DSGameEngine GameEngine
		{
			get
			{
				return( m_oGameEngine );
			}
			set
			{
				m_oGameEngine = value;
			}
		}
		#endregion
	}


	public class Alert
	{
		#region Properties 
		private double m_nY = 0;
		private string m_sMessage = "";
		private double m_nElapsedTime = 0;
		private enumAlertState m_nState = enumAlertState.Rising;
		#endregion


		public Alert()
		{
		}



		#region Properties 
		public double Y
		{
			get
			{
				return( m_nY );
			}
			set
			{
				m_nY = value;
			}
		}
		public string Message
		{
			get
			{
				return( m_sMessage );
			}
			set
			{
				m_sMessage = value;
			}
		}
		public double ElapsedTime
		{
			get
			{
				return( m_nElapsedTime );
			}
			set
			{
				m_nElapsedTime = value;
			}
		}
		public enumAlertState State
		{
			get
			{
				return( m_nState );
			}
			set
			{
				m_nState = value;
			}
		}
		#endregion
	}
}