//
// Asura_PSP_SAS.h
//
// Created by Kim Randell - 23/09/2004
// 
// Copyright (C) 2004 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_PSP_SAS_H__
#define __ASURA_PSP_SAS_H__

// Asura headers
#include "Core/Asura_Handle.h"
#include "Core/Asura_Multithread.h"
#include "Sound/Asura_ProjectSoundIDs.h"
#include "Sound/Asura_PSP_SimpleAudio.h"
#include "Sound/Asura_PSP_Sound.h"

// PSP headers
#include <kerneltypes.h>
#include <psptypes.h>

struct Asura_PSP_SAS_ActiveSound
{
	int				m_iLoadedSoundIndex;
	int				m_iPitch;
	int				m_iVolumeL;
	int				m_iVolumeR;
	union
	{
		struct
		{
			u_int	m_bSetVoice			: 1,
					m_bKeyOn			: 1,
					m_bKeyOff			: 1,
					m_bLooping			: 1,
					m_bPlaying			: 1,
					m_bPauseOn			: 1,
					m_bPauseOff			: 1,
					m_bStopping			: 1,

					m_bPausedByRequest	: 1,
					m_bPausedByPitch	: 1,
										: 0;
		};
		u_int		m_uFlags;
	};
};

class Asura_PSP_SAS
{
public:
	static void Initialise();
	static void Shutdown();
	static void Reset();
	static bool Decode(void);

	// Functions to lock SAS usage whilst in operation...
	static void BeginUsage(void)	{ s_xMutex.Lock(); }
	static void EndUsage(void)		{ s_xMutex.Unlock(); }

	// Load/unload
	static bool LoadSoundFromResource(Asura_Handle iFileHandle, int iFileSize, int iLoadedSoundID);
	static bool UnloadSound(int iLoadedSoundID);
	static bool LoadSoundBlock(Asura_Handle iFileHandle, u_int uSoundDataSize, u_int uNumEntries);
	// Standard playing methods
	static bool CreateSound(int iLoadedSoundID, Asura_Handle iSoundHandle);
	static bool PlaySound(Asura_Handle iSoundHandle, bool bLooping);
	static bool IsSoundPlaying(Asura_Handle iSoundHandle);
	static bool IsSoundPaused(Asura_Handle iSoundHandle);
	static bool StopSound(Asura_Handle iSoundHandle);
	static bool DestroySound(Asura_Handle iSoundHandle);
	static bool PauseSound(Asura_Handle iSoundHandle);
	static bool UnpauseSound(Asura_Handle iSoundHandle);
	// Property setting
	static bool SetSoundVolumePanAndFade(Asura_Handle iSoundHandle, float fVolume, float fPan, float fFade);
	static bool SetSoundPitch(Asura_Handle iSoundHandle, float fPitch);
	// interface for borrowing sound memory (for FMV playback)
	static u_int GetPermanentSoundsSize() { return s_uPermanentSoundsSize; }
	static void GetMemoryFromPermanentSounds(char** ppcMemoryBlock);
	static void RestorePermanentSounds();

private:
	// Function to ensure that a particular loaded sound is no longer played...
	static u_int StopLoadedSound(const int iLoadedSoundID);

	// Pause related helper functions
	static void PauseIfNecessary(Asura_Handle iSoundHandle);
	static void UnpauseIfNecessary(Asura_Handle iSoundHandle);

	// Voice alteration functions...
	static bool UpdatePitch(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);

	static bool	SetVoice(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);

	static bool KeyOn(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);
	static bool KeyOff(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);
	static bool PauseOn(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);
	static bool PauseOff(const u_int uVoice, Asura_PSP_SAS_ActiveSound& xActiveSound);

	// Members
	static Asura_PSP_SAS_ActiveSound	s_axActiveSounds[uASURA_PSP_MAX_VOICES];
	static Asura_Mutex					s_xMutex;
	static u_char*						s_pucPermanentSounds;
	static u_int						s_uPermanentSoundsSize;
};

#endif//__ASURA_PSP_SAS_H__
