// Intensity
// -John Newfield

#include "StdAfx.h"
#include "Intensity.h"
#include "Actor.h"
#include "Player.h"

//----------------------------------------------------------
CIntensity::CIntensity(CActor *owner) : 
	m_owner(owner),
	m_fStartFOV(1.0f),
	m_fGoalFOV(1.0f),
	m_fBaseZoomTime(10.0f),
	m_bForce(false),
	m_bEnabled(true),
	m_bDone(true)
{
}

//----------------------------------------------------------
CIntensity::~CIntensity(void)
{
}

//----------------------------------------------------------
void CIntensity::ChangeFOV(float goalfov, float time, bool force, float baseZoomDiff)
{
	// Only allowed to change if we're not being forced to zoom and we're enabled
	if (!m_bForce && m_bEnabled)
	{
		// Start wherever the FOV is currently at
		SPlayerParams *pActorParams = static_cast<SPlayerParams *>(m_owner->GetActorParams());
		m_fStartFOV = pActorParams->viewFoVScale;
		m_fGoalFOV = goalfov;

		// baseZoomDiff allows us to zoom at a particular rate regardless of where we start in the zoom.
		// Basically, it allows you to achieve a certain zoom per second rate given a goal and zoom time
		//  and an assumed zoom difference.
		if (baseZoomDiff != 0.0f)
		{
			m_fBaseZoomTime = fabs(((m_fGoalFOV - m_fStartFOV) / (baseZoomDiff)) * time);
		}
		else
		{
			m_fBaseZoomTime = time;
		}
		m_bForce = force;
		m_bDone = false;
	}
}

//----------------------------------------------------------
void CIntensity::Enable(bool enable)
{
	m_bEnabled = enable;
}

//----------------------------------------------------------
// Update the zoom level
void CIntensity::Update(float frameTime)
{
	// Don't mess around with the zoom if we're disabled and have no current zooming to do
	if (!m_bEnabled && !m_bForce)
		return;

	SPlayerParams *pActorParams = static_cast<SPlayerParams *>(m_owner->GetActorParams());
	float current_fov = pActorParams->viewFoVScale;
	float fovdiff = m_fGoalFOV - current_fov;

	// If zoom is not at or close to the goal zoom, and this is not an instant snap zoom...
	if (fabs(fovdiff) > 0.001f && m_fBaseZoomTime != 0.0f)
	{
		float zoomtimeremaining = 0.0f;		// ETA on hitting the goal zoom level
		if ((m_fGoalFOV - m_fStartFOV) != 0.0f)
			zoomtimeremaining = (fovdiff / (m_fGoalFOV - m_fStartFOV)) * m_fBaseZoomTime;
		float q = 0.0f;		// Quotient of FOV to apply this frame.
		if (zoomtimeremaining != 0.0f)
			q = (frameTime / zoomtimeremaining) * fovdiff;

		// If this quotient will take us beyond the goal FOV, just set FOV to goal FOV
		if (((q < 0.0f) && (current_fov + q < m_fGoalFOV)) || ((q > 0.0f && current_fov + q > m_fGoalFOV)))
			pActorParams->viewFoVScale = m_fGoalFOV;
		else
			pActorParams->viewFoVScale += q;
	}
	else
	{
		pActorParams->viewFoVScale = m_fGoalFOV;
		// When we've reached the goal zoom, we're done forcing
		m_bForce = false;
		m_bDone = true;
	}
}

//----------------------------------------------------------
void CIntensity::Reset()
{
	SPlayerParams *pActorParams = static_cast<SPlayerParams *>(m_owner->GetActorParams());
	pActorParams->viewFoVScale = 1.0f;
	m_fStartFOV = 1.0f;
	m_fGoalFOV = 1.0f;
	m_fBaseZoomTime = 10.0f;
	m_bForce = false;
	m_bEnabled = true;
	m_bDone = true;
}

//----------------------------------------------------------
float CIntensity::GetCurrentFOV()
{
	SPlayerParams *pActorParams = static_cast<SPlayerParams *>(m_owner->GetActorParams());
	return pActorParams->viewFoVScale;
}