///////////////////////////////////////////////////////////////////////////////
//
// File      : Asura_Platform_RumbleSystem.cpp
// Author    : Philip Hall
// Created   : 10/10/2007
//
// Copyright (C) 2007 Rebellion. All Rights Reserved
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

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

// Optionally include file contents
#if (defined ASURA_SUPPORT_CONTROLLER_RUMBLE) && (ASURA_SUPPORT_CONTROLLER_RUMBLE != 0)

// Asura headers
#include "Debugging/Asura_Assert.h"
#include "Debugging/Asura_Logfile.h"
#include "Input/Asura_Rumble_System.h"

// Asura PS3 headers
#include "Input/Asura_PS3_USBPad.h"


Asura_Platform_Rumble* Asura_Rumble_System::ASURA_STANDARD_RUMBLE_EXPLOSION = NULL;
Asura_Platform_Rumble* Asura_Rumble_System::ASURA_STANDARD_RUMBLE_SINGLESHOT = NULL;
Asura_Platform_Rumble* Asura_Rumble_System::ASURA_STANDARD_RUMBLE_HEARTBEAT = NULL;
Asura_Platform_Rumble* Asura_Rumble_System::ASURA_STANDARD_RUMBLE_HIT = NULL;


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Asura_Rumble_System::Platform_Initialise
// Description : Initialise basic platform rumbles (taken from PS2 and
//               tweaked slightly)
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void Asura_Rumble_System::Platform_Initialise()
{
	// Shot
	Asura_Handle iSingleShotSlowMotor = Asura_Rumble::CreateAsuraRumble(RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 1.0f, 0.0f, 2.5f, 1);
	Asura_Handle iSingleShotRumble = s_pxDynamicPlatformRumbleList->Allocate();
	ASURA_STANDARD_RUMBLE_SINGLESHOT = s_pxDynamicPlatformRumbleList->GetPointer(iSingleShotRumble);
    ASURA_STANDARD_RUMBLE_SINGLESHOT->m_apxMotorRumbles[ASURA_PS3_SMALL_MOTOR] = NULL;
	ASURA_STANDARD_RUMBLE_SINGLESHOT->m_apxMotorRumbles[ASURA_PS3_LARGE_MOTOR] = Asura_Rumble::GetRumblePointer(iSingleShotSlowMotor);
	
	ASURA_STANDARD_RUMBLE_HIT = ASURA_STANDARD_RUMBLE_SINGLESHOT;
	ASURA_STANDARD_RUMBLE_EXPLOSION = ASURA_STANDARD_RUMBLE_SINGLESHOT;
	ASURA_STANDARD_RUMBLE_HEARTBEAT = ASURA_STANDARD_RUMBLE_SINGLESHOT;
	
	// Hit	
	Asura_Handle iHitSlowMotor = Asura_Rumble::CreateAsuraRumble(RUMBLE_BASE_LINEAR, RUMBLE_ADJUST_REVERSE, 0.75f, 0.0f, 1.0f, 1);
	Asura_Handle iHitRumble = s_pxDynamicPlatformRumbleList->Allocate();
	ASURA_STANDARD_RUMBLE_HIT = s_pxDynamicPlatformRumbleList->GetPointer(iHitRumble);
    ASURA_STANDARD_RUMBLE_HIT->m_apxMotorRumbles[ASURA_PS3_SMALL_MOTOR] = NULL;
	ASURA_STANDARD_RUMBLE_HIT->m_apxMotorRumbles[ASURA_PS3_LARGE_MOTOR] = Asura_Rumble::GetRumblePointer(iHitSlowMotor);

	// Explosion
	Asura_Handle iExplosionFastMotor = Asura_Rumble::CreateAsuraRumble(RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 1.0f, 0.0f, 2.5f, 1);
	Asura_Rumble::AddRumbleStep(iExplosionFastMotor, RUMBLE_BASE_LINEAR, RUMBLE_ADJUST_REVERSE, 1.0f, 0.0f, 1.0f, 1);
	Asura_Handle iExplosionSlowMotor = Asura_Rumble::CreateAsuraRumble(RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 1.0f, 0.0f, 2.5f, 1);
	Asura_Rumble::AddRumbleStep(iExplosionSlowMotor, RUMBLE_BASE_LINEAR, RUMBLE_ADJUST_REVERSE, 1.0f, 0.0f, 0.5f, 1);
	Asura_Handle iExplosionRumble = s_pxDynamicPlatformRumbleList->Allocate();
	ASURA_STANDARD_RUMBLE_EXPLOSION = s_pxDynamicPlatformRumbleList->GetPointer(iExplosionRumble);
	ASURA_STANDARD_RUMBLE_EXPLOSION->m_apxMotorRumbles[ASURA_PS3_SMALL_MOTOR] = Asura_Rumble::GetRumblePointer(iExplosionFastMotor);
	ASURA_STANDARD_RUMBLE_EXPLOSION->m_apxMotorRumbles[ASURA_PS3_LARGE_MOTOR] = Asura_Rumble::GetRumblePointer(iExplosionSlowMotor);

	// Heartbeat
	Asura_Handle iHeartbeatSlowMotor = Asura_Rumble::CreateAsuraRumble(RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 0.0f, 0.0f, 5.0f, 1);
	Asura_Rumble::AddRumbleStep(iHeartbeatSlowMotor, RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 0.3f, 0.0f, 2.0f, 1);
	Asura_Rumble::AddRumbleStep(iHeartbeatSlowMotor, RUMBLE_BASE_CONSTANT, RUMBLE_ADJUST_NONE, 0.0f, 0.0f, 1.0f, 1);
	Asura_Handle iHeartbeatRumble = s_pxDynamicPlatformRumbleList->Allocate();
	ASURA_STANDARD_RUMBLE_HEARTBEAT = s_pxDynamicPlatformRumbleList->GetPointer(iHeartbeatRumble);
    ASURA_STANDARD_RUMBLE_HEARTBEAT->m_apxMotorRumbles[ASURA_PS3_SMALL_MOTOR] = NULL;
	ASURA_STANDARD_RUMBLE_HEARTBEAT->m_apxMotorRumbles[ASURA_PS3_LARGE_MOTOR] = Asura_Rumble::GetRumblePointer(iHeartbeatSlowMotor);
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Asura_Rumble_System::Platform_Shutdown
// Description : Shutdown and clean up the PS3 specific rumble system
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void Asura_Rumble_System::Platform_Shutdown()
{
	Platform_StopAllRumbles();
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Asura_Rumble_System::Platform_Reset
// Description : Reset the PS3 specific rumble system
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void Asura_Rumble_System::Platform_Reset()
{
	Platform_StopAllRumbles();
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Asura_Rumble_System::Platform_PlayCurrentRumbles
// Description : Play the current rumble values
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void Asura_Rumble_System::Platform_PlayCurrentRumbles()
{
    for (int iCurrentSlot = 0; iCurrentSlot < Asura_PS3_Input::GetAPI().GetMaxControllers(); iCurrentSlot++)
    {
		Asura_PS3_USBPad* pxController = Asura_PS3_Input::GetAPI().GetController(iCurrentSlot);
		if ( (pxController != NULL) && pxController->IsConnectedAndSupported() )
		{
			pxController->SetMotorSpeeds(s_fCurrentMotorMagnitudes[iCurrentSlot][ASURA_PS3_SMALL_MOTOR],
			                             s_fCurrentMotorMagnitudes[iCurrentSlot][ASURA_PS3_LARGE_MOTOR]);
		}
    }
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Asura_Rumble_System::Platform_StopAllRumbles
// Description : Directly stop the rumbles in progress on any connected controller
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void Asura_Rumble_System::Platform_StopAllRumbles()
{
    for (int iCurrentSlot = 0; iCurrentSlot < Asura_PS3_Input::GetAPI().GetMaxControllers(); iCurrentSlot++)
    {
		Asura_PS3_USBPad* pxController = Asura_PS3_Input::GetAPI().GetController(iCurrentSlot);
		if ( (pxController != NULL) && pxController->IsConnectedAndSupported() )
		{
			pxController->SetMotorSpeeds(0, 0);
		}
	}
}


#endif // #if (defined ASURA_SUPPORT_CONTROLLER_RUMBLE) && (ASURA_SUPPORT_CONTROLLER_RUMBLE != 0) 
