/*********************************************************************//**
*	Bodove svetlo.
*	Tohle je objekt, ktery definuje svetelny zdroj.
*	
*	author: Michal Jirous
*	date: 23.04.2009
*	file: ent_items.cpp
**********************************************************************/

#include "ent_light.h"


#define GO_DOWN	0
#define GO_UP 1

Light::Light()	: CBaseEnvironment()
{
	m_bStore_IsOn = true;
	m_bIsOn = true;
	m_iType = LS_NORMAL;
	memset( m_Color,0, sizeof(m_Color) );	//reset barvy :)
	m_iData = 0;
	m_fValue = m_fMaxValue = m_fMinValue = m_fStep = 0.0f;
	m_iProperties = ENT_PARM_RUNNABLE;
}

void Light::passFlags( int flags )
{
	if( flags & INITIALY_DARK )
	{
		m_bIsOn = m_bStore_IsOn = false;
	}
}

void Light::passStoredEvent( BackTimeData &backData )
{
	CBaseEnvironment::passStoredEvent( backData );
	/*if( backData.type == EVENT_TURN_ON )
	{
		if( !m_bIsOn )
			onTarget( 0 );
	}
	else if( backData.type == EVENT_TURN_OFF )
	{
		if( m_bIsOn )
			onTarget( 0 );
	}*/	
}

void Light::setGlColor()
{
	glColor3fv( m_Color ); 
}

void Light::restart()
{
	CBaseEnvironment::restart();
	m_bIsOn = m_bStore_IsOn;
}

void Light::goBackInTime()
{
	CBaseEnvironment::goBackInTime();
	for( std::list<BackTimeData>::reverse_iterator riter = m_BackTimeData.rbegin(); riter != m_BackTimeData.rend();  ++riter )
	{
		//jakmile nalezneme border, tak koncime pruchod
		if( (*riter).type == EVENT_BORDER )
			return;

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


#include "game.h"

void Light::onTarget( int target_type )
{
	m_BackTimeData.push_front( BackTimeData() );
	m_BackTimeData.front().event_time = game.getGameTime();;
	
	if( m_bIsOn )
	{
		m_BackTimeData.front().type = EVENT_TURN_OFF;
		m_bIsOn = false;
	}
	else
	{
		m_BackTimeData.front().type = EVENT_TURN_ON;
		m_bIsOn = true;
	}
}
#include "colors.h"
void Light::setParameters( parameters_t &parametersMap )
{
	CBaseEnvironment::setParameters( parametersMap );

	string value = getParameterValue( parametersMap, "_light" );	//barva svetla
	if( !value.empty() )
	{
		colorStringToField4<float>( value.c_str(), m_Color );
		for( int i = 0; i < 4; i++ )
			m_Color[i] /= 255.0f;


		memcpy( m_Store_Color, m_Color, sizeof( m_Color ) );
	}

	value =  getParameterValue( parametersMap, "style" );	//identifikacni cislo stylu (pokud nejaky je)
	if( !value.empty() )
	{
		m_iStyleNum = atoi( value.c_str() );
	}

	value =  getParameterValue( parametersMap, "type" );	//vlastnost svetla
	if( !value.empty() )
	{
		m_iType = atoi( value.c_str() );
		switch( m_iType )
		{
			case LS_PULSE_LINEAR_SLOW:
			case LS_PULSE_LINEAR_NORMAL:
			case LS_PULSE_LINEAR_FAST:
				m_fMaxValue = m_Store_Color[3];	//last alpha is brightness here
				m_iData = GO_DOWN;	//zacneme pekne od shora
				m_fValue = m_fMaxValue;
				if( m_iType == LS_PULSE_LINEAR_SLOW )
					m_fStep = 0.005f;
				else if( m_iType == LS_PULSE_LINEAR_NORMAL )
					m_fStep = 0.01f;
				else
					m_fStep = 0.05f;
				break;
			case LS_STROBE_RARELY:
			case LS_STROBE_OCCASIONALLY:
			case LS_STROBE_OFTEN:
				m_fMaxValue = m_Store_Color[3];	//last alpha is brightness here
				m_fValue = 0.0f;	//start dark
				m_fStep = 0.1f;		//fast back
				if( m_iType == LS_STROBE_RARELY )
					m_iData = 2;	//pravdepodobnost vyboje
				else if(  m_iType == LS_STROBE_OCCASIONALLY )
					m_iData = 5;	//pravdepodobnost vyboje
				else
					m_iData = 10;	//pravdepodobnost vyboje
				break;
		}
	}
}




void Light::update( float seconds )
{
	CBaseEnvironment::update( seconds );
	if(m_bIsOn)
	{
		switch( m_iType )
		{
			case LS_PULSE_LINEAR_SLOW:
			case LS_PULSE_LINEAR_NORMAL:
			case LS_PULSE_LINEAR_FAST:
				if( m_iData == GO_UP )
				{
					if( m_fMaxValue - m_fValue < m_fStep )
					{
						m_fValue = m_fMaxValue;
						m_iData = GO_DOWN;
					}
					else
						m_fValue += m_fStep;
				}	
				else
				{
					if( m_fValue - m_fMinValue < m_fStep )
					{
						m_fValue = m_fMinValue;
						m_iData = GO_UP;
					}
					else
						m_fValue -= m_fStep;
				}
				break;
			case LS_STROBE_OCCASIONALLY:
			case LS_STROBE_RARELY:
			case LS_STROBE_OFTEN:
				{
					if( m_fValue - m_fMinValue < m_fStep )
						m_fValue = m_fMinValue;
					else
						m_fValue -= m_fStep;

					//strobe
					if( rand() % 100 < m_iData )
					{
						m_fValue = ((float)(rand() % 100)) / 100.0f;
					}
				}
				break;
				
			
		}

		for( int i = 0; i < 3; ++i )
			m_Color[i] = m_Store_Color[i] * (m_fValue / m_fMaxValue);
	}
}
