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


		#include "binding_helpers.h"
		#include "motion/motion.h"

		using namespace GS;
		using namespace GS::Core;
		using namespace GS::Script;

/*
#include "micropather.h"
using namespace micropather;

#include "pathfinding.h"

MicroPather *pather;
MapPathFinder* pathfinding_map;

//------------------------------------------------------------------------------
SQInteger	NodePathFinder_CreateNode(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
		__SQ_GETINT(id)
		__SQ_GETINT(id_child)
		__SQ_GETEND

		pathfinding_map->AddChildToNode(id, id_child);
		__SQ_RETURN
}

//------------------------------------------------------------------------------
SQInteger	NodePathFinder_AddChild(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
		__SQ_GETINT(id)
		__SQ_GETFLOAT(weight)
		__SQ_GETEND

		pathfinding_map->CreateNode(weight, id);
	__SQ_RETURN
}

//------------------------------------------------------------------------------
SQInteger	CreateMicroPather(HSQUIRRELVM vm)
{
	pathfinding_map = new MapPathFinder();
	pather = new MicroPather(pathfinding_map, 20);
	__SQ_RETURN
}
*/
//------------------------------------------------------------------------------
SQInteger	MotionGetClosestPoint(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETVECTOR(p)
	__SQ_GETEND

	Vector4 closest;
	if	(motion)
		motion->GetClosestPoint(p, closest);
	__SQ_RETURNVECTOR(closest)
}
SQInteger	MotionGetClosestTime(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETVECTOR(p)
	__SQ_GETEND

	Vector4 closest;
	float closest_t = 0.f;
	if	(motion)
		motion->GetClosestPoint(p, closest, &closest_t);
	__SQ_RETURNFLOAT(closest_t);
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger	MotionEvaluateData(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETFLOAT(t)
	__SQ_GETEND
	GS::Variant sample;
	if	(motion)
		motion->EvaluateData(Time::fromSec(t), sample);
	__SQ_RETURNSTRING(sample.s_value)
}
SQInteger	MotionEvaluatePosition(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETFLOAT(t)
	__SQ_GETEND
	Vector4	sample(0, 0, 0);
	if	(motion)
		motion->EvaluatePosition(Time::fromSec(t), sample, Curve::Repeat);
	__SQ_RETURNVECTOR(sample)
}

SQInteger	MotionEvaluateDirection(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETFLOAT(t)
	__SQ_GETEND
	Vector4	sample(0, 0, 0);
	if	(motion)
		motion->EvaluateDirection(Time::fromSec(t), sample, Curve::Repeat);
	__SQ_RETURNVECTOR(sample)
}


SQInteger	MotionEvaluatePositionConstant(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(motion, Motion, typetag_Motion)
	__SQ_GETFLOAT(t)
	__SQ_GETEND
	Vector4	sample(0, 0, 0);
	if	(motion)
		motion->EvaluatePosition(Time::fromSec(t), sample, Curve::Constant);
	__SQ_RETURNVECTOR(sample)
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger	MotionGetName(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(m, Motion, typetag_Motion)
	__SQ_RETURNSTRING(m->name)
}
SQInteger	MotionGetLength(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(m, Motion, typetag_Motion)
	__SQ_RETURNFLOAT(m->GetDuration().toSec())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void		RegisterMotionBinding(HSQUIRRELVM vm)
{
/*#
	Topic: Motion
	Type: Motion
#*/

/*#
	Section: Motion
	Desc: Motion functions
#*/
	/*#
		Func: MotionGetClosestPoint
		Proto: float:Motion,Vector
		Desc: Return the nearest point on this motion for the position given
	#*/
	sq_register(vm, MotionGetClosestPoint, "MotionGetClosestPoint", _SC(".xx"));
	/*#
		Func: MotionGetClosestTime
		Proto: float:Motion,Vector
		Desc: Return the time for the nearest position.
	#*/
	sq_register(vm, MotionGetClosestTime, "MotionGetClosestTime", _SC(".xx"));
	/*#
		Func: MotionGetName
		Proto: String:Motion
		Desc: Return motion name.
	#*/
	sq_register(vm, MotionGetName, "MotionGetName", _SC(".x"));
	/*#
		Func: MotionEvaluateData
		Proto: String:Motion,float time
		Desc: Evaluate the data in motion at the specified time.
	#*/
	sq_register(vm, MotionEvaluateData, "MotionEvaluateData", _SC(".xn"));
	/*#
		Func: MotionEvaluatePosition
		Proto: Vector:Motion,float time
		Desc: Evaluate position triplet (x, y, z) in motion at the specified time. Note that a motion may not have all or any of the channels required for this evaluation.
	#*/
	sq_register(vm, MotionEvaluatePosition, "MotionEvaluatePosition", _SC(".xn"));
	sq_register(vm, MotionEvaluateDirection, "MotionEvaluateDirection", _SC(".xn"));
	/*#
		Func: MotionEvaluatePositionConstant
		Proto: Vector:Motion,float time
		Desc: IT'S CLAMPED TO THE BEGINING AND END. Evaluate position triplet (x, y, z) in motion at the specified time. Note that a motion may not have all or any of the channels required for this evaluation.
	#*/
	sq_register(vm, MotionEvaluatePositionConstant, "MotionEvaluatePositionConstant", _SC(".xn"));
	
	/*#
		Func: MotionGetLength
		Proto: float:Motion
		Desc: Return highest timecode in motion.
	#*/
	sq_register(vm, MotionGetLength, "MotionGetLength", _SC(".x"));

	// Push defines.
	sq_pushroottable(vm);

	sq_pushstring(vm, "ChannelNone", -1); sq_pushinteger(vm, MotionChannel::NoType); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelXPos", -1); sq_pushinteger(vm, MotionChannel::XPos); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelYPos", -1); sq_pushinteger(vm, MotionChannel::YPos); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelZPos", -1); sq_pushinteger(vm, MotionChannel::ZPos); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelXRot", -1); sq_pushinteger(vm, MotionChannel::XRot); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelYRot", -1); sq_pushinteger(vm, MotionChannel::YRot); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelZRot", -1); sq_pushinteger(vm, MotionChannel::ZRot); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelXScl", -1); sq_pushinteger(vm, MotionChannel::XScl); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelYScl", -1); sq_pushinteger(vm, MotionChannel::YScl); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelZScl", -1); sq_pushinteger(vm, MotionChannel::ZScl); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelXPiv", -1); sq_pushinteger(vm, MotionChannel::XPiv); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelYPiv", -1); sq_pushinteger(vm, MotionChannel::YPiv); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelZPiv", -1); sq_pushinteger(vm, MotionChannel::ZPiv); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelRDif", -1); sq_pushinteger(vm, MotionChannel::RDif); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelGDif", -1); sq_pushinteger(vm, MotionChannel::GDif); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelBDif", -1); sq_pushinteger(vm, MotionChannel::BDif); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelRSpc", -1); sq_pushinteger(vm, MotionChannel::RSpc); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelGSpc", -1); sq_pushinteger(vm, MotionChannel::GSpc); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelBSpc", -1); sq_pushinteger(vm, MotionChannel::BSpc); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelDiffuseIntensity", -1); sq_pushinteger(vm, MotionChannel::DiffuseIntensity); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelSpecularIntensity", -1); sq_pushinteger(vm, MotionChannel::SpecularIntensity); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelConeAngle", -1); sq_pushinteger(vm, MotionChannel::ConeAngle); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelEdgeAngle", -1); sq_pushinteger(vm, MotionChannel::EdgeAngle); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelAlpha", -1); sq_pushinteger(vm, MotionChannel::Alpha); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelZoomFactor", -1); sq_pushinteger(vm, MotionChannel::ZoomFactor); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelRange", -1); sq_pushinteger(vm, MotionChannel::Range); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "ChannelFogStart", -1); sq_pushinteger(vm, MotionChannel::FogStart); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelFogEnd", -1); sq_pushinteger(vm, MotionChannel::FogEnd); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelRFog", -1); sq_pushinteger(vm, MotionChannel::RFog); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelGFog", -1); sq_pushinteger(vm, MotionChannel::GFog); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ChannelBFog", -1); sq_pushinteger(vm, MotionChannel::BFog); sq_newslot(vm, -3, true);

	sq_pop(vm, 1);
}
//------------------------------------------------------------------------------
