//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: CTF Regenerate Zone.
//
//=============================================================================//

#include "cbase.h"
#include "tf_player.h"
#include "tf_item.h"
#include "tf_team.h"
#include "func_regenerate.h"
#include "tf_gamerules.h"
#include "eventqueue.h"

LINK_ENTITY_TO_CLASS( func_regenerate, CRegenerateZone );

#define TF_REGENERATE_SOUND				"Regenerate.Touch"
#define TF_REGENERATE_NEXT_USE_TIME		3.0f

//=============================================================================
//
// CTF Regenerate Zone tables.
//

BEGIN_DATADESC( CRegenerateZone )
	DEFINE_FIELD( m_hAssociatedModel, FIELD_EHANDLE ),
	DEFINE_KEYFIELD( m_iszAssociatedModel, FIELD_STRING, "associatedmodel" ),

	// Functions.
	DEFINE_FUNCTION( Touch ),
END_DATADESC();

//=============================================================================
//
// CTF Regenerate Zone functions.
//

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CRegenerateZone::CRegenerateZone()
{
	m_bDisabled = false;
}

//-----------------------------------------------------------------------------
// Purpose: Spawn function for the entity
//-----------------------------------------------------------------------------
void CRegenerateZone::Spawn( void )
{
	Precache();
	InitTrigger();
	SetTouch( &CRegenerateZone::Touch );
}

//-----------------------------------------------------------------------------
// Purpose: Precache function for the entity
//-----------------------------------------------------------------------------
void CRegenerateZone::Precache( void )
{
	PrecacheScriptSound( TF_REGENERATE_SOUND );
}

//-----------------------------------------------------------------------------
// Purpose: Precache function for the entity
//-----------------------------------------------------------------------------
void CRegenerateZone::Activate( void )
{
	BaseClass::Activate();

	if ( m_iszAssociatedModel != NULL_STRING )
	{
		CBaseEntity *pEnt = gEntList.FindEntityByName( NULL, STRING(m_iszAssociatedModel) );
		if ( !pEnt )
		{
			Warning("%s(%s) unable to find associated model named '%s'.\n", GetClassname(), GetDebugName(), STRING(m_iszAssociatedModel) );
		}
		else
		{
			m_hAssociatedModel = dynamic_cast<CDynamicProp*>(pEnt);
			if ( !m_hAssociatedModel )
			{
				Warning("%s(%s) tried to use associated model named '%s', but it isn't a dynamic prop.\n", GetClassname(), GetDebugName(), STRING(m_iszAssociatedModel) );
			}
		}	
	}
	else
	{
		Warning("%s(%s) has no associated model.\n", GetClassname(), GetDebugName() );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRegenerateZone::Touch( CBaseEntity *pOther )
{
	if ( !IsDisabled() )
	{
		CTFPlayer *pPlayer = ToTFPlayer( pOther );
		if ( pPlayer )
		{
			if ( pPlayer->GetNextRegenTime() > gpGlobals->curtime )
				return;

			if ( pPlayer->IsTaunting() )
				return;

			int iTeam = GetTeamNumber();

			if ( TFGameRules()->State_Get() != GR_STATE_TEAM_WIN )
			{
				if ( iTeam && ( pPlayer->GetTeamNumber() != iTeam ) )
					return;
			}
			else
			{
				// no health for the losing team, but all zones work for the winning team
				if ( TFGameRules()->GetWinningTeam() != pPlayer->GetTeamNumber() )
					return;
			}

			if ( TFGameRules()->InStalemate() )
				return;

			Regenerate( pPlayer );

#ifdef STAGING_ONLY
			if ( TFGameRules() && TFGameRules()->IsBountyMode() )
			{
				pPlayer->m_Shared.SetInUpgradeZone( true );
			}
#endif // STAGING_ONLY
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRegenerateZone::EndTouch( CBaseEntity *pOther )
{
	if ( pOther->IsPlayer() )
	{
		CTFPlayer *pTFPlayer = ToTFPlayer( pOther );
		if ( pTFPlayer )
		{
			pTFPlayer->m_Shared.SetInUpgradeZone( false );
		}
	}

	BaseClass::EndTouch( pOther );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRegenerateZone::InputEnable( inputdata_t &inputdata )
{
	SetDisabled( false );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRegenerateZone::InputDisable( inputdata_t &inputdata )
{
	SetDisabled( true );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CRegenerateZone::IsDisabled( void )
{
	return m_bDisabled;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRegenerateZone::InputToggle( inputdata_t &inputdata )
{
	if ( m_bDisabled )
	{
		SetDisabled( false );
	}
	else
	{
		SetDisabled( true );
	}
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRegenerateZone::SetDisabled( bool bDisabled )
{
	m_bDisabled = bDisabled;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CRegenerateZone::Regenerate( CTFPlayer *pPlayer )
{
	pPlayer->Regenerate();
	pPlayer->SetNextRegenTime( gpGlobals->curtime + TF_REGENERATE_NEXT_USE_TIME );

	CSingleUserRecipientFilter filter( pPlayer );
	EmitSound( filter, pPlayer->entindex(), TF_REGENERATE_SOUND );

	if ( m_hAssociatedModel )
	{
		variant_t tmpVar;
		tmpVar.SetString( MAKE_STRING("open") );
		m_hAssociatedModel->AcceptInput( "SetAnimation", this, this, tmpVar, 0 );

		tmpVar.SetString( MAKE_STRING("close") );
		g_EventQueue.AddEvent( m_hAssociatedModel, "SetAnimation", tmpVar, TF_REGENERATE_NEXT_USE_TIME - 1.0, this, this );
	}
}