#include "ent_triggers.h"

CBaseTrigger::CBaseTrigger()
{
	m_uiTriggerTime = TRIGGER_INFINITE;	//maximum - nelze provest trigger
	m_uiTriggerDelay = 0;
	m_uiResetDelay = 0;
	m_uiResetTime = 0;
	m_iProperties = ENT_PARM_COLLIDING | ENT_PARM_RUNNABLE;
	m_bIsOn = true;
	m_bTriggerOnce = false;
	m_pTriggeredObject = NULL;
	m_bStored_IsOn = true;
}

void CBaseTrigger::passFlags( int flags )
{
	if( flags & FIRE_ONCE )
		m_bTriggerOnce = true;
	if( flags & START_OFF )
	{
		m_bStored_IsOn = false;
		m_bIsOn = false;
	}
}



void CBaseTrigger::setParameters( parameters_t &parametersMap )
{
	CBaseEntity::setParameters( parametersMap );

	std::string sValue = getParameterValue( parametersMap, "delay" );
	if( !sValue.empty() )
		m_uiTriggerDelay = atoi( sValue.c_str() );

	if( !m_bTriggerOnce )
	{
		sValue = getParameterValue( parametersMap, "resettime" );
		if( !sValue.empty() )
			m_uiResetDelay = atoi( sValue.c_str() );
	}
	
}

void CBaseTrigger::restart()
{
	CBaseEntity::restart();
	//TODO
	m_uiTriggerTime = TRIGGER_INFINITE;	//maximum - nelze provest trigger
	m_uiResetTime = 0;	
	m_bIsOn = m_bStored_IsOn;
}

#include "game.h"

void CBaseTrigger::update( float seconds )
{
	CBaseEntity::update( seconds );
	if( m_bIsOn )
	{
		if( m_uiTriggerTime != TRIGGER_INFINITE && game.getGameTime() >= m_uiTriggerTime + m_uiTriggerDelay )
		{
			m_uiResetTime = game.getGameTime();
			m_uiTriggerTime = TRIGGER_INFINITE;
			trigger();
		}

		
	}
}


void CBaseTrigger::trigger()
{
	m_BackTimeData.push_front( BackTimeData() );
	m_BackTimeData.front().event_time = game.getGameTime();
	m_BackTimeData.front().type = EVENT_TRIGGER;
}


void CBaseTrigger::passStoredEvent( BackTimeData &backData )
{
	if( backData.type == EVENT_TRIGGER )
		trigger();
	else if( backData.type == EVENT_TURN_OFF )
		m_bIsOn = false;
	else if( backData.type == EVENT_TURN_ON )
		m_bIsOn = true;
}


void CBaseTrigger::processTrigger( CBasePhysics * initiator )
{
	m_pTriggeredObject = initiator;

	//m_uiResetTime je nula pouze pri prvnim pruchodu
	if( m_uiResetTime == 0 || ( m_uiResetDelay != TRIGGER_INFINITE && m_uiResetTime != TRIGGER_INFINITE && m_uiResetTime + m_uiResetDelay <= game.getGameTime() ) )
	{
		m_uiTriggerTime = game.getGameTime();
		m_uiResetTime = TRIGGER_INFINITE;
	}
}

#include "level_collision.h"
#include "level_loader.h"
bool CBaseTrigger::collisionDetection( CollisionData &collData )
{
	if( m_bIsOn )
	{
		dmodel_t myModel = levelLoader.m_LevelData.models[m_SolidModel];
		if( myModel.bounds.compare( collData.model.m_DynamicBounds ) )
		{
			Creatures *creature = ((Creatures*)(collData.initiator));
			int hull = creature->getHullType();
			int response = collisionSystem.clippingHullCollision( collData.model.m_middleCenterPoint, m_SolidModel, hull );
			if( response != CONTENTS_EMPTY  )
			{
				processTrigger( creature );
				return false;
			}
			
				Vector normal = collData.normal;
				float distance = collData.distance;
				collData.distance = collData.maxdistance;
				float maxheight = collData.highestPoint;
				if(  basicSolidCollisionDetection( collData ) )
					processTrigger( creature );

				collData.normal = normal;
				collData.distance = distance;
				collData.highestPoint = maxheight;
			
		}
	}
	return false;
}


void CBaseTrigger::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;
	else
		m_BackTimeData.front().type = EVENT_TURN_ON;
	
	m_bIsOn ^= 1;	//switch on/off

}


void CBaseTrigger::goBackInTime()
{
	//musime zjistit v jakem stavu byl tento trigger
	//kdyz o tom neni zaznam, tak je stav stejny
	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 )
		{	
			m_bIsOn = true;
			return;
		}
		else if( (*riter).type == EVENT_TURN_ON )
		{
			m_bIsOn = false;
			return;
		}
	}
}
