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


		#include "squirrel_binding.h"
		#include "binding_helpers.h"
		#include "motion/motion.h"
		#include "automation/automation_source_group.h"
		#include "automation/automation_player.h"

		using namespace GS;
		using namespace GS::Script;
		using namespace GS::Automation;


//------------------------------------------------------------------------------
SQInteger			AnimationSourceSetLoopMode(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETINT(loop_mode)
	__SQ_GETEND
	source->SetLoopMode((Curve::LoopMode)loop_mode);
	__SQ_RETURN
}
SQInteger			AnimationSourceSetLoop(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETFLOAT(loop_start)
	__SQ_GETFLOAT(loop_end)
	__SQ_GETEND
	source->SetLoop(Time::fromSec(loop_start), Time::fromSec(loop_end));
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGetClock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_RETURNFLOAT(source->time.toSec())
}
SQInteger			AnimationSourceSetClock(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETFLOAT(time)
	__SQ_GETEND
	source->time = Time::fromSec(time);
	__SQ_RETURN
}
SQInteger			AnimationSourceGetClockScale(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_RETURNFLOAT(source->time_scale)
}
SQInteger			AnimationSourceSetClockScale(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETFLOAT(scale)
	__SQ_GETEND
	source->time_scale = scale;
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceIsRelative(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_RETURNBOOL(source->relative);
}
SQInteger			AnimationSourceSetRelative(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETBOOL(relative)
	__SQ_GETEND
	source->relative = asbool(relative);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceSetWeight(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETFLOAT(weight)
	__SQ_GETFLOAT(blend)
	__SQ_GETEND
	source->SetWeight(weight, blend);
	__SQ_RETURN
}
SQInteger			AnimationSourceStop(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETFLOAT(blend)
	__SQ_GETEND
	source->Dispose(blend);
	__SQ_RETURN
}
SQInteger			AnimationSourceIsDone(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_RETURNBOOL(source->IsDone());
}
//------------------------------------------------------------------------------

// Group

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGroupGetSourceCount(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_RETURNINT(group->source_list.GetCount())
}
SQInteger			AnimationSourceGroupGetSource(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETINT(index)
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(group->source_list[index], typetag_AutomationSource)
}
SQInteger			AnimationSourceGroupAddSource(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETSAFEPTR(source, Source, typetag_AutomationSource)
	__SQ_GETEND
	group->source_list.Add(source);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGroupSetLoopMode(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETINT(loop_mode)
	__SQ_GETEND
	group->SetLoopMode((Curve::LoopMode)loop_mode);
	__SQ_RETURN
}
SQInteger			AnimationSourceGroupSetLoop(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETFLOAT(loop_start)
	__SQ_GETFLOAT(loop_end)
	__SQ_GETEND
	group->SetLoop(Time::fromSec(loop_start), Time::fromSec(loop_end));
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGroupGetClock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	if	(group->source_list.GetCount() == 0)
		return sq_throwerror(vm, "No animation source in group");
	__SQ_RETURNFLOAT(group->source_list[0]->time.toSec())
}
SQInteger			AnimationSourceGroupSetClock(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETFLOAT(time)
	__SQ_GETEND
	group->SetTime(Time::fromSec(time));
	__SQ_RETURN
}
SQInteger			AnimationSourceGroupGetClockScale(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	if	(group->source_list.GetCount() == 0)
		return sq_throwerror(vm, "No animation source in group");
	__SQ_RETURNFLOAT(group->source_list[0]->time_scale)
}
SQInteger			AnimationSourceGroupSetClockScale(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETFLOAT(scale)
	__SQ_GETEND
	group->SetTimeScale(scale);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGroupSetRelative(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETBOOL(relative)
	__SQ_GETEND
	group->SetRelative(asbool(relative));
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			AnimationSourceGroupSetWeight(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETFLOAT(weight)
	__SQ_GETFLOAT(blend)
	__SQ_GETEND
	group->SetWeight(weight, blend);
	__SQ_RETURN
}
SQInteger			AnimationSourceGroupStop(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_GETFLOAT(blend)
	__SQ_GETEND
	group->Dispose(blend);
	__SQ_RETURN
}
SQInteger			AnimationSourceGroupIsDone(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, SourceGroup, typetag_AutomationSourceGroup)
	__SQ_RETURNBOOL(group->IsDone());
}
//------------------------------------------------------------------------------

//--------------------------------------------------
void		RegisterAnimationBinding(HSQUIRRELVM vm)
//--------------------------------------------------
{
/*#
	Topic: Animation
	Type: AnimationSourceGroup
	Type: AnimationSource
#*/

/*#
	Section: Animation Source
	Desc: Provides control over an animation source.
#*/
	/*#
		Func: AnimationSourceSetLoopMode
		Proto: void:AnimationSource, AnimationLoopMode mode
		Desc: Set animation source loop mode.
	#*/
	sq_register(vm, AnimationSourceSetLoopMode, "AnimationSourceSetLoopMode", _SC(".xi"));
	/*#
		Func: AnimationSourceSetLoop
		Proto: void:AnimationSource, float loop_start, float loop_end
		Desc: Set animation source loop point.
	#*/
	sq_register(vm, AnimationSourceSetLoop, "AnimationSourceSetLoop", _SC(".xnn"));
	/*#
		Func: AnimationSourceGetClock
		Proto: float:AnimationSource
		Desc: Get animation source clock.
	#*/
	sq_register(vm, AnimationSourceGetClock, "AnimationSourceGetClock", _SC(".x"));
	/*#
		Func: AnimationSourceSetClock
		Proto: void:AnimationSource, float clock
		Desc: Set animation source clock.
	#*/
	sq_register(vm, AnimationSourceSetClock, "AnimationSourceSetClock", _SC(".xn"));
	/*#
		Func: AnimationSourceGetClockScale
		Proto: float:AnimationSource
		Desc: Get animation source clock scale.
	#*/
	sq_register(vm, AnimationSourceGetClockScale, "AnimationSourceGetClockScale", _SC(".x"));
	/*#
		Func: AnimationSourceSetClockScale
		Proto: void:AnimationSource, float clock_scale
		Desc: Set animation source clock scale.
	#*/
	sq_register(vm, AnimationSourceSetClockScale, "AnimationSourceSetClockScale", _SC(".xn"));
	/*#
		Func: AnimationSourceSetWeight
		Proto: void:AnimationSource, float weight, float blend
		Desc: Set animation source weight and weight blend duration.
	#*/
	sq_register(vm, AnimationSourceSetWeight, "AnimationSourceSetWeight", _SC(".xnn"));
	/*#
		Func: AnimationSourceIsRelative
		Proto: bool:AnimationSource
		Desc: Return the animation source evaluation mode..
	#*/
	sq_register(vm, AnimationSourceIsRelative, "AnimationSourceIsRelative", _SC(".x"));
	/*#
		Func: AnimationSourceSetRelative
		Proto: void:AnimationSource, bool relative
		Desc: Set animation source evaluation mode to relative instead of absolute.<br>Relative source offsets the value they modify instead of replacing it.
	#*/
	sq_register(vm, AnimationSourceSetRelative, "AnimationSourceSetRelative", _SC(".xb"));
	/*#
		Func: AnimationSourceStop
		Proto: void:AnimationSource, float blend
		Desc: Stop an animation source. The motion weight can be brought down to 0 over a given blend duration before the source is stopped.
	#*/
	sq_register(vm, AnimationSourceStop, "AnimationSourceStop", _SC(".xn"));
	/*#
		Func: AnimationSourceIsDone
		Proto: bool:AnimationSource
		Desc: Returns true if this animation source is done playing.
	#*/
	sq_register(vm, AnimationSourceIsDone, "AnimationSourceIsDone", _SC(".x"));

/*#
	Section: Animation Source Group
	Desc: Provides control over a group of animation sources.
#*/
	/*#
		Func: AnimationSourceGroupGetSourceCount
		Proto: int:AnimationSourceGroup
		Desc: Return the number of animation sources in this group.
	#*/
	sq_register(vm, AnimationSourceGroupGetSourceCount, "AnimationSourceGroupGetSourceCount", _SC(".x"));
	/*#
		Func: AnimationSourceGroupGetSource
		Proto: AnimationSource:AnimationSourceGroup, int index
		Desc: Return an animation source from the group.
	#*/
	sq_register(vm, AnimationSourceGroupGetSource, "AnimationSourceGroupGetSource", _SC(".xi"));
	/*#
		Func: AnimationSourceGroupAddSource
		Proto: void:AnimationSourceGroup, AnimationSource
		Desc: Add an animation source to the group.
	#*/
	sq_register(vm, AnimationSourceGroupAddSource, "AnimationSourceGroupAddSource", _SC(".xx"));
	/*#
		Func: AnimationSourceGroupSetLoopMode
		Proto: void:AnimationSourceGroup, AnimationLoopMode mode
		Desc: Set animation source group loop mode.
	#*/
	sq_register(vm, AnimationSourceGroupSetLoopMode, "AnimationSourceGroupSetLoopMode", _SC(".xi"));
	/*#
		Func: AnimationSourceGroupSetLoop
		Proto: void:AnimationSourceGroup, float loop_start, float loop_end
		Desc: Set animation source group loop point.
	#*/
	sq_register(vm, AnimationSourceGroupSetLoop, "AnimationSourceGroupSetLoop", _SC(".xnn"));

	/*#
		Func: AnimationSourceGroupGetClock
		Proto: float:AnimationSourceGroup
		Desc: Get animation source group clock.
	#*/
	sq_register(vm, AnimationSourceGroupGetClock, "AnimationSourceGroupGetClock", _SC(".x"));
	/*#
		Func: AnimationSourceGroupSetClock
		Proto: void:AnimationSourceGroup, float clock
		Desc: Set animation source group clock.
	#*/
	sq_register(vm, AnimationSourceGroupSetClock, "AnimationSourceGroupSetClock", _SC(".xn"));

	/*#
		Func: AnimationSourceGroupGetClockScale
		Proto: float:AnimationSourceGroup
		Desc: Get animation source group clock scale.
	#*/
	sq_register(vm, AnimationSourceGroupGetClockScale, "AnimationSourceGroupGetClockScale", _SC(".x"));
	/*#
		Func: AnimationSourceGroupSetClockScale
		Proto: void:AnimationSourceGroup, float clock_scale
		Desc: Set animation source group clock scale.
	#*/
	sq_register(vm, AnimationSourceGroupSetClockScale, "AnimationSourceGroupSetClockScale", _SC(".xn"));

	/*#
		Func: AnimationSourceGroupSetWeight
		Proto: void:AnimationSourceGroup, float weight, float blend
		Desc: Set animation source group weight and weight blend duration.
	#*/
	sq_register(vm, AnimationSourceGroupSetWeight, "AnimationSourceGroupSetWeight", _SC(".xnn"));
	/*#
		Func: AnimationSourceGroupSetRelative
		Proto: void:AnimationSourceGroup, bool relative
		Desc: Set animation source evaluation mode to relative instead of absolute.<br>Relative source offsets the value they modify instead of replacing it.
	#*/
	sq_register(vm, AnimationSourceGroupSetRelative, "AnimationSourceGroupSetRelative", _SC(".xb"));
	/*#
		Func: AnimationSourceGroupStop
		Proto: void:AnimationSourceGroup, float blend
		Desc: Stop an animation source group. The motion weight can be brought down to 0 over a given blend duration before the source group is stopped.
	#*/
	sq_register(vm, AnimationSourceGroupStop, "AnimationSourceGroupStop", _SC(".xn"));
	/*#
		Func: AnimationSourceGroupIsDone
		Proto: bool:AnimationSourceGroup
		Desc: Returns true if this animation source group is done playing.
	#*/
	sq_register(vm, AnimationSourceGroupIsDone, "AnimationSourceGroupIsDone", _SC(".x"));

	// Push defines.
	sq_pushroottable(vm);

	/*#
		Enum: AnimationLoopMode
		Values: AnimationConstant,AnimationRepeat,AnimationReset,AnimationOffsetRepeat,AnimationOscillate
	#*/
	sq_pushstring(vm, "AnimationConstant", -1); sq_pushinteger(vm, Curve::Constant); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "AnimationRepeat", -1); sq_pushinteger(vm, Curve::Repeat); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "AnimationReset", -1); sq_pushinteger(vm, Curve::Reset); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "AnimationOffsetRepeat", -1); sq_pushinteger(vm, Curve::OffsetAndRepeat); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "AnimationOscillate", -1); sq_pushinteger(vm, Curve::Oscillate); sq_newslot(vm, -3, true);

	sq_pop(vm, 1);
}
