// File: PowerUp.cs
// Author: Sonhui Schweitzer
// Date: January 25th, 2005
// Project: CS470 Applied Software Developement Project
using System;
using Microsoft.DirectX;
using Direct3D=Microsoft.DirectX.Direct3D;
using DirectSound=Microsoft.DirectX.DirectSound;

namespace BreakOut
{
	public class PowerUp : Entity
	{
		protected string m_oName = "PowerUp";
		private Circle m_oBounds;
		private Vector2 m_oVelocity;
		private System.Drawing.Color m_oColor;

		public System.Drawing.Color Color
		{
			get { return m_oColor; }
			set { m_oColor = value; }
		}

		public Vector2 Location
		{
			get { return m_oBounds.Location; }
			set { m_oBounds.Location = value; }
		}

		public PowerUp( Vector2 oLocation )
		{
			m_oVelocity = new Vector2( 0.0f , -0.5f );
			m_oBounds = new Circle( oLocation , 0.03f );
			m_oColor = System.Drawing.Color.Gold;
		}

		~PowerUp()
		{
		}

		public static Direct3D.VertexBuffer CreateVB( Direct3D.Device oDevice )
		{
			Direct3D.VertexBuffer oVB = new Direct3D.VertexBuffer( typeof( Direct3D.CustomVertex.PositionColoredTextured ) , 4 , oDevice , 0 , Direct3D.CustomVertex.PositionColoredTextured.Format , Microsoft.DirectX.Direct3D.Pool.Default );
			GraphicsStream oStream = oVB.Lock( 0 , 0 , 0 );
			Direct3D.CustomVertex.PositionColoredTextured[] aVertices = new Direct3D.CustomVertex.PositionColoredTextured[ 4 ];
			
			float fEdgeSize = 0.00f;
			float fXSize = 4.5f;
			float fYSize = 2.25f;
			aVertices[ 0 ].X = -fXSize;
			aVertices[ 0 ].Y = fYSize;
			aVertices[ 0 ].Z = 0.0f;
			aVertices[ 0 ].Color = new Direct3D.ColorValue( 1.0f , 1.0f , 1.0f , 1.0f ).ToArgb();
			aVertices[ 0 ].Tu = fEdgeSize;
			aVertices[ 0 ].Tv = fEdgeSize;

			aVertices[ 1 ].X = -fXSize;
			aVertices[ 1 ].Y = -fYSize;
			aVertices[ 1 ].Z = 0.0f;
			aVertices[ 1 ].Color = new Direct3D.ColorValue( 1.0f , 1.0f , 1.0f , 1.0f ).ToArgb();
			aVertices[ 1 ].Tu = fEdgeSize;
			aVertices[ 1 ].Tv = 1.0f - fEdgeSize;

			aVertices[ 2 ].X = fXSize;
			aVertices[ 2 ].Y = fYSize;
			aVertices[ 2 ].Z = 0.0f;
			aVertices[ 2 ].Color = new Direct3D.ColorValue( 1.0f , 1.0f , 1.0f , 1.0f ).ToArgb();
			aVertices[ 2 ].Tu = 1.0f - fEdgeSize;
			aVertices[ 2 ].Tv = fEdgeSize;
			
			aVertices[ 3 ].X = fXSize;
			aVertices[ 3 ].Y = -fYSize;
			aVertices[ 3 ].Z = 0.0f;
			aVertices[ 3 ].Color = new Direct3D.ColorValue( 1.0f , 1.0f , 1.0f , 1.0f ).ToArgb();
			aVertices[ 3 ].Tu = 1.0f - fEdgeSize;
			aVertices[ 3 ].Tv = 1.0f - fEdgeSize;
			
			oStream.Write( aVertices );
			oVB.Unlock();
			return oVB;
		}

		public virtual void Render( Direct3D.Device oDevice , Game oGame )
		{
			Direct3D.VertexBuffer oVB = oGame.GetVB( "PowerUp" );
			Direct3D.Texture oTexture = oGame.GetTexture( m_oName );
			if ( ( oVB != null ) && ( oTexture != null ) )
			{
				oDevice.Transform.World = Matrix.Scaling( m_oBounds.Radius , m_oBounds.Radius , 1.0f ) * Matrix.Translation( m_oBounds.Location.X , m_oBounds.Location.Y , 0.0f );

				oDevice.SetStreamSource( 0 , oVB , 0 );
				oDevice.VertexFormat = Direct3D.CustomVertex.PositionColoredTextured.Format;

				oDevice.SetTexture( 0 , oTexture );
				oDevice.RenderState.AlphaBlendEnable = true;
				oDevice.RenderState.SourceBlend = Direct3D.Blend.SourceAlpha;
				oDevice.RenderState.DestinationBlend = Direct3D.Blend.InvSourceAlpha;
				oDevice.SamplerState[ 0 ].MinFilter = Direct3D.TextureFilter.Linear;
				oDevice.SamplerState[ 0 ].MagFilter = Direct3D.TextureFilter.Linear;
				oDevice.SamplerState[ 0 ].MipFilter = Direct3D.TextureFilter.Linear;
				oDevice.TextureState[ 0 ].ColorOperation = Direct3D.TextureOperation.Modulate;
				oDevice.TextureState[ 0 ].ColorArgument1 = Direct3D.TextureArgument.TextureColor;
				oDevice.TextureState[ 0 ].ColorArgument2 = Direct3D.TextureArgument.Diffuse;
				oDevice.TextureState[ 0 ].AlphaOperation = Direct3D.TextureOperation.Modulate;
				oDevice.TextureState[ 0 ].AlphaArgument1 = Direct3D.TextureArgument.TextureColor;
				oDevice.TextureState[ 0 ].AlphaArgument2 = Direct3D.TextureArgument.Diffuse;

				oDevice.DrawPrimitives( Direct3D.PrimitiveType.TriangleStrip , 0 , 2 );
				oDevice.RenderState.AlphaBlendEnable = false;
			}
		}

		public virtual void Collide( Game oGame , CollideArgs oArgs )
		{
			for ( int i = 0 ; i < oArgs.Count ; ++i )
			{
				// if colliding with Paddle apply powerup and destroy it
				if ( oArgs.GetEntity( i ) is Paddle )
				{
					// TODO: apply powerup
					ApplyPowerUp( oGame );
					oGame.AddParticleSystem( new ParticleSystem( oGame.Random , m_oBounds.Location , System.Drawing.Color.White , 1.0f , 8 , Vector2.Empty , false , 0.1f , 0.08f ) );
					oGame.RemovePowerUp( this );
					oGame.PlaySound( "PowerUp" );
				}
				// else if colliding with void destroy powerup
				else if ( oArgs.GetEntity( i ) is Void )
				{
					oGame.RemovePowerUp( this );
				}
				// else do nothing
			}
		}

		public virtual void ApplyPowerUp( Game oGame )
		{
		}

		public virtual float Update( Game oGame , float fDeltaTime )
		{
			m_oBounds.Location += m_oVelocity * fDeltaTime;
			return 0.0f;
		}

		public Bounds GetBounds()
		{
			return ( Bounds )m_oBounds;
		}
	}
}
