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

   PROGRAM: audioenv.cpp

   DESCRIPTION: audio object class code

****************************************************************************/
#include "audioenv.h"

// EAX-test
// load up eax for Windows and MacOS, and add initguid.h for Windows for good measure...
#define OPENAL
#ifndef LINUX
#ifdef WINDOWS
#include <initguid.h>
#else
#define INITGUID
#endif
#include "eax.h"
#endif

// constructor
AudioEnv::AudioEnv ()
{
	nextBuffer = 0;
	nextSource = 0;
}

// destructor
AudioEnv::~AudioEnv ()
{
	alutExit();
}

// init
void AudioEnv::Init ()
{
   alutInit (NULL, 0); // init OpenAL

#ifndef LINUX
   // EAX test -- set EAX environment if EAX is available
	EAXSet pfPropSet;
	EAXGet pfPropGet;
	unsigned long ulEAXVal;
	long lGlobalReverb;
	if (alIsExtensionPresent((ALubyte *)"EAX") == AL_TRUE)
	{
		pfPropSet = (EAXSet) alGetProcAddress((ALubyte *)"EAXSet");
		if (pfPropSet != NULL)
		{
		    lGlobalReverb = 0;
			pfPropSet(&DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ROOM, 0, &lGlobalReverb, sizeof(unsigned long));
			ulEAXVal = EAX_ENVIRONMENT_GENERIC;
			pfPropSet(&DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, 0, &ulEAXVal, sizeof(unsigned long));
		}
	}
#endif
}

// init
void AudioEnv::ListenerPosition (ALfloat* position, ALfloat* angle)
{
	alListenerfv(AL_POSITION, position);
	alListenerfv(AL_ORIENTATION, angle);
}

int AudioEnv::LoadFile (char *filename, bool loop)
{
   // create buffer
   alGetError(); /* clear */
   alGenBuffers(1, &buffer[nextBuffer]);
   if(alGetError() != AL_NO_ERROR) {
	   return 0;
   }

   // create source
   alGetError(); /* clear */
   alGenSources(1, &source[nextSource]);
   if(alGetError() != AL_NO_ERROR) {
	   return 0;
   }

   // load data into buffer
#ifdef WINDOWS
   ALsizei size, freq;
   ALenum format;
   ALvoid *data;
   ALboolean looping;
   
   alutLoadWAVFile(filename, &format, &data, &size, &freq, &looping);
   alBufferData (buffer[nextBuffer], format, data, size, freq);
#endif
#ifdef MACOS
   ALsizei size, freq;
   ALenum format;
   ALvoid *data;
   
   alutLoadWAVFile(filename, &format, &data, &size, &freq);
   alBufferData (buffer[nextBuffer], format, data, size, freq);
#endif
#ifdef LINUX
   ALsizei size, freq, bits;
   ALenum format;
   ALvoid *data;
   ALboolean err;
   
   err = alutLoadWAV(filename, &data, &format, &size, &bits, &freq);
   if(err == AL_FALSE) {
	   fprintf(stderr, "Could not load %s\n", filename);
	   return 0;
   }

   alBufferData (buffer[nextBuffer], format, data, size, freq);
#endif   

   // setup source
   alSourcei(source[nextSource], AL_BUFFER, buffer[nextBuffer]);
   alSourcei(source[nextSource], AL_LOOPING, 1);

   nextBuffer++;
   nextSource++;
   return nextBuffer;
}

// Playfile
int AudioEnv::PlayFile (char *filename, bool loop)
{
	int loadhandle;

	loadhandle = LoadFile(filename, loop);

	if (loadhandle != 0) { 
		Play(loadhandle); 
	} else
	{
		return 0;
	}

	return loadhandle;
}

//SetSourcePosition
void AudioEnv::SetSourcePosition (int handle, float *position)
{
	alSourcefv(source[handle-1], AL_POSITION, position);
}

// Play

void AudioEnv::Play(int handle)
{
	alSourcePlay(source[handle-1]); 
}

// Stop
void AudioEnv::Stop(int handle)
{
	alSourceStop(source[handle-1]);
}

// IncrementEnv
int AudioEnv::IncrementEnv()
{
#ifndef LINUX
        // increment EAX environment if EAX is available
	EAXSet pfPropSet;
	EAXGet pfPropGet;
	unsigned long ulEAXVal;
	static unsigned long ulEAXEnv = 0;
	if (alIsExtensionPresent((ALubyte *)"EAX") == AL_TRUE)
	{
		pfPropSet = (EAXSet) alGetProcAddress((ALubyte *)"EAXSet");
		if (pfPropSet != NULL)
		{
		    ulEAXVal = 65535;
			pfPropSet(&DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ROOM, 0, &ulEAXVal, sizeof(unsigned long));
			ulEAXEnv += 1;
			if (ulEAXEnv >= EAX_ENVIRONMENT_COUNT) { ulEAXEnv = EAX_ENVIRONMENT_GENERIC; }
			pfPropSet(&DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, 0, &ulEAXEnv, sizeof(unsigned long));
		}
	}
	return (int) ulEAXEnv;
#else
   return 0;
#endif
}



