#ifndef _RUSYMPHONY_BASE_H_
#define _RUSYMPHONY_BASE_H_

// Base types
#include "../Core/Type/RuType_Object.h"

// Miles Sound System
#include "../../Tools/MilesWin/include/mss.h"

// Import Miles Sound System library
#pragma comment(lib, "mss32.lib")

#pragma unmanaged

// ************************************************************************************************************************************************************

class CRuSymphony : public IRuObject
{
	ruRTTI_DECLARE
	ruHEAP_DECLARE
	ruCLASSGUID_DECLARE

protected:
	struct SampleDescriptor
	{
		HSAMPLE									m_sampleHandle;						//!< Handle to the sample
		BYTE*									m_sampleData;						//!< Pointer to the sample data
		INT32									m_sampleDataSize;					//!< Sample data size
	};

	struct SoundDescriptor
	{
		char*									m_resourceName;						//!< Resource name for the sound
		INT32									m_soundDataSize;					//!< Size of the sound data
		BYTE*									m_soundData;						//!< Raw sound data

												SoundDescriptor();
												~SoundDescriptor();
	};

	// MSS
	HDIGDRIVER									m_digDriver;						//!< Digital driver handle

	INT32										m_numSampleHandles;					//!< Total number of sample handles
	SampleDescriptor*							m_sampleDescriptors;				//!< Sample descriptors

	// Settings
	INT32										m_soundDescriptorCacheSize;			//!< Maximum cache size allowed for the sound descriptor cache
	char*										m_resourcePath;						//!< Root path for all sound resources

	REAL										m_defaults_3D_MinDist;
	REAL										m_defaults_3D_MaxDist;

	// Sound dictionary
	CRuStringHash<SoundDescriptor *>*			m_soundDescriptorHash;
	CRuLRUQueue<PTRVALUE, SoundDescriptor *>*	m_soundDescriptorQueue;

public:
												CRuSymphony();
	virtual										~CRuSymphony();

	// Startup & Shutdown
	BOOL										Startup();
	BOOL										Shutdown();

	// Settings
	const char*									GetResourcePath();
	void										SetResourcePath(const char *resourcePath);

	// Listener positioning and falloff
	BOOL										SetListenerPosition(REAL x, REAL y, REAL z);
	BOOL										SetListenerOrientation(REAL xAt, REAL yAt, REAL zAt, REAL xUp, REAL yUp, REAL zUp);
	BOOL										SetDefault3DSoundDistances(REAL minDist, REAL maxDist);

	// Playback
	BOOL										PlaySoundByPath(const char *soundPath);
	BOOL										Play3DSoundByPath(const char *soundPath, REAL x, REAL y, REAL z);
	BOOL										PlaySoundByTag(const char *soundTag);

	// Resource retrieval
	SampleDescriptor*							GetAvailableSampleDescriptor();
	SoundDescriptor*							GetSoundDescriptor(const char *soundPath);

	BOOL										IsSoundDescriptorInUse(SoundDescriptor *soundDesc);

protected:
	BOOL										ClearSoundDescriptorHash();
	BOOL										ClearSoundDescriptorHashCallback(const void *key, void *data);

	BOOL										ClearSoundDescriptorQueue();
	BOOL										ClearSoundDescriptorQueueCallback(const void *key, void *data);
};

// ************************************************************************************************************************************************************

extern CRuSymphony*								g_ruSymphony;

// ************************************************************************************************************************************************************

#pragma managed

#endif
