/*********************************************************************//**
*	2D Sprite
*	Umisti do sceny 2D sprite.
*	
*	author: Michal Jirous
*	date: 23.04.2009
*	file: ent_env_sprite.cpp
**********************************************************************/

#include "ent_env_sprite.h"

EnvSprite::EnvSprite() : CBaseEnvironment()
{
	m_sClassName = "env_sprite";
	m_iProperties = ENT_PARM_RUNNABLE | ENT_PARM_RENDER;
	m_pStart = NULL;
	m_pEnd = NULL;
	m_pSortBoundingBox = &m_Bounds;
	m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL;	//zakladni nastaveni pri pouziti specialni osy

	m_bPlayOnce = false;
	m_iAxis = AXIS_TYPE_NO_AXIS;
	m_bDirectional = false;

}

void EnvSprite::passFlags( int flags )
{
	m_Sprite.m_bIsPlaying = flags & SPRITE_START_ON;
	if(flags & SPRITE_PLAY_ONCE)
		m_bPlayOnce = true;
	if( flags & SPRITE_LOCK_ON_X )
		m_iAxis = AXIS_TYPE_X_AXIS;
	if( flags & SPRITE_LOCK_ON_Y )
		m_iAxis = AXIS_TYPE_Y_AXIS;
	if( flags & SPRITE_LOCK_ON_Z )
		m_iAxis = AXIS_TYPE_Z_AXIS;
	if( flags & SPRITE_DIRECTIONAL )
		m_bDirectional = true;
}


void EnvSprite::update( float seconds )
{
	CBaseEnvironment::update( seconds );
	m_Sprite.update( (int)(seconds*1000.0f) );
}

void EnvSprite::setParameters( parameters_t &parametersMap )
{
	CBaseEnvironment::setParameters( parametersMap );

	m_sSpriteName = getParameterValue( parametersMap, "model" );

	m_sStartPoint = getParameterValue( parametersMap, "startpoint" );
	m_sEndPoint = getParameterValue( parametersMap, "endpoint" );

	std::string value = getParameterValue( parametersMap, "textureoption" );
	if( !value.empty() )
	{
		m_iTextureOption = atoi( value.c_str() );

		switch( m_iTextureOption )
		{
		case 2:
			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_COPY;
			break;
		case 3:
			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_EXPAND;
			break;
		case 1:
		default:
			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL;
		}
	}
}

#include "game.h"

void EnvSprite::trigger()
{
	m_Sprite.m_bIsPlaying ^= 1;


	m_BackTimeData.push_front( BackTimeData() );
	m_BackTimeData.front().event_time = game.getGameTime();

	if( m_Sprite.m_bIsPlaying )
		m_BackTimeData.front().type = EVENT_TURN_ON;
	else
		m_BackTimeData.front().type = EVENT_TURN_OFF;
}


void EnvSprite::onTarget( int target_type )
{
	trigger();
	
}

void EnvSprite::goBackInTime()
{
	CBaseEnvironment::goBackInTime();
	//musime najit stav
	for( std::list<BackTimeData>::reverse_iterator riter = m_BackTimeData.rbegin(); riter != m_BackTimeData.rend(); ++riter )
	{
		if( (*riter).type == EVENT_BORDER )	//na border bych tu nemel narazit
			return;

		if( (*riter).type == EVENT_TURN_ON )
		{
			m_Sprite.m_bIsPlaying = false;
			return;
		}
		else if( (*riter).type == EVENT_TURN_OFF )
		{
			m_Sprite.m_bIsPlaying = true;
			return;
		}
	}
}

void EnvSprite::restart()
{
	CBaseEnvironment::restart();
	m_Sprite.m_bIsPlaying = m_Store_IsOn;
}

#include "level_loader.h"
#include "level_collision.h"
void EnvSprite::compile()
{
	CBaseEnvironment::compile();

	if( m_bDirectional )
	{
		m_iAxis = AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL;
		Vector axis;
		axis.createFrom2Angles( angles.x, angles.z );
		m_pStart = &origin;
		m_pEnd = new Point( origin + axis );
	}
	else if( !m_sStartPoint.empty() && !m_sEndPoint.empty() )
	{
		entityList_t *pEtartEntities = levelLoader.m_Entities.getEntitiesByName( m_sStartPoint );
		entityList_t *pEndEntities = levelLoader.m_Entities.getEntitiesByName( m_sEndPoint );
		if( pEtartEntities && !pEtartEntities->empty() )
			m_pStart = &pEtartEntities->front()->origin;

		if( pEndEntities && !pEndEntities->empty() )
			m_pEnd = &pEndEntities->front()->origin;

		if( m_pStart && m_pEnd )
			m_iAxis = m_iTextureOption;
	}

	m_Store_IsOn = m_Sprite.m_bIsPlaying;
	
	


	
	
	spritesLibrary.applySprite( m_Sprite, m_sSpriteName, m_iAxis );

	if( m_iAxis >= AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL )
	{
		m_Bounds.setBasicValues( *m_pEnd );
		m_Bounds.updateData( *m_pStart );
	}
	else
	{
		m_Bounds.setBasicValues( origin );
	}

	m_Bounds.setRange( m_Sprite.getRadius() );

	m_Sprite.m_bIsLooping = !m_bPlayOnce;


	switch( m_Sprite.getRenderType() )
	{
		case BLACK_BLEND:
		case ALPHA_BLEND:
			m_bIsBlending = true;	
	}


	if( rendermode != RENDER_MODE_COLOR )
	{
		m_Bounds.setRange( 10.0f );
		float distance = 100.0f;
		Face *pNearestFace = collisionSystem.findNearestFace( m_Bounds, distance );
		m_Bounds.setRange( -10.0f );
		if( pNearestFace )
			pNearestFace->getLightColor( (GLfloat*)&rendercolor );
	}
}	

void EnvSprite::decompile()
{
	m_Sprite.unload();
	if( m_bDirectional )
		delete m_pEnd;
}

void EnvSprite::render( RenderData &renderData )
{
	if( !m_Sprite.isWorking() || !m_Sprite.m_bIsPlaying)
		return;

	glPushAttrib( GL_CURRENT_BIT );

	glColor4f( rendercolor.x, rendercolor.y,rendercolor.z, 1.0f  );

	if( m_iAxis >= AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL )
		m_Sprite.draw( *renderData.cameraPosition, Axis( *m_pStart, *m_pEnd ) );
	else
		m_Sprite.draw( *renderData.cameraPosition, origin );
	
	glPopAttrib();
}

bool EnvSprite::renderCullTest( RenderData &renderData )
{
	return renderData.frustum->isBoundsInsideFrustum( m_Bounds );
}


//#include "baseentity.h"
//#include "algebraic_ext.h"
//#include "game.h"
//CEnvSprite::CEnvSprite( CBaseObject *pPlayer)
//{
//	init();
//	m_sClassName = "env_sprite";
//	m_sSearchType = "";
//
//	m_pPlayer = pPlayer;
//	m_pSprite = NULL;
//	m_bIsOn = false;
//	m_iRate = -1;
//	m_fScale = 1;
//	m_iAxis = AXIS_TYPE_NO_AXIS;
//	m_bIsFinished = false;
//
//	m_bPlayOnce = false;
//	start = NULL;
//	end = NULL;
//	m_uiCurrentFrame = 0;
//	m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL;
//}
//
//void CEnvSprite::run()
//{
//	m_Sprite.update( 30 );
//	//m_uiCurrentFrame++;
//	/*if(m_pSprite != NULL && m_bIsOn)
//		m_pSprite->run();*/
//}
//
//void CEnvSprite::setFlags( int flags )
//{
//	m_bIsOn = flags & SPRITE_START_ON;
//	if(flags & SPRITE_PLAY_ONCE) m_bPlayOnce = true;
//
//	if( flags & SPRITE_LOCK_ON_X )	m_iAxis = AXIS_TYPE_X_AXIS;
//	if( flags & SPRITE_LOCK_ON_Y )	m_iAxis = AXIS_TYPE_Y_AXIS;
//	if( flags & SPRITE_LOCK_ON_Z )	m_iAxis = AXIS_TYPE_Z_AXIS;
//}
//
//void CEnvSprite::onTarget()
//{
//	m_Sprite.m_bIsPlaying ^= true;
//}
//
//void CEnvSprite::draw()
//{
//	if( !m_Sprite.isWorking() || !m_bIsOn || m_bIsFinished || !m_Sprite.m_bIsPlaying)
//		return;
//
//	if( m_iAxis >= AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL )
//		m_Sprite.draw(-game.m_pPlayer->getOrigin(), Axis(start->object->getOrigin(), end->object->getOrigin()) );
//	else
//		m_Sprite.draw( -game.m_pPlayer->getOrigin(), origin );
//	
//	Uint32 timeStart,endTime;
//	int TIMETEST = 100000;
//	timeStart =  SDL_GetTicks();
//		
//	
//		for( int i = 0; i < TIMETEST; i++ )
//		m_Sprite.draw(-game.m_pPlayer->getOrigin(), Axis(start->object->getOrigin(), end->object->getOrigin()) );
//
//	
//	endTime = SDL_GetTicks();
//	cout << "Axis draw" << endTime - timeStart << endl;
//
//	m_Sprite.unload();
//	spritesLibrary.applySprite( m_Sprite, spriteName, AXIS_TYPE_X_AXIS );
//	
//	timeStart =  SDL_GetTicks();
//		for( int i = 0; i < TIMETEST; i++ )
//		m_Sprite.draw( -game.m_pPlayer->getOrigin(), origin );
//
//	endTime = SDL_GetTicks();
//	cout << "Axis draw" << endTime - timeStart << endl;
//	
//	
//	//spritesLibrary.drawSprite( m_pSprite, m_uiCurrentFrame, origin, m_iAxis, &m_SpecialAxisParms );
//	
//	//if( m_bPlayOnce )
//	//	m_bIsFinished  = true;
//}
//
//void CEnvSprite::setTextureOption( int option )
//{
//	switch( option )
//	{
//		case 2:
//			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_COPY;
//			break;
//		case 3:
//			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_EXPAND;
//			break;
//		case 1:
//		default:
//			m_iTextureOption = AXIS_TYPE_SPECIFICATED_TEXTURE_ORIGINAL;
//	}
//}
//
//void CEnvSprite::compile()
//{
//	m_Sprite.unload();
//	//spritesLibrary.unloadSprite( m_pSprite );
//	
//
//	
//
//	if(start != NULL && end != NULL)
//	{
//		m_iAxis = m_iTextureOption;
//		
//		
//
//		//Vector vecSpecialAxis = end->object->getOrigin() - start->object->getOrigin();
//
//		//origin = (start->object->getOrigin() + end->object->getOrigin()) / 2;
//		//m_SpecialAxisParms = spritesLibrary.createSpecialAxis( m_pSprite, vecSpecialAxis );
//	}
//	
//	spritesLibrary.applySprite( m_Sprite, spriteName, m_iAxis );
//
//	m_Bounds.setBasicValues( origin );
//	m_Bounds.setRange( sqrt( 3*pow( (float)max(64,64 ),2.0f) ) );
//	
//	m_Sprite.m_bIsLooping = !m_bPlayOnce;
//	m_Sprite.m_bIsPlaying = m_bIsOn;
//}
//
//void CEnvSprite::decompile()
//{
//	m_Sprite.unload();
//
//	if(pTarget != NULL)
//	{
//		delete pTarget;
//		pTarget = NULL;
//	}
//	if(start != NULL)
//	{
//		delete start;
//		start = NULL;
//	}
//	if(end != NULL)
//	{
//		delete end;
//		end = NULL;
//	}
//
//}
