/*************************************************************************
Crytek Source File.
Copyright (C), Crytek Studios, 2001-2004.
-------------------------------------------------------------------------
$Id$
$DateTime$

-------------------------------------------------------------------------
History:
- 11:9:2005   15:00 : Created by Márcio Martins

*************************************************************************/
#include "StdAfx.h"
#include "Throw.h"
#include "Actor.h"
#include "Player.h"


//------------------------------------------------------------------------
CThrow::CThrow()
{
}

//------------------------------------------------------------------------
CThrow::~CThrow()
{
}

//------------------------------------------------------------------------
void CThrow::Update(float frameTime, uint frameId)
{
	CSingle::Update(frameTime, frameId);

	if (m_firing)
	{
		if (!m_pulling && !m_throwing && !m_thrown)
		{
			if (m_auto_throw)
			{
				DoThrow();
				m_auto_throw=false;
			}
		}
		else if (m_throwing && m_throw_time<=0.0f)
		{
			m_pWeapon->HideItem(true);
			m_pWeapon->SetBusy(false);
			Shoot(true);
			m_pWeapon->SetBusy(true);
			m_throwing = false;
		}
		else if (m_thrown)
		{
			m_pWeapon->SetBusy(false);
			m_pWeapon->HideItem(false);

			int ammoCount = m_pWeapon->GetAmmoCount(m_fireparams.ammo_type.c_str());
			if (ammoCount > 0)
				m_pWeapon->PlayAction("select");
			else
				static_cast<CPlayer*>(m_pWeapon->GetOwnerActor())->SelectLastItem(true);

			m_firing = false;
			m_throwing = false;
			m_thrown = false;
		}

		m_throw_time -= frameTime;
		if (m_throw_time<0.0f)
			m_throw_time=0.0f;
	}
}

//------------------------------------------------------------------------
void CThrow::ResetParams(const struct IItemParamsNode *params)
{
	CSingle::ResetParams(params);

	const IItemParamsNode *throwp = params?params->GetChild("throw"):0;
	const IItemParamsNode *throwa = params?params->GetChild("actions"):0;

	m_throwparams.Reset(throwp);
	m_throwactions.Reset(throwa);
}

//------------------------------------------------------------------------
void CThrow::PatchParams(const struct IItemParamsNode *patch)
{
	CSingle::PatchParams(patch);

	const IItemParamsNode *throwp = patch->GetChild("throw");
	const IItemParamsNode *throwa = patch->GetChild("actions");

	m_throwparams.Reset(throwp, false);
	m_throwactions.Reset(throwa, false);
}

//------------------------------------------------------------------------
void CThrow::Activate(bool activate)
{
	CSingle::Activate(activate);

	m_thrown=false;
	m_pulling=false;
	m_throwing=false;
	m_firing=false;
	m_auto_throw=false;

	CheckAmmo();
}

//------------------------------------------------------------------------
bool CThrow::CanReload() const
{
	return CSingle::CanReload() && !m_throwing;
}

//------------------------------------------------------------------------
bool CThrow::IsReadyToFire() const
{
	return CanFire(true) && !m_firing && !m_throwing && !m_pulling && !m_thrown;
}

//------------------------------------------------------------------------
void CThrow::StartFire(EntityId shooterId)
{
	if (m_pWeapon->IsBusy())
		return;

	m_shooterId = shooterId;

	if (CanFire(true) && !m_firing && !m_throwing && !m_pulling)
	{
		m_firing = true;
		m_pulling = true;
		m_throwing = false;
		m_thrown = false;
		m_auto_throw = false;

		m_pWeapon->SetBusy(true);
		m_pWeapon->PlayAction(m_throwactions.pull.c_str());

		struct StartThrowAction: public ISchedulerAction
		{
			StartThrowAction(CThrow *_throw): pthrow(_throw) {};
			CThrow *pthrow;

			virtual void execute(CItem *_this)
			{
				pthrow->m_pulling = false;
				pthrow->m_pWeapon->PlayAction(pthrow->m_throwactions.hold.c_str(), 0, true, CItem::eIPAF_Default|CItem::eIPAF_NoBlend);
			}
		};
		m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(CItem::eIGS_FirstPerson), new StartThrowAction(this), false);
		m_pWeapon->SetDefaultIdleAnimation(CItem::eIGS_FirstPerson, m_throwactions.hold.c_str());
	}
}

//------------------------------------------------------------------------
void CThrow::StopFire(EntityId shooterId)
{
	if (m_firing)
	{
		if (!m_pulling)
		{
			m_auto_throw = false;
			DoThrow();
		}
		else
		{
			m_auto_throw = true;
		}
	}
}

//------------------------------------------------------------------------
void CThrow::CheckAmmo()
{
	m_pWeapon->HideItem(!m_pWeapon->GetAmmoCount(m_fireparams.ammo_type.c_str()) && m_throwparams.hide_ammo);
}

//------------------------------------------------------------------------
void CThrow::DoThrow()
{
	m_throw_time = m_throwparams.delay;
	m_throwing = true;
	m_thrown = false;

	m_pWeapon->PlayAction(m_throwactions.throwit.c_str());

	struct ThrowAction: public ISchedulerAction
	{
		ThrowAction(CThrow *_throw): pthrow(_throw) {};
		CThrow *pthrow;

		virtual void execute(CItem *_this)
		{
			pthrow->m_thrown = true;
		}
	};

	m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(CItem::eIGS_FirstPerson), new ThrowAction(this), false);
	m_pWeapon->SetDefaultIdleAnimation(CItem::eIGS_FirstPerson, "idle");
}

