#pragma once

#include "..\munga\audlvl.h"
#include "l4audhdw.h"
#include "openal/al.h"

enum SampleChannel
{
	CHANNEL_LEFT,
	CHANNEL_RIGHT,
	CHANNEL_CENTER
};

enum SampleLoop
{
	LoopAtWill,		//Will play once or loop as desired
	ForceStatic,	//Plays only once even if looped
	LoopAlways,		//Ramp up and then down
	SampleLoopMax
};

struct SAMPLEINFO
{
	int bufferIndex;
	bool implemented;
	const char *file;
	SampleChannel chan;
	SampleLoop loop;
};

struct PRESETINFO
{
	int sampleNum;
	SAMPLEINFO samples[5];
	bool is3d;
};

extern PRESETINFO allPresets[2][100];

bool PRESET_isImplemented(int bank, int preset);
int PRESET_getNumSamples(int bank, int preset);
SAMPLEINFO PRESET_getSampleInfo(int bank, int preset, int sampleInd);
void PRESET_setBufferIndex(int bank, int preset, int sampleInd, int index);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PatchLevelOfDetail ~~~~~~~~~~~~~~~~~~~~~~~~~~

typedef MIDIValue	SBKPatchID;
typedef MIDIValue SBKBankID;

class PatchLevelOfDetail:
	public AudioLevelOfDetail
{
public:
	//
	//-----------------------------------------------------------------------
	// Construction, Destruction, Testing
	//-----------------------------------------------------------------------
	//
	PatchLevelOfDetail(PlugStream *stream);
	~PatchLevelOfDetail();

	void PlayNote(SourceSet sourceSet);
	void StopNote(SourceSet sourceSet);

	Logical
		TestInstance() const;

	virtual AudioVoiceCount
		GetVoiceCount()
			{return PRESET_getNumSamples(bankID,patchID);}

	//
	//-----------------------------------------------------------------------
	// BuildFromPage
	//-----------------------------------------------------------------------
	//
	static void
		BuildFromPage(
			PlugStream *stream,
			NameList *name_list,
			ClassID class_ID,
			ObjectID object_ID
		);

	//
	//-----------------------------------------------------------------------
	// Accessors
	//-----------------------------------------------------------------------
	//
	void
		SetupPatch(SourceSet sourceSet);

	MIDINRPNValue
		GetMaxMIDIFilterCutoff()
			{return maxMIDIFilterCutoff;}

private:
	//
	//-----------------------------------------------------------------------
	// Private data
	//-----------------------------------------------------------------------
	//
	SBKBankID
		bankID;
	SBKPatchID
		patchID;
	MIDINRPNValue
		maxMIDIFilterCutoff;

	#ifdef LAB_ONLY
		int 
			setupCount;
	#endif

	//
	// Keep table of created patchs to verify that duplicates
	// are not created
	//
	#if DEBUG_LEVEL>0
		static TableOf<PatchLevelOfDetail*, unsigned int>
			patchTableSocket;
	#endif
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PatchResource ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class PatchResource:
	public AudioResource
{
public:
	//
	//-----------------------------------------------------------------------
	// Construction, Destruction, Testing
	//-----------------------------------------------------------------------
	//
	PatchResource(PlugStream *stream);
	~PatchResource();

	void PlayNote(SourceSet sourceSet);
	void StopNote(SourceSet sourceSet);

	Logical
		TestInstance() const;

	//
	//-----------------------------------------------------------------------
	// BuildFromPage
	//-----------------------------------------------------------------------
	//
	static void
		BuildFromPage(
     	PlugStream *stream,
			NameList *name_list,
			ClassID class_ID,
			ObjectID object_ID
     );

	//
	//-----------------------------------------------------------------------
	// Accessors
	//-----------------------------------------------------------------------
	//
	void
		SetupPatch(SourceSet sourceSet);

	MIDINRPNValue
		GetMaxMIDIFilterCutoff();
};

