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

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

#include "Core/Asura.h"

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

// Asura independent header-files...
#include "Core/Asura_Maths.h"
#include "Input/Asura_ControlMapping_Axis.h"
#include "Input/Asura_ControlMapping_HoldKey.h"
#include "Input/Asura_ControlMapping_Key.h"
#include "Input/Asura_ControlMapping_TapAxis.h"
#include "Input/Asura_ControlMapping_TapKey.h"

// Asura platform header-files...

// Tools header-files...


////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Private functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Protected functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::StoreMapping
// Author       : Andy Tate
// Date         : 6-Jan-2006
//
// Description  : Stores the specified mapping at the end of the appropriate
//				  mapping-list.
//
// Parameters   : The index of the mapping to store, a pointer to the mapping.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::StoreMapping(const u_int uMapping,
									 Asura_ControlMapping* pxMapping)
{
	Asura_Assert( (uMapping < m_uNumberOfMappings), "Requested mapping is greater than the number of mappings available. Cannot store mapping." );
	if( uMapping < m_uNumberOfMappings )
	{
		Asura_ControlMapping*	pxPreviousMapping	= NULL;
		Asura_ControlMapping*	pxCurrentMapping	= m_ppxMappings[uMapping];

		// Find the end of the list...
		while(pxCurrentMapping != NULL)
		{
			pxPreviousMapping	= pxCurrentMapping;
			pxCurrentMapping	= pxCurrentMapping->GetNextMapping();
		}

	#ifdef ASURA_USE_NEW_INPUT
		pxMapping->SetOwner(this);
	#endif

		// Did we have a previous mapping?
		if(pxPreviousMapping == NULL)
		{
			m_ppxMappings[uMapping]	= pxMapping;
		}
		else
		{
			pxPreviousMapping->SetNextMapping(pxMapping);
		}
	}
}

/// End of function 'Asura_ControlMap::StoreMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Public functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::Asura_ControlMap
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Constructor function for the control-map class.
//
// Return value : N/A.
////////////////////////////////////////////////////////////////////////////////

Asura_ControlMap::Asura_ControlMap(void)
:
#ifdef ASURA_USE_NEW_INPUT
m_uControllerIndex(0),
#endif //#ifdef ASURA_USE_NEW_INPUT
m_bActive(true)
, m_uNumberOfMappings(0)
, m_ppxMappings(NULL)
, m_pfScales(NULL)
, m_pfValues(NULL)
, m_pfHUDValues(NULL)
{
	// Nothing more to initialise...
}

/// End of function 'Asura_ControlMap::Asura_ControlMap'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::Asura_ControlMap
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Constructor function for the control-map class.
//
// Parameters   : The number of control mappings to be made.
//
// Return value : N/A.
////////////////////////////////////////////////////////////////////////////////

Asura_ControlMap::Asura_ControlMap(const u_int uNumberOfMappings)
:
#ifdef ASURA_USE_NEW_INPUT
m_uControllerIndex(0),
#endif //#ifdef ASURA_USE_NEW_INPUT
m_bActive(true)
, m_uNumberOfMappings(0)
, m_ppxMappings(NULL)
, m_pfScales(NULL)
, m_pfValues(NULL)
, m_pfHUDValues(NULL)
{
	// Create the mappings...
	CreateMappings(uNumberOfMappings);
}

/// End of function 'Asura_ControlMap::Asura_ControlMap'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::~Asura_ControlMap
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Destructor function for the control-map class.
//
// Return value : N/A.
////////////////////////////////////////////////////////////////////////////////

Asura_ControlMap::~Asura_ControlMap ()
{
	// Destroy the mappings...
	DeleteMappings();
}

/// End of function 'Asura_ControlMap::~Asura_ControlMap'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::CreateMappings
// Author       : Andy Tate
// Date         : 10-Jan-2006
//
// Description  : Creates a new array of control mappings...
//
// Parameters   : The number of mappings to be created.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::CreateMappings(const u_int uNumberOfMappings)
{
	// Do we already have mappings?
	if (m_ppxMappings == NULL)
	{
		// Allocate the array of mappings...
		m_uNumberOfMappings	= uNumberOfMappings;
		m_ppxMappings		= new Asura_ControlMapping* [uNumberOfMappings];
		m_pfScales			= new float [uNumberOfMappings];
		m_pfValues			= new float [uNumberOfMappings];
		m_pfHUDValues		= new float [uNumberOfMappings];

		// Initialise the values...
		for(u_int u = 0; u < uNumberOfMappings; u++)
		{
			m_ppxMappings[u]	= NULL;
			m_pfScales[u]		= 1.0f;
			m_pfValues[u]		= 0.0f;
			m_pfHUDValues[u]	= 0.0f;
		}
	}
	else
	{
		Asura_Assert(false, "We already have a control map allocated.");
	}
}

/// End of function 'Asura_ControlMap::CreateMappings'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::DeleteMappings
// Author       : Andy Tate
// Date         : 10-Jan-2006
//
// Description  : Deletes all of the control mappings.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::DeleteMappings(void)
{
	// Do we have any mappings?
	if(m_ppxMappings != NULL)
	{
		// Destroy the individual mappings...
		for(u_int u = 0; u < m_uNumberOfMappings; u++)
		{
			delete(m_ppxMappings[u]);
		}
	}

	// Destroy the arrays...
	delete[](m_ppxMappings);
	delete[](m_pfScales);
	delete[](m_pfValues);
	delete[](m_pfHUDValues);

	// Reset the variables...
	m_uNumberOfMappings	= 0;
	m_ppxMappings		= NULL;
	m_pfScales			= NULL;
	m_pfValues			= NULL;
	m_pfHUDValues		= NULL;
}

/// End of function 'Asura_ControlMap::DeleteMappings'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddAxisMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Creates a mapping onto the specified axis.
//
// Parameters   : The ID of the mapping and the axis this ID maps to.
//
// Return value : None.
//
// Usage : 1) If no response time is specified, the returned value for the axis will be
//			that of the stick/mouse. Gives a crisp axis control.
//		   2) If a response time is specified (& no decay) the returned value will take 
//			this long to build up (to max) when the stick/mouse is pressed & this long 
//          again to decay when the stick/mouse is released. Gives an axis laggy behaviour.
//		   3) If a decay time is given as well, the axis behaves as in 2) but now the user 
//			can now control the rate of decay when the stick/mouse is released.
//
//////////////////////////////////////////////////////////////////////////////////


void Asura_ControlMap::AddAxisMapping(const u_int uMapping,
#ifdef ASURA_USE_NEW_INPUT
									   const u_int uPositiveID,
									   const u_int uNegativeID, 
#else
									   const int iAxisID,
#endif
									   const float fScale,
									   const float fResponseTime,
									   const float fDecayTime,
									   const ASURA_CONTROLMAPPING_AXIS_MASK eSection,
									   const float fExponent)
{
#ifdef ASURA_USE_NEW_INPUT
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_Axis (uPositiveID, uNegativeID, fScale, fResponseTime, fDecayTime, eSection, fExponent);
#else
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_Axis (iAxisID, fScale, fResponseTime, fDecayTime, eSection, fExponent);
#endif

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddAxisMapping'. ///

void Asura_ControlMap::AddAxisMapping(const u_int uMapping,
#ifdef ASURA_USE_NEW_INPUT
									   const u_int uPositiveID,
									   const u_int uNegativeID, 
#else
									   const int iAxisID,
#endif
									   const float fScale,
									   const float* const pfResponseTime,
									   const float* const pfDecayTime,
									   const ASURA_CONTROLMAPPING_AXIS_MASK eSection,
									   const float* const pfExponent)
{
#ifdef ASURA_USE_NEW_INPUT
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_Axis (uPositiveID, uNegativeID, fScale, pfResponseTime, pfDecayTime, eSection, pfExponent);
#else
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_Axis (iAxisID, fScale, pfResponseTime, pfDecayTime, eSection, pfExponent);
#endif

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddAxisMapping'. ///


////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddKeyMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Creates a mapping onto the specified key.
//
// Parameters   : The ID of the mapping and the key this ID maps to.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddKeyMapping(const u_int uMapping,
									  const int iKeyID,
									  const Asura_ControlMapping::KeyHoldType eHoldType,
									  const float fScale)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_Key (iKeyID, eHoldType, fScale);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddKeyMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddHoldKeyMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Creates a mapping onto the specified key being held down.
//
// Parameters   : The ID of the mapping, the key this ID maps to AND the duration
//				  this key must be held down for before being confirmed.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddHoldKeyMapping(const u_int uMapping,
										  const int iKeyID,
										  const float fMinDuration,
										  const float fScale,
										  const Asura_ControlMapping_HoldKey::RampType eRampType,
										  const Asura_ControlMapping::KeyHoldType eHoldType)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_HoldKey (iKeyID, fMinDuration, fScale, eRampType, eHoldType);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddHoldKeyMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddTapKeyMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Creates a mapping onto the specified key being tapped.
//
// Parameters   : The ID of the mapping, the key this ID maps to AND the duration
//				  this key must be held down for before being confirmed.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddTapKeyMapping(const u_int uMapping,
									     const int iKeyID,
									     const float fMaxPressDuration,
									     const float fScale)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_TapKey (iKeyID, fMaxPressDuration, fScale);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddTapKeyMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddTapKeyMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Creates a mapping onto the specified key being tapped.
//
// Parameters   : The ID of the mapping, the key this ID maps to AND the duration
//				  this key must be held down for before being confirmed.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddTapKeyMapping(const u_int uMapping,
									     const int iKeyID,
									     const u_int uNumTaps,
									     const Asura_ControlMapping::KeyHoldType eHoldType,
									     const float fMaxPressDuration,
									     const float fMaxReleaseDuration,
									     const float fScale)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_TapKey (iKeyID, uNumTaps, eHoldType, fMaxPressDuration, fMaxReleaseDuration, fScale);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddTapKeyMapping'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddTapAxisMapping
// Author       : Anthony Gregson
// Date         : 07/06/06
//
// Description  : Creates a mapping onto the specified axis being tapped.
//
// Parameters   : The ID of the mapping, the axis this ID maps to AND the duration
//				  this key must be held down for before being confirmed.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddTapAxisMapping(const u_int uMapping,
									      const int iKeyID,
									      const float fMaxPressDuration,
									      const float fTapRegisterThreshold,
									      const float fScale)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_TapAxis(iKeyID, fMaxPressDuration, fTapRegisterThreshold, fScale);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddTapAxisMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddTapAxisMapping
// Author       : Anthony Gregson
// Date         : 07/06/06
//
// Description  : Creates a mapping onto the specified axis being tapped.
//
// Parameters   : The ID of the mapping, the axis this ID maps to AND the duration
//				  this key must be held down for before being confirmed.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddTapAxisMapping(const u_int uMapping,
									      const int iKeyID,
									      const u_int uNumTaps,
									      const Asura_ControlMapping::KeyHoldType eHoldType,
									      const float fMaxPressDuration,
									      const float fMaxReleaseDuration,
									      const float fTapRegisterThreshold,
									      const float fScale)
{
	Asura_ControlMapping*	pxMapping	= new Asura_ControlMapping_TapAxis(iKeyID, uNumTaps, eHoldType, fMaxPressDuration, fMaxReleaseDuration, fTapRegisterThreshold, fScale);

	// Store this mapping...
	StoreMapping(uMapping, pxMapping);
}

/// End of function 'Asura_ControlMap::AddTapAxisMapping'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::AddCombinationMapping
// Author       : Andy McCabe
// Date         : 9-Sep-2006
//
// Description  : Adds a combined mapping, which is combination of two mappings.
//
// Parameters   : The ID of the mapping, and a reference to the combination mapping.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::AddCombinationMapping(const u_int uMapping, 
											  Asura_ControlMapping_Combination* pxCombinationMapping)
{
	// Store this mapping...
	StoreMapping(uMapping, pxCombinationMapping);
}

/// End of function 'Asura_ControlMap::Asura_ControlMap::AddCombinationMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::DeleteMapping
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Deletes the specified mapping.
//
// Parameters   : The mapping to delete.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::DeleteMapping(const u_int uMapping)
{
	// Delete and reset the pointer...
	delete(m_ppxMappings[uMapping]);

	m_ppxMappings[uMapping]	= NULL;
}

/// End of function 'Asura_ControlMap::DeleteMapping'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::Activate
// Author       : Andy Tate
// Date         : 27-Jul-2007
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::Activate(void)
{
	if(!m_bActive)
	{
		m_bActive	= true;
	}
}

/// End of function 'Asura_ControlMap::Activate'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::Update
// Author       : Andy Tate
// Date         : 1-Dec-2005
//
// Description  : Handles the update of all mappings associated with this
//				  control map.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::Update(void)
{
	// Do we have anything to update?
	if(m_ppxMappings != NULL)
	{
		// Yes - update each mapping in-turn...
		for(u_int u = 0; u < m_uNumberOfMappings; u++)
		{
			Asura_ControlMapping*	pxMapping	= m_ppxMappings [u];
			float					fMax		= 0.0f;
			float					fMin		= 0.0f;
			float					fHUDTotal	= 0.0f;

			// Do we have a mapping here?
			while(pxMapping != NULL)
			{
				const float	fScale	= pxMapping->GetScale();

				float		fValue;
				float		fHUDValue;

				// Fetch the values...
				pxMapping->UpdateValues(m_bActive, fValue, fHUDValue);

				// Should we be accumulating these values?
				if(pxMapping->IsActive())
				{
					const float	fTotal	= (fValue * fScale);

					// Accumulate values...
					if( fTotal >= 0.0f )
					{
						fMax = Asura_Maths::Max( fMax, fTotal );
					}
					else
					{
						fMin = Asura_Maths::Min( fMin, fTotal );
					}

					// Accumulate the HUD values...
					fHUDTotal	+= (fHUDValue * fScale);
				}

				// Try the next mapping...
				pxMapping	= pxMapping->GetNextMapping();
			}

			// scale the values
			m_pfValues[u]		 = fMin + fMax;
			m_pfValues[u]		*= m_pfScales[u];

			m_pfHUDValues[u]	 = Asura_Maths::ClampToRange(fHUDTotal, -1.0f, 1.0f);
		}
	}
}

/// End of function 'Asura_ControlMap::Update'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::Deactivate
// Author       : Andy Tate
// Date         : 27-Jul-2007
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::Deactivate(void)
{
	if(m_bActive)
	{
		m_bActive	= false;
	}
}

/// End of function 'Asura_ControlMap::Deactivate'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::GetValue
// Author       : Andy Tate
// Date         : 23-May-2007
////////////////////////////////////////////////////////////////////////////////

float Asura_ControlMap::GetValue( const u_int uMapping ) const
{
	if(uMapping < m_uNumberOfMappings)
	{
		return(m_pfValues[uMapping]);
	}
	else
	{
		Asura_Assert(false, "Control map index is out of range.");
		return(0.0f);
	}
}

/// End of function 'Asura_ControlMap::GetValue'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::GetHUDValue
// Author       : Neil Young
// Date         : 2-May-2006
//
// Description  : Gets the "working" (internal) value of a control, for the hud.
//				  Used for charge-up controls, where the game only needs the value when it's released,
//				  but the hud needs it while it charges
//
// Return value : Value to display on hud.
////////////////////////////////////////////////////////////////////////////////

float Asura_ControlMap::GetHUDValue(const u_int uMapping) const
{
	if(uMapping < m_uNumberOfMappings)
	{
		return(m_pfHUDValues[uMapping]);
	}
	else
	{
		Asura_Assert(false, "Control map index is out of range.");
		return(0.0f);
	}
}

/// End of function 'Asura_ControlMap::GetHUDValue'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::ResetValues
// Author       : Anthony Gregson
// Date         : 28/07/06
//
// Description  : Clears the inputs, returns the mappings to their default states.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::ResetValues(void)
{
	// Do we have anything to clear?
	if(m_ppxMappings)
	{
		// Yes - reset each mapping in-turn...
		for(u_int u = 0; u < m_uNumberOfMappings; u++)
		{
			Asura_ControlMapping*	pxMapping	= m_ppxMappings[u];

			// Do we have a mapping here?
			while(pxMapping != NULL)
			{
				pxMapping->ResetValue();

				// Try the next mapping...
				pxMapping	= pxMapping->GetNextMapping();
			}

			m_pfValues[u]		= 0.0f;
			m_pfHUDValues[u]	= 0.0f;
		}
	}
}

/// End of function 'Asura_ControlMap::ResetValues'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::ResetValue
// Author       : Richard May
// Date         : 13/12/06
//
// Description  : Resets a specific mapping and it's associated value
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_ControlMap::ResetValue(const u_int uMapping)
{
	// Do we have anything to clear?
	if(m_ppxMappings)
	{
		Asura_ControlMapping*	pxMapping	= m_ppxMappings[uMapping];

		// Do we have a mapping here?
		while(pxMapping != NULL)
		{
			pxMapping->ResetValue();

			// Try the next mapping...
			pxMapping	= pxMapping->GetNextMapping();
		}

		m_pfValues[uMapping]	= 0.0f;
		m_pfHUDValues[uMapping]	= 0.0f;
	}
}

/// End of function 'Asura_ControlMap::ResetValues'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_ControlMap::GetNumMappingsOfType
// Author       : Callum Hope
// Date         : 30-Oct-2008
//
// Description  : Returns the number of mappings stored for an individual mapping type. 
//
// Parameters   : The enum value and hence the array index of the mapping type. 
//
// Return value : the number of mappings stored for the mapping type
////////////////////////////////////////////////////////////////////////////////

u_int Asura_ControlMap::GetNumMappingsOfType( const u_int uMapping ) const
{
	Asura_Assert( (uMapping < m_uNumberOfMappings), "Requested mapping is greater than the number of mappings available. Can't find number of mappings requested." );

	u_int uCount = 0;

	if( uMapping < m_uNumberOfMappings )
	{
		Asura_ControlMapping* pxCurrentMapping = m_ppxMappings[uMapping];
		while ( pxCurrentMapping != NULL )
		{
			pxCurrentMapping = pxCurrentMapping->GetNextMapping();
			++uCount;
		}
	}

	return uCount;
}

/// End of function 'Asura_ControlMap::GetNumMappingsOfType'. ///

/// End of file. ///
