#ifndef _ALC_H_
#define _ALC_H_

#include "altypes.h"
#include "alctypes.h"

#include "..\OpenAL32\include\alListener.h"
#include "..\OpenAL32\include\alSource.h"

#ifdef _WIN32
 #ifdef _LIB
  #define ALCAPI
 #else
  #define ALCAPI
 #endif
 #define ALCAPIENTRY __cdecl
 #pragma comment(lib, "winmm.lib")
 #include <windows.h>
#else
 #define ALCAPI
 #define ALCAPIENTRY __cdecl
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct ALCdevice_struct 
{
	ALenum		LastError;
	ALboolean	InUse;
	ALboolean	Valid;

	ALuint		Frequency;
	ALuint		Channels;
	ALenum		Format;

	ALint		MajorVersion;
	ALint		MinorVersion;

	//Platform specific variables
	CRITICAL_SECTION mutex;
	HWAVEOUT	handle;
	WAVEHDR		buffer[3];
} ALCdevice;

typedef struct ALCcontext_struct 
{
	ALlistener	Listener;
	
	ALsource *	Source;
	ALuint		SourceCount;

	ALenum		LastError;
	ALboolean	InUse;
	ALboolean	Valid;

	ALuint		Frequency;
	ALuint		Channels;
	ALenum		Format;

	ALfloat		DopplerScale;
	ALfloat		DistanceScale;

	ALboolean	Doppler;
	ALboolean	Distance;

	ALCdevice * Device;
	ALvoid *	reverb;

	struct ALCcontext_struct *previous;
	struct ALCcontext_struct *next;
} ALCcontext;

#ifndef AL_NO_PROTOTYPES

ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(ALCubyte *deviceName,ALCint *attrList);
ALCAPI ALCvoid    ALCAPIENTRY alcCloseDevice(ALCdevice *device);
ALCAPI ALCboolean ALCAPIENTRY alcQueryVersion(ALCdevice *device,ALCuint *majorVersion,ALCuint *minorVersion);

ALCAPI ALCcontext*ALCAPIENTRY alcCreateContext(ALCdevice *device,ALCint *attrList);
ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context);
ALCAPI ALCcontext*ALCAPIENTRY alcGetCurrentContext(ALCvoid);
ALCAPI ALCvoid    ALCAPIENTRY alcUpdateContext(ALCcontext *context);
ALCAPI ALCvoid    ALCAPIENTRY alcDestroyContext(ALCcontext *context);

ALCAPI ALCenum	  ALCAPIENTRY alcGetError(ALCvoid);
ALCAPI ALCubyte	  ALCAPIENTRY alcGetErrorString(ALCenum errorCode);

ALCAPI ALvoid	  ALCAPIENTRY alcLockContext(ALCcontext *context);
ALCAPI ALvoid	  ALCAPIENTRY alcUnlockContext(ALCcontext *context);
				
#else /* AL_NO_PROTOTYPES */

ALCAPI ALCdevice* ALCAPIENTRY (*alcOpenDevice)(ALubyte *deviceName,ALCint *attrList);
ALCAPI ALCvoid    ALCAPIENTRY (*alcCloseDevice)(ALCdevice *device);
ALCAPI ALCboolean ALCAPIENTRY (*alcQueryVersion)(ALCdevice *device,ALCuint *majorVersion,ALCuint *minorVersion);

ALCAPI ALCcontext*ALCAPIENTRY (*alcCreateContext)(ALCdevice *device,ALCint *attrList);
ALCAPI ALCboolean ALCAPIENTRY (*alcMakeContextCurrent)(ALCcontext *context);
ALCAPI ALCcontext*ALCAPIENTRY (*alcGetCurrentContext)(ALCvoid);
ALCAPI ALCvoid    ALCAPIENTRY (*alcUpdateContext)(ALCcontext *context);
ALCAPI ALCvoid    ALCAPIENTRY (*alcDestroyContext)(ALCcontext *context);

ALCAPI ALCenum	  ALCAPIENTRY (*alcGetError)(ALCvoid);
ALCAPI ALCubyte	  ALCAPIENTRY (*alcGetErrorString)(ALCenum errorCode);

ALCAPI ALvoid	  ALCAPIENTRY (*alcLockContext)(ALCcontext *context);
ALCAPI ALvoid	  ALCAPIENTRY (*alcUnlockContext)(ALCcontext *context);

#endif /* AL_NO_PROTOTYPES */

#ifdef __cplusplus
};
#endif

#endif
