/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "binding_helpers.h"
		#include "core/sound.h"
		#include "core/mixer.h"

		using namespace GS::Audio;
		using namespace GS::Script;


//------------------------------------------------------------------------------
SQInteger			MixerSetGain(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETFLOAT(gain)
	__SQ_GETEND
	mixer->SetMasterVolume(gain);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			MixerMute(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(mixer, IMixer, typetag_Mixer)
	mixer->SetMasterVolume(0);
	__SQ_RETURN
}
SQInteger			MixerUnmute(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(mixer, IMixer, typetag_Mixer)
	mixer->SetMasterVolume(1);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			MixerChannelLock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_RETURNINT(mixer->LockChannel())
}
SQInteger			MixerChannelUnlock(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETEND
	mixer->UnlockChannel(channel);
	__SQ_RETURN
}
SQInteger			MixerChannelUnlockAll(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(mixer, IMixer, typetag_Mixer)
	mixer->UnlockAllChannels();
	__SQ_RETURN
}
SQInteger			MixerChannelStart(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETSAFEPTR(sound, Sound, typetag_Sound)
	__SQ_GETEND
	__SQ_RETURNBOOL(mixer->Start(channel, sound->mixer_data))
}
SQInteger			MixerChannelStartStream(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETSTRING(uri)
	int r = mixer->Stream(channel, uri);
	__SQ_GETEND
	__SQ_RETURNBOOL(r != -1)
}
SQInteger			MixerSoundStartFast(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETSAFEPTR(sound, Sound, typetag_Sound)
	bool r = mixer->StartFast(-1, sound->mixer_data);
	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}
SQInteger			MixerSoundStart(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETSAFEPTR(sound, Sound, typetag_Sound)
	int channel = mixer->Start(-1, sound->mixer_data);
	__SQ_GETEND
	__SQ_RETURNINT(channel)
}
SQInteger			MixerStreamStartFast(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETSTRING(uri)
	bool r = mixer->StreamFast(-1, uri);
	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}
SQInteger			MixerStreamStart(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETSTRING(uri)
	int channel = mixer->Stream(-1, uri);
	__SQ_GETEND
	__SQ_RETURNINT(channel)
}
SQInteger			MixerChannelPause(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETEND
	mixer->Pause(channel);
	__SQ_RETURN
}
SQInteger			MixerChannelResume(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETEND
	mixer->Resume(channel);
	__SQ_RETURN
}
SQInteger			MixerChannelGetState(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETEND
	__SQ_RETURNINT(0)
}
SQInteger			MixerChannelStop(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETEND
	mixer->Stop(channel);
	__SQ_RETURN
}
SQInteger			MixerChannelStopAll(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(mixer, IMixer, typetag_Mixer)
//	mixer->StopAllChannels();
	__SQ_RETURN
}
SQInteger			MixerChannelSetGain(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETFLOAT(gain)
	__SQ_GETEND
	mixer->SetChannelVolume(channel, gain);
	__SQ_RETURN
}
SQInteger			MixerChannelSetPitch(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETFLOAT(pitch)
	__SQ_GETEND
	mixer->SetChannelPitch(channel, pitch);
	__SQ_RETURN
}
SQInteger			MixerChannelSetPanning(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETFLOAT(panning)
	__SQ_GETEND
	mixer->SetChannelPanning(channel, panning);
	__SQ_RETURN
}
SQInteger			MixerChannelSetLoopMode(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETINT(loop)
	__SQ_GETEND
	mixer->SetChannelLoopMode(channel, (IMixer::Loop)loop);
	__SQ_RETURN
}
SQInteger			MixerChannelSetLoopPosition(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(mixer, IMixer, typetag_Mixer)
	__SQ_GETINT(channel)
	__SQ_GETINT(position)
	__SQ_GETEND
	mixer->SetChannelLoopPosition(channel, position);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void				RegisterMixerBinding(HSQUIRRELVM vm)
{
/*#
	Topic: Mixer
	Type: Mixer
	Type: Channel
	Related: Sound,ResourceFactory
#*/

/*#
	Section: ChannelManagement
	Desc: Channel management functions
#*/
	/*#
		Func: MixerChannelGetState
		Proto: ChannelState:Mixer,int channel
		Desc: Return the channel state.
	#*/
	sq_register(vm, MixerChannelGetState, "MixerChannelGetState", _SC(".xi"));
	/*#
		Func: MixerChannelStop
		Proto: void:Mixer,int channel
		Desc: Stop playback on a given channel.
	#*/
	sq_register(vm, MixerChannelStop, "MixerChannelStop", _SC(".xi"));
	/*#
		Func: MixerChannelPause
		Proto: void:Mixer,int channel
		Desc: Pause playback on a given channel.
	#*/
	sq_register(vm, MixerChannelPause, "MixerChannelPause", _SC(".xi"));
	/*#
		Func: MixerChannelResume
		Proto: void:Mixer,int channel
		Desc: Resume playback on a given channel.
	#*/
	sq_register(vm, MixerChannelResume, "MixerChannelResume", _SC(".xi"));
	/*#
		Func: MixerChannelStopAll
		Proto: void:Mixer
		Desc: Stop replay on all mixer channels.
	#*/
	sq_register(vm, MixerChannelStopAll, "MixerChannelStopAll", _SC(".x"));

/*#
	Section: MixerControl
	Desc: Mixer control functions
#*/
	/*#
		Func: MixerSetGain
		Proto: void:Mixer mixer,float gain
		Desc: Set the global mixer gain.
	#*/
	sq_register(vm, MixerSetGain, "MixerSetGain", _SC(".xn"));
	/*#
		Func: MixerPlaySoundFast
		Proto: bool:Mixer mixer,Sound sound
		Desc: Play a sound on the first channel available, this function returns immediately and the channel used for replay is not returned.
		See: ResourceFactoryLoadSound
	#*/
	sq_register(vm, MixerSoundStartFast, "MixerSoundStartFast", _SC(".xx"));
	sq_register(vm, MixerSoundStartFast, "MixerPlaySoundFast", _SC(".xx"));
	/*#
		Func: MixerPlaySound
		Proto: Channel:Mixer mixer,Sound sound
		Desc: Play a sound on the first channel available, the channel used for replay is returned. If no free channel was found -1 is returned.
		Note: Use MixerPlaySoundFast to prevent waiting for the mixer thread to return the channel used for playback if you do not need this information.
		See: MixerPlaySoundFast,ResourceFactoryLoadSound,MixerChannelPlaySound
	#*/
	sq_register(vm, MixerSoundStart, "MixerSoundStart", _SC(".xx"));
	sq_register(vm, MixerSoundStart, "MixerPlaySound", _SC(".xx"));
	/*#
		Func: MixerStartStreamFast
		Proto: bool:Mixer,uri
		Desc: Play a stream on the first channel available, this function returns immediately and the channel used for replay is not returned.
	#*/
	sq_register(vm, MixerStreamStartFast, "MixerStreamStartFast", _SC(".xs"));
	sq_register(vm, MixerStreamStartFast, "MixerStartStreamFast", _SC(".xs"));
	/*#
		Func: MixerStartStream
		Proto: Channel:Mixer,uri
		Desc: Play a stream on the first channel available, the channel used for replay is returned. If no free channel was found -1 is returned.
		Note: Use MixerStartStreamFast to prevent waiting for the mixer thread to return the channel used for playback if you do not need this information.
		See: MixerStartStreamFast,MixerChannelStartStream
	#*/
	sq_register(vm, MixerStreamStart, "MixerStreamStart", _SC(".xs"));
	sq_register(vm, MixerStreamStart, "MixerStartStream", _SC(".xs"));
	/*#
		Func: MixerMute
		Proto: void:Mixer
		Desc: Mute all sound output.
	#*/
	sq_register(vm, MixerMute, "MixerMute", _SC(".x"));
	/*#
		Func: MixerUnmute
		Proto: void:Mixer
		Desc: Unmute all sound output.
	#*/
	sq_register(vm, MixerUnmute, "MixerUnmute", _SC(".x"));

/*#
	Section: ChannelControl
	Desc: Channel control functions
#*/
	/*#
		Func: MixerChannelLock
		Proto: Channel:Mixer
		Desc: Lock a new mixer channel.
	#*/
	sq_register(vm, MixerChannelLock, "MixerChannelLock", _SC(".x"));
	/*#
		Func: MixerChannelUnlock
		Proto: void:Mixer,Channel
		Desc: Unlock channel.
	#*/
	sq_register(vm, MixerChannelUnlock, "MixerChannelUnlock", _SC(".xi"));
	/*#
		Func: MixerChannelUnlockAll
		Proto: void:Mixer
		Desc: Unlock all channels.
	#*/
	sq_register(vm, MixerChannelUnlockAll, "MixerChannelUnlockAll", _SC(".x"));
	/*#
		Func: MixerChannelPlaySound
		Proto: bool:Mixer,Channel,Sound
		Desc: Play a sound on a specific channel. Returns true on success, false otherwise.
	#*/
	sq_register(vm, MixerChannelStart, "MixerChannelStart", _SC(".xix"));
	sq_register(vm, MixerChannelStart, "MixerChannelPlaySound", _SC(".xix"));
	/*#
		Func: MixerChannelStartStream
		Proto: bool:Mixer,Channel,string uri
		Desc: Play a stream on a specific channel. Returns true on success, false otherwise.
	#*/
	sq_register(vm, MixerChannelStartStream, "MixerChannelStartStream", _SC(".xis"));

	/*#
		Func: MixerChannelSetGain
		Proto: void:Mixer,Channel,float gain
		Desc: Set channel gain. Note: The channel gain is not reset by starting new sounds.
	#*/
	sq_register(vm, MixerChannelSetGain, "MixerChannelSetGain", _SC(".xin"));
	/*#
		Func: MixerChannelSetPitch
		Proto: void:Mixer,Channel,float pitch
		Desc: Set channel pitch (Default: 1.0). Note: The channel pitch is not reset by starting new sounds.
	#*/
	sq_register(vm, MixerChannelSetPitch, "MixerChannelSetPitch", _SC(".xin"));
	/*#
		Func: MixerChannelSetPanning
		Proto: void:Mixer,Channel,float panning
		Desc: Set channel panning (Default: 0.5). Note: The channel panning is not reset by starting new sounds.
	#*/
	sq_register(vm, MixerChannelSetPanning, "MixerChannelSetPanning", _SC(".xin"));
	/*#
		Func: MixerChannelSetLoopMode
		Proto: void:Mixer,Channel,ChannelLoop loop
		Desc: Set channel loop mode.
	#*/
	sq_register(vm, MixerChannelSetLoopMode, "MixerChannelSetLoopMode", _SC(".xii"));
	/*#
		Func: MixerChannelSetLoopPosition
		Proto: void:Mixer,Channel,int ms
		Desc: Set channel loop position in millisecond, the loop mode must be set to LoopRepeat for this setting to have any effect.
	#*/
	sq_register(vm, MixerChannelSetLoopPosition, "MixerChannelSetLoopPosition", _SC(".xii"));

	// Push defines.
	sq_pushroottable(vm);

	/*#
		Enum: ChannelLoop
		Values: LoopNone,LoopRepeat
	#*/
	sq_pushstring(vm, "LoopNone", -1); sq_pushinteger(vm, IMixer::None); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "LoopRepeat", -1); sq_pushinteger(vm, IMixer::Repeat); sq_newslot(vm, -3, true);

	/*#
		Enum: ChannelState
		Values: ChannelStateInvalid,ChannelStateStopped,ChannelStatePlaying,ChannelStatePaused
	#*/
	sq_pushstring(vm, "ChannelStateInvalid", -1); sq_pushinteger(vm, IMixer::Invalid); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelStateStopped", -1); sq_pushinteger(vm, IMixer::Stopped); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelStatePlaying", -1); sq_pushinteger(vm, IMixer::Playing); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelStatePaused", -1); sq_pushinteger(vm, IMixer::Paused); sq_newslot(vm, -3, true);
	sq_pop(vm, 1);
}
//------------------------------------------------------------------------------
