/*********************************************************************//**
*	Zvukovy efekt.
*	Umisti do sceny zvuk.
*	
*	author: Michal Jirous
*	date: 23.04.2009
*	file: ent_env_sound.cpp
**********************************************************************/

#include "ent_env_sound.h"

EnvSound::EnvSound() : CBaseEnvironment()
{
	m_sClassName = "env_sound";
	m_iProperties = ENT_PARM_RUNNABLE;
	m_fRadius = 256.0f;
	m_fVolume = 1.0f;
	m_bHearEveryWhere = false;
	m_bIsLooping = false;
	m_bStore_IsOn = true;
	m_bIsOn = true;
	m_bIsPlaying = false;
	m_uiFadeIn = 0;
	m_uiFadeOut = 0;
}

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

	m_sSoundFileName = getParameterValue( parametersMap, "soundfile" );
	
	std::string value = getParameterValue( parametersMap, "radius" );
	if( !value.empty() )
		m_fRadius = (float)atof( value.c_str() );

	value = getParameterValue( parametersMap, "volume" );
	if( !value.empty() )
		m_fVolume = (float)atof( value.c_str() );


	value = getParameterValue( parametersMap, "fadein" );
	if( !value.empty() )
		m_uiFadeIn = atoi( value.c_str() );

	value = getParameterValue( parametersMap, "fadeout" );
	if( !value.empty() )
		m_uiFadeOut = atoi( value.c_str() );
}

#include "game.h"
void EnvSound::onTarget( int target_type )
{
	m_BackTimeData.push_front( BackTimeData() );
	m_BackTimeData.front().event_time = game.getGameTime();

	if( !m_bIsLooping )
	{
		m_Sound.play();
		m_BackTimeData.front().type = EVENT_TURN_ON;
		return;
	}

	if( m_bIsOn )
	{
		//m_Sound.stop();
		m_FadeStartTime = SDL_GetTicks();
		m_BackTimeData.front().type = EVENT_TURN_OFF;
	}
	else
	{
		myLoopPlay();
		m_BackTimeData.front().type = EVENT_TURN_ON;
	}

	
	m_bIsOn ^= true;

}

void EnvSound::myLoopPlay()
{
	m_bIsPlaying = false;	//nejdriv je false
	m_Sound.setGain( 0.0f );	//za zacatku nula
	m_Sound.play();
	m_FadeStartTime = SDL_GetTicks();
}

void EnvSound::restart()
{
	CBaseEnvironment::restart();

	if( !m_bStore_IsOn )
	{
		m_Sound.stop();
		m_bIsPlaying = false;
	}
	else
	{
		if( m_bIsLooping )
			myLoopPlay();
		else
		{
			m_Sound.play();
		}
	}

	m_bIsOn = m_bStore_IsOn;
}

void EnvSound::goBackInTime()
{
	CBaseEnvironment::goBackInTime();

	//musime zjistit v jakym sme stavu
	for( std::list<BackTimeData>::reverse_iterator riter = m_BackTimeData.rbegin(); riter != m_BackTimeData.rend(); ++riter )
	{
		if( (*riter).type == EVENT_BORDER )
			return;

		if( (*riter).type == EVENT_TURN_OFF )
		{	
			if( !m_bIsOn || !m_bIsLooping )
				m_Sound.play();

			m_bIsPlaying = true;
			m_Sound.setGain( m_fVolume );
			m_bIsOn = true;
			return;
		}
		else if( (*riter).type == EVENT_TURN_ON )
		{	
			if( !m_bIsLooping )
			{
				m_Sound.play();
				m_bIsOn = true;
				return;
			}
			m_bIsOn = false;
			m_Sound.stop();
			m_bIsPlaying = false;
			return;
		}
	}
}

void EnvSound::passFlags( int flags )
{
	if(flags & START_SILENT)
		m_bStore_IsOn = false;
	if( flags & LOOPING )
		m_bIsLooping = true;
	if( flags & HEAR_EVERYWHERE )
		m_bHearEveryWhere = true;
}


void EnvSound::decompile()
{
	CBaseEnvironment::decompile();
	m_Sound.stop();
	soundLibrary.unloadSound( m_Sound );
}

#include "error_handler.h"
void EnvSound::compile()
{
	CBaseEnvironment::compile();

	if( !m_sSoundFileName.empty() )
	{
		if( !soundLibrary.loadSound( m_Sound, m_sSoundFileName ) )
			ERR_FILENOTFOUND(m_sSoundFileName);

		m_Sound.setLooping( m_bIsLooping );
		m_Sound.setSourceRelative( m_bHearEveryWhere );
		if( !m_bHearEveryWhere )
			m_Sound.setPosition( origin.x, origin.y, origin.z );


		m_Sound.setGain( m_fVolume );
		m_Sound.setRadius( m_fRadius );

		m_bIsOn = m_bStore_IsOn;

		if( m_bIsOn )
		{
			if( m_bIsLooping )
				myLoopPlay();
			else
				m_Sound.play();
		}
	}
}

void EnvSound::update( float seconds )
{
	m_Sound.update();

	if( m_bIsLooping )
	{
		
		Uint32 diff = SDL_GetTicks() - m_FadeStartTime;
		if( m_bIsOn  )
		{
			if( !m_bIsPlaying )
			{
				if( m_uiFadeIn == 0 )
				{
					m_Sound.setGain( m_fVolume );
					m_bIsPlaying = true;
					
				}
				else
				{
					m_Sound.setGain( m_fVolume * getFromRange( (ALfloat)(diff) / (ALfloat)m_uiFadeIn, 0.0f, 1.0f ) );
					if( diff >= m_uiFadeIn )
						m_bIsPlaying = true;
				}

			}
		
		}
		else if( m_bIsPlaying )
		{
			if( diff > m_uiFadeOut || m_uiFadeOut == 0 )
			{
				m_bIsPlaying = false;
				m_Sound.stop();
			}
			else
				m_Sound.setGain( m_fVolume * ( 1.0f - (ALfloat)(diff) / (ALfloat)m_uiFadeOut ) );

		}
	}

}
