//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: NPC Puppet
//
//=============================================================================

#include "cbase.h"
#include "ai_basenpc.h"

// Must be the last file included
#include "memdbgon.h"

class CNPC_Puppet : public CAI_BaseNPC
{
	DECLARE_CLASS( CNPC_Puppet, CAI_BaseNPC );
public:

	virtual void Spawn( void );
	virtual void Precache( void );

	void	InputSetAnimationTarget( inputdata_t &inputdata );

private:
	
	string_t	m_sAnimTargetname;
	string_t	m_sAnimAttachmentName;

	CNetworkVar( EHANDLE, m_hAnimationTarget );	// NPC that will drive what animation we're playing
	CNetworkVar( int, m_nTargetAttachment );	// Attachment point to match to on the target

	DECLARE_DATADESC();
	DECLARE_SERVERCLASS();
};

LINK_ENTITY_TO_CLASS( npc_puppet, CNPC_Puppet );

BEGIN_DATADESC( CNPC_Puppet )
	DEFINE_KEYFIELD( m_sAnimTargetname, FIELD_STRING,	"animationtarget" ),
	DEFINE_KEYFIELD( m_sAnimAttachmentName, FIELD_STRING,	"attachmentname" ),

	DEFINE_FIELD( m_nTargetAttachment, FIELD_INTEGER ),
	DEFINE_FIELD( m_hAnimationTarget, FIELD_EHANDLE ),
	DEFINE_INPUTFUNC( FIELD_STRING, "SetAnimationTarget", InputSetAnimationTarget ),
END_DATADESC()

IMPLEMENT_SERVERCLASS_ST( CNPC_Puppet, DT_NPC_Puppet )
	SendPropEHandle( SENDINFO( m_hAnimationTarget ) ),
	SendPropInt( SENDINFO( m_nTargetAttachment) ),
END_SEND_TABLE()

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Puppet::Precache( void )
{
	BaseClass::Precache();
	PrecacheModel( STRING( GetModelName() ) );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Puppet::Spawn( void )
{
	BaseClass::Spawn();

	Precache();

	SetModel( STRING( GetModelName() ) );
	
	NPCInit();

	SetHealth( 100 );

	// Find our animation target
	CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_sAnimTargetname );
	m_hAnimationTarget = pTarget;
	if ( pTarget )
	{
		CBaseAnimating *pAnimating = pTarget->GetBaseAnimating();
		if ( pAnimating )
		{
			m_nTargetAttachment = pAnimating->LookupAttachment( STRING( m_sAnimAttachmentName ) );
		}
	}

	// Always be scripted
	SetInAScript( true );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &inputdata - 
//-----------------------------------------------------------------------------
void CNPC_Puppet::InputSetAnimationTarget( inputdata_t &inputdata )
{
	// Take the new name
	m_sAnimTargetname = MAKE_STRING( inputdata.value.String() );

	// Find our animation target
	CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_sAnimTargetname );
	if ( pTarget == NULL )
	{
		Warning("Failed to find animation target %s for npc_puppet (%s)\n", STRING( m_sAnimTargetname ), STRING( GetEntityName() ) );
		return;
	}
	
	m_hAnimationTarget = pTarget;
	
	CBaseAnimating *pAnimating = pTarget->GetBaseAnimating();
	if ( pAnimating )
	{
		// Cache off our target attachment
		m_nTargetAttachment = pAnimating->LookupAttachment( STRING( m_sAnimAttachmentName ) );
	}

	// Stuff us at the owner's core for visibility reasons
	SetParent( pTarget );
	SetLocalOrigin( vec3_origin );
	SetLocalAngles( vec3_angle );
}