//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#include "cbase.h"
#include "view.h"
#include "materialsystem/IMesh.h"
#include "hl2wars/fx_quad2.h"
#include "tier0/vprof.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

CFXQuad2::CFXQuad2( const FXQuadData2_t &data )

: CClientSideEffect( "Quad2" )
{
	m_FXData = data;
	m_bActiveInternal = true;
}

CFXQuad2::~CFXQuad2( void )
{
	Destroy();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : frametime - 
//-----------------------------------------------------------------------------
void CFXQuad2::Draw( double frametime )
{
	VPROF_BUDGET( "FX_Quad::Draw", VPROF_BUDGETGROUP_PARTICLE_RENDERING );

	// Update the effect
	Update( frametime );

	//float	scaleTimePerc, alphaTimePerc;

	//Determine the scale
	/*if ( m_FXData.m_uiFlags & FXQUAD_BIAS_SCALE )
	{
		scaleTimePerc = Bias( ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ), m_FXData.m_flScaleBias );
	}
	else
	{
		scaleTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime );
	}

	float scale = m_FXData.m_flStartScale + ( ( m_FXData.m_flEndScale - m_FXData.m_flStartScale ) * scaleTimePerc );*/
	float scale = m_FXData.m_flScale;

	//Determine the alpha
	/*if ( m_FXData.m_uiFlags & FXQUAD_BIAS_ALPHA )
	{
		alphaTimePerc = Bias( ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ), m_FXData.m_flAlphaBias );
	}
	else
	{
		alphaTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime );
	}

	float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * alphaTimePerc );*/
	float alpha = m_FXData.m_flAlpha;
	alpha = clamp( alpha, 0.0f, 1.0f );
	
	CMatRenderContextPtr pRenderContext( materials );

	//Bind the material
	IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial );
	CMeshBuilder meshBuilder;

	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	//Update our roll
	m_FXData.m_flYaw = anglemod( m_FXData.m_flYaw + ( m_FXData.m_flDeltaYaw * frametime ) );

	Vector	pos;
	Vector	vRight, vUp;

	float color[4];

	color[0] = m_FXData.m_Color[0];
	color[1] = m_FXData.m_Color[1];
	color[2] = m_FXData.m_Color[2];
	color[3] = alpha;

	VectorVectors( m_FXData.m_vecNormal, vRight, vUp );

	Vector	rRight, rUp;

	rRight	= ( vRight * cos( DEG2RAD( m_FXData.m_flYaw ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw ) ) );
	rUp		= ( vRight * cos( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) ) - ( vUp * sin( DEG2RAD( m_FXData.m_flYaw+90.0f ) ) );

	vRight	= rRight * ( scale * 0.5f );
	vUp		= rUp * ( scale * 0.5f );

	pos = m_FXData.m_vecOrigin + vRight - vUp;

	meshBuilder.Position3fv( pos.Base() );
	meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() );
	meshBuilder.TexCoord2f( 0, 1.0f, 1.0f );
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	pos = m_FXData.m_vecOrigin - vRight - vUp;

	meshBuilder.Position3fv( pos.Base() );
	meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() );
	meshBuilder.TexCoord2f( 0, 0.0f, 1.0f );
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	pos = m_FXData.m_vecOrigin - vRight + vUp;

	meshBuilder.Position3fv( pos.Base() );
	meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	pos = m_FXData.m_vecOrigin + vRight + vUp;

	meshBuilder.Position3fv( pos.Base() );
	meshBuilder.Normal3fv( m_FXData.m_vecNormal.Base() );
	meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CFXQuad2::IsActive( void )
{
	return m_bActiveInternal;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CFXQuad2::Destroy( void )
{
	//Release the material
	if ( m_FXData.m_pMaterial != NULL )
	{
		m_FXData.m_pMaterial->DecrementReferenceCount();
		m_FXData.m_pMaterial = NULL;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : frametime - 
//-----------------------------------------------------------------------------
void CFXQuad2::Update( double frametime )
{
	if( !m_FXData.m_bMoving || !m_FXData.m_hEntFollow.Get() || !m_FXData.m_hEntFollow.Get()->IsAlive() )
		return; 

	// update origin
	m_FXData.m_vecOrigin = m_FXData.m_hEntFollow.Get()->GetAbsOrigin();
	m_FXData.m_vecOrigin[2] += 1.0f; 

	// update normal
	Vector start, end;
	VectorCopy( m_FXData.m_hEntFollow.Get()->GetAbsOrigin(), start );
	VectorCopy( m_FXData.m_hEntFollow.Get()->GetAbsOrigin(), end );

	// Straight down
	end[2] -= 64;

	trace_t	trace;
	UTIL_TraceLine( start, end, MASK_SOLID, m_FXData.m_hEntFollow.Get(), COLLISION_GROUP_NONE, &trace );

	if( trace.DidHitWorld() )
	{
		VectorCopy( trace.plane.normal, m_FXData.m_vecNormal );
	}
}

void CFXQuad2::DeActivate()
{
	m_bActiveInternal = false;
}

