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

#include "cbase.h"
#include "entityinput.h"
#include "entityoutput.h"
#include "eventqueue.h"
#include "hl2wars/logic_rts_objectives.h"
#include "hl2wars/rts_shareddefs.h"
#include "saverestore_utlvector.h"

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

LINK_ENTITY_TO_CLASS(logic_rts_objectives, CLogicRTSObjectives);

BEGIN_SIMPLE_DATADESC( objdata_t )
	DEFINE_FIELD( m_iObjectiveID, FIELD_INTEGER ),
	DEFINE_FIELD( m_iType, FIELD_INTEGER ),	
END_DATADESC()

BEGIN_DATADESC( CLogicRTSObjectives )
	// fields
	DEFINE_KEYFIELD(m_bDisabled, FIELD_BOOLEAN, "StartDisabled"),
	DEFINE_UTLVECTOR( m_ObjectiveData, FIELD_EMBEDDED ),

	// Inputs
	DEFINE_INPUTFUNC(FIELD_VOID, "Enable", InputEnable),
	DEFINE_INPUTFUNC(FIELD_VOID, "Disable", InputDisable),
	DEFINE_INPUTFUNC(FIELD_VOID, "Toggle", InputToggle),

	DEFINE_INPUTFUNC(FIELD_INTEGER, "ObjectiveCompleted", InputObjectiveCompleted),
	DEFINE_INPUTFUNC(FIELD_INTEGER, "ObjectiveFailed", InputObjectiveFailed),
	DEFINE_INPUTFUNC(FIELD_INTEGER, "ObjectiveSetVisible", InputObjectiveSetVisible),
	DEFINE_INPUTFUNC(FIELD_INTEGER, "ObjectiveHide", InputObjectiveSetVisible),

	// Outputs
	DEFINE_OUTPUT(m_OnSpawn, "OnSpawn"),

END_DATADESC()

//-----------------------------------------------------------------------------
// Purpose: Constructor.
//-----------------------------------------------------------------------------
CLogicRTSObjectives::CLogicRTSObjectives(void)
{
}

//-----------------------------------------------------------------------------
// Purpose: Restores the current object from disk, by iterating through the objects
//			data description hierarchy
// Input  : &restore - restore buffer which the class data is read from
// Output : int	- 0 if the restore failed, 1 on success
//-----------------------------------------------------------------------------
/*int CLogicRTSObjectives::Restore( IRestore &restore )
{
	int status = BaseClass::Restore( restore );

	for( int i = 0; i < m_ObjectiveData.Count(); i++ )
	{
		IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
		if ( event )
		{
			Msg("Restoring objective, id: %d, type: %d\n", m_ObjectiveData.Element(i).m_iObjectiveID, m_ObjectiveData.Element(i).m_iType );
			event->SetInt( "objectiveID", m_ObjectiveData.Element(i).m_iObjectiveID );
			event->SetInt( "type", m_ObjectiveData.Element(i).m_iType );
			gameeventmanager->FireEvent( event );
		}		
	}

	return status;
}*/

//-----------------------------------------------------------------------------
// handler to do stuff after you are restored
//-----------------------------------------------------------------------------
void CLogicRTSObjectives::OnRestore()
{
	for( int i = 0; i < m_ObjectiveData.Count(); i++ )
	{
		IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
		if ( event )
		{
			//Msg("Restoring objective, id: %d, type: %d\n", m_ObjectiveData.Element(i).m_iObjectiveID, m_ObjectiveData.Element(i).m_iType );
			event->SetInt( "objectiveID", m_ObjectiveData.Element(i).m_iObjectiveID );
			event->SetInt( "type", m_ObjectiveData.Element(i).m_iType );
			gameeventmanager->FireEvent( event );
		}		
	}
}


//------------------------------------------------------------------------------
// Purpose: Turns on the relay, allowing it to fire outputs.
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputEnable( inputdata_t &inputdata )
{
	m_bDisabled = false;
}

//------------------------------------------------------------------------------
// Purpose: Turns off the relay, preventing it from firing outputs.
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputDisable( inputdata_t &inputdata )
{ 
	m_bDisabled = true;
}


//------------------------------------------------------------------------------
// Purpose: Toggles the enabled/disabled state of the relay.
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputToggle( inputdata_t &inputdata )
{ 
	m_bDisabled = !m_bDisabled;

	if( m_bDisabled )
		InputDisable( inputdata );
	else
        InputEnable( inputdata );
}

//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputObjectiveCompleted( inputdata_t &inputdata ) 
{
	if( m_bDisabled )
		return;

	// make sure it's an int, if it can't be converted just throw it away
	if ( !inputdata.value.Convert(FIELD_INTEGER) )
		return;

	IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
	if ( event )
	{
		event->SetInt( "objectiveID", inputdata.value.Int() );
		event->SetInt( "type", OBJECTIVE_COMPLETED );
		gameeventmanager->FireEvent( event );
	}

	// store info for restore
	objdata_t data;
	data.m_iObjectiveID = inputdata.value.Int();
	data.m_iType = OBJECTIVE_COMPLETED;
	m_ObjectiveData.AddToTail(data);
}

//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputObjectiveFailed( inputdata_t &inputdata ) 
{
	if( m_bDisabled )
		return;

	// make sure it's an int, if it can't be converted just throw it away
	if ( !inputdata.value.Convert(FIELD_INTEGER) )
		return;

	IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
	if ( event )
	{
		event->SetInt( "objectiveID", inputdata.value.Int() );
		event->SetInt( "type", OBJECTIVE_FAILED );
		gameeventmanager->FireEvent( event );
	}

	// store info for restore
	objdata_t data;
	data.m_iObjectiveID = inputdata.value.Int();
	data.m_iType = OBJECTIVE_FAILED;
	m_ObjectiveData.AddToTail(data);
}

//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputObjectiveSetVisible( inputdata_t &inputdata )
{
	if( m_bDisabled )
		return;

	// make sure it's an int, if it can't be converted just throw it away
	if ( !inputdata.value.Convert(FIELD_INTEGER) )
		return;

	IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
	if ( event )
	{
		event->SetInt( "objectiveID", inputdata.value.Int() );
		event->SetInt( "type", OBJECTIVE_SETVISIBLE );
		gameeventmanager->FireEvent( event );
	}

	// store info for restore
	objdata_t data;
	data.m_iObjectiveID = inputdata.value.Int();
	data.m_iType = OBJECTIVE_SETVISIBLE;
	m_ObjectiveData.AddToTail(data);
}

//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CLogicRTSObjectives::InputObjectiveHide( inputdata_t &inputdata )
{
	if( m_bDisabled )
		return;

	// make sure it's an int, if it can't be converted just throw it away
	if ( !inputdata.value.Convert(FIELD_INTEGER) )
		return;

	IGameEvent * event = gameeventmanager->CreateEvent( "objective_updated" );
	if ( event )
	{
		event->SetInt( "objectiveID", inputdata.value.Int() );
		event->SetInt( "type", OBJECTIVE_HIDE );
		gameeventmanager->FireEvent( event );
	}

	// store info for restore
	objdata_t data;
	data.m_iObjectiveID = inputdata.value.Int();
	data.m_iType = OBJECTIVE_HIDE;
	m_ObjectiveData.AddToTail(data);
}