
///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_ControlMapping_HoldKey.cpp
// Author : Andy Tate
// Date   : 5-Dec-2005
//
// Copyright (C) 2005 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "Input/Asura_ControlMapping_HoldKey.h"

// Asura independent header-files...
#include "Core/Asura_Timers.h"
#ifdef ASURA_USE_NEW_INPUT
#include "Input/Asura_ControlMap.h"
#include "Input/Asura_Input.h"
#endif
#include "Core/Asura_UserInput.h"
#include "Debugging/Asura_Assert.h"


////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMapping_HoldKey::Asura_ControlMapping_HoldKey
// Author       : Andy Tate
// Date         : 5-Dec-2005
//
// Description  : Constructor function for the hold-key control-mapping class.
//
// Parameters   : The ID of the key to check AND the minimum duration this key
//				  is to be held down before being registered as held.
//
// Return value : N/A.
////////////////////////////////////////////////////////////////////////////////

Asura_ControlMapping_HoldKey::Asura_ControlMapping_HoldKey (const int iKeyID,
															const float fMinDuration,
															const float fScale,
															const RampType eRampType,
															const KeyHoldType eHoldType) :
	Asura_ControlMapping(fScale),
	m_iKeyID(iKeyID),
	m_fMinDuration(fMinDuration),
	m_fValueToReport(0.0f),
	m_eHoldType(eHoldType),
	m_eRampType(eRampType),
	m_fCurrentDuration(0.0f)
{
	// Nothing more to initialise...
	Asura_Assert(iKeyID < MAX_NUMBER_OF_ASURA_KEYIDS, "invalid key ID");
}

/// End of function 'Asura_ControlMapping_HoldKey::Asura_ControlMapping_HoldKey'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMapping_HoldKey::UpdateValue
// Author       : Andy Tate
// Date         : 5-Dec-2005
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMapping_HoldKey::UpdateValues(const bool bActive, float& fValue, float& fHUDValue)
{
#ifdef ASURA_USE_NEW_INPUT
	const float fKeyValue = Asura_Input::GetKeyValue(m_pxOwner->GetControllerIndex(), m_iKeyID);
#else
	const int	iKeyValue	= Asura_UserInput::GetKeyValue(m_iKeyID);
	const float	fKeyValue	= static_cast<float>(iKeyValue) / 255.0f;
#endif
	const float	fOldValue	= m_fValueToReport;

	if (m_bActive || !GetPauseWhileInactive())
	{
		// Is the key held-down?
		if(fKeyValue > 0.0f)
		{
			const float	fTimeStep	= Asura_Timers::GetFrameTime();

			// Yes - update the duration...
			m_fCurrentDuration	+= fTimeStep;

			// Have we held the key down for long enough?
			if(m_fCurrentDuration >= m_fMinDuration)
			{
				// Yes - what sort of ramping are we using?
				switch(m_eRampType)
				{
					case NO_RAMPING:
					case KEY_SCALED_LINEAR_RAMPING:
					{
						m_fValueToReport	= fKeyValue;
						break;
					}

					case LINEAR_RAMPING:
					{
						m_fValueToReport	= 1.0f;
						break;
					}

					default:
					{
						Asura_Assert(false, "Unexpected hold-key ramping type specified.");
						m_fValueToReport	= 0.0f;
						break;
					}
				}		// End of switch.
			}
			else
			{
				// No - what sort of ramping are we using?
				switch(m_eRampType)
				{
					case NO_RAMPING:
					{
						m_fValueToReport	= 0.0f;
						break;
					}

					case LINEAR_RAMPING:
					{
						m_fValueToReport	= (m_fCurrentDuration / m_fMinDuration);
						break;
					}

					case KEY_SCALED_LINEAR_RAMPING:
					{
						m_fValueToReport	= fKeyValue * (m_fCurrentDuration / m_fMinDuration);
						break;
					}

					default:
					{
						Asura_Assert(false, "Unexpected hold-key ramping type specified.");
						m_fValueToReport	= 0.0f;
						break;
					}
				}		// End of switch.
			}
		}
		else
		{
			// No - reset the duration...
			m_fCurrentDuration	= 0.0f;

			// Return no value...
			if (m_eHoldType != ON_DEBOUNCED_RELEASE)
			{
				m_fValueToReport = 0.0f;
			}
		}
	}

	// Update the active flags...
	if(bActive)
	{
		if(!m_bActive && (fKeyValue == 0.0f))
		{
			m_bActive	= true;
		}
	}
	else
	{
		m_bActive	= false;
	}

	// Decide upon the value to return...
	switch(m_eHoldType)
	{
		case ON_PRESS:
		{
			fValue		= m_fValueToReport;
			fHUDValue	= m_fValueToReport;
			return;
		}

		case ON_DEBOUNCED_PRESS:
		{
			if((fKeyValue > 0.0f) && (fOldValue > 0.0f))
			{
				fValue = 0.0f;
			}
			else
			{
				fValue = m_fValueToReport;
			}

			fHUDValue	= fValue;
			return;
		}

		case ON_RELEASE:
		{
			if(fKeyValue > 0.0f)
			{
				fValue		= 0.0f;
				fHUDValue	= m_fValueToReport;
				return;
			}
			else
			{
				m_fValueToReport = 1.0f;
				fValue			= m_fValueToReport;
				fHUDValue		= m_fValueToReport;
				return;
			}
		}

		case ON_DEBOUNCED_RELEASE:
		{
			// Do we still have the key held-down?
			if(fKeyValue > 0.0f)
			{
				fValue		= 0.0f;
				fHUDValue	= m_fValueToReport;
				return;
			}
			else
			{
				// No - report the value but reset the value to report...
				fValue				= m_fValueToReport;
				fHUDValue			= m_fValueToReport;
				m_fValueToReport	= 0.0f;
				return;
			}
		}

		default:
		{
			Asura_Assert(false, "Unexpected hold type found.");
			fValue		= 0.0f;
			fHUDValue	= m_fValueToReport;
			return;
		}
	}		// End of switch.
}

/// End of function 'Asura_ControlMapping_HoldKey::UpdateValue'. ///


// Clear the stored value.
void Asura_ControlMapping_HoldKey::ResetValue()
{
	m_bActive			= false;
	m_fValueToReport	= 0.0f;
	m_fCurrentDuration	= 0.0f;
}

/// End of file. ///
