//////////////////////////////////////////////////////////////////////////////
//
// Asura_Sound_Event_Playback.h
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
// Description:
//
//     classes to handle the runtime playback of events
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_SOUND_EVENT_PLAYBACK_H___
#define ___ASURA_SOUND_EVENT_PLAYBACK_H___ 1

// I N C L U D E S ///////////////////////////////////////////////////////////
#include "Core/Asura_Maths.h"
#include "Sound/Asura_Sound_Event.h"

// F O R W A R D   D E C L A R A T I O N S ///////////////////////////////////
class Asura_Phonon;
class Asura_Sound_Event_Controller;

// Asura_Sound_Event_System::PlayEvent() can return a handle from a list of Asura_Sound_Event_Instance
class Asura_Sound_Event_Instance
{
public:

	Asura_Sound_Event_Instance();
	~Asura_Sound_Event_Instance();

	void Update(bool bMixerChanged);
	void Play(const Asura_Sound_Event* pxEvent, const Asura_Vector_3* pxPos, float fVolumeScale);
	void Play(const Asura_Phonon* pxPhonon);
	void Stop();
	void FadeOut( float fFadeTime );
	void SetPosition( const Asura_Vector_3& xPos );
	void SetVolumeScale( float fVolScale );
	void SetPitchScale( float fPitchScale );
	bool IsLooping() const;
	float GetInnerRadius() const;
	float GetOuterRadius() const;
	Asura_Hash_ID GetInstanceGroupID() const {return m_uInstanceGroupID;}
	
#if defined(ASURA_TOOLS) || defined(ASURA_USE_MULTIPLE_HANDLERS)
	void SoundEventDeleted(const Asura_Sound_Event* pxEventDeleted);
#endif	// defined(ASURA_TOOLS) || defined(ASURA_USE_MULTIPLE_HANDLERS)

	// accessors
	bool NoExternalHandle() const { return m_bNoExternalHandle; }
	void SetHasExternalHandle(bool bHasExternalHandle) { m_bNoExternalHandle = !bHasExternalHandle; }
	bool IsPlaying() const { return m_bPlaying; }
	float GetVolumeScale() const { return m_fVolumeScale; }
	float GetPitchScale() const { return m_fPitchScale; }
	bool GetUsePosition() const { return m_bUsePosition; }
	const Asura_Vector_3& GetPosition() const { return m_xPosition; }
	const Asura_Phonon* GetPhonon() const { return m_pxPhonon; }

	void AddPlayController(Asura_Sound_Event_Controller* pxController); 
	void RemovePlayController(Asura_Sound_Event_Controller* pxController); 

	const Asura_Sound_Event* GetEvent() const {return m_pxEvent;}
	u_int GetNumControllers() const;	// returns number of events that are controlled by this. 
	u_int GetNumVoices() const; // returns number of voices used by this instance.

private:

	void Reset();

	bool						m_bNoExternalHandle;	// managed by Asura_Sound_Event_System
	bool						m_bPlaying;				// set during Update() based on sound status, play mode etc.
	bool						m_bUsePosition;			// if set, play as 3d using m_xPosition
	bool						m_bFadingOut;			// volume is reduced by m_fVolumeFadeoutRate until zero.
	Asura_Vector_3				m_xPosition;
	float						m_fVolumeScale;			// scale of the starting volume
	float						m_fPitchScale;
	float						m_fVolumeFadeoutRate;

	Asura_Hash_ID				m_uInstanceGroupID;

	const Asura_Sound_Event*   		m_pxEvent;
	const Asura_Phonon*				m_pxPhonon;
	Asura_Sound_Event_Controller*	m_apxFirstController[uASURA_SOUND_EVENT_MAX_FOR_SIMULTANEOUS_PLAY];
	Asura_Sound_Event_Controller*	m_apxPlayController[uASURA_SOUND_EVENT_MAX_FOR_SIMULTANEOUS_PLAY];
	u_int							m_uNumPlayControllers;

	// non-copyable
	Asura_Sound_Event_Instance(const Asura_Sound_Event_Instance&);
	Asura_Sound_Event_Instance* operator= (const Asura_Sound_Event_Instance&);
};

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_SOUND_EVENT_PLAYBACK_H___
