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


		#include "binding_helpers.h"
		#include "script_squirrel/cobject/matrix_decl.h"
		#include "scene3d/group.h"
		#include "automation/automation_source_group.h"
		#include "math/matrix4.h"

		using namespace GS::S3D;
		using namespace GS::Script;


SQInteger			GroupSetInvisible(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETBOOL(value)
	__SQ_GETEND
	group->SetInvisible(value ? true : false);
	__SQ_RETURN
}

extern	SQInteger	GetMatrix4(HSQUIRRELVM vm, int idx, GS::Matrix4 &mtx);

SQInteger			GroupOffsetMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETMATRIX4(m)
	__SQ_GETEND
	group->Offset(m);
	__SQ_RETURN
}

SQInteger			GroupFindItem(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSTRING(item_id)
	__SQ_GETEND
	MItem *item = group->Item(item_id);
	__SQ_RETURNSAFEPTR(item, typetag_Item)
}

SQInteger			GroupSetRootItem(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSAFEPTR(root, MItem, typetag_Item)
	__SQ_GETEND
	group->SetRootItem(root);
	__SQ_RETURN
}

SQInteger			GroupGetRootItem(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	__SQ_RETURNSAFEPTR(group->GetRootItem(), typetag_Item)
}

SQInteger			GroupItemIsMember(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSAFEPTR(item, MItem, typetag_Item)
	__SQ_GETEND
	__SQ_RETURNBOOL(group->IsMember(item))
}
SQInteger			GroupAddItem(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSAFEPTR(item, MItem, typetag_Item)
	__SQ_GETEND
	group->Add(item);
	__SQ_RETURN
}
SQInteger			GroupRemoveItem(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSAFEPTR(item, MItem, typetag_Item)
	__SQ_GETEND
	group->Remove(item);
	__SQ_RETURN
}
SQInteger			GroupSetName(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSTRING(_name)
	group->name = _name;
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			GroupGetName(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	__SQ_RETURNSTRING(group->name)
}

SQInteger			GroupSetup(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	group->Setup();
	__SQ_RETURN
}

SQInteger			GroupSetupScript(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	__LOG_V__ << "GroupSetupScript: STUB\n";
	__SQ_RETURN
}

SQInteger			GroupRenderSetup(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSAFEPTR(rf, GS::Core::ResourceFactories, typetag_ResourceFactories)
	__SQ_GETEND
	group->RenderSetup(rf);
	__SQ_RETURN
}

SQInteger			GroupReset(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	group->Reset();
	__SQ_RETURN
}

SQInteger			GroupSetMotion(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(group, Group, typetag_Group)
	__SQ_GETSTRING(name)
	__SQ_GETFLOAT(blend)
	GS::Automation::SourceGroup *anim_group = NULL;
	group->SetMotion(name, &anim_group, blend);
	__SQ_GETEND
	__SQ_RETURNMANAGEDSAFEPTR(anim_group, typetag_AutomationSourceGroup)
}

//--------------------------------------------------
SQInteger			GroupGetItemList(HSQUIRRELVM vm)
//--------------------------------------------------
{
	__SQ_GETSINGLESAFEPTR(group, Group, typetag_Group)
	sq_newarray(vm, 0);
	ListForeachPtr(MItem *, i, group->GetItemList())
	{
		CObject::Push(vm, (void *)i, typetag_Item);
		sq_arrayappend(vm, -2);
	}
	return 1;
}

//----------------------------------------------
void		RegisterGroupBinding(HSQUIRRELVM vm)
//----------------------------------------------
{
/*#
	Topic: Group
	Desc: A group holds a reference to several scene items.
	It is often used to keep track of instantiated 'block scene' items and resources inside a larger scene.
	Type: Group
	Related: Scene, Item
#*/

/*#
	Section: GroupManagement
	Desc: Management
#*/
	/*#
		Func: GroupSetup
		Proto: void:Group group
		Desc: Setup all members of a group.
		See: ItemSetup
	#*/
	sq_register(vm, GroupSetup, "GroupSetup", _SC(".x"));
	/*#
		Func: GroupSetup
		Proto: void:Group group
		Desc: Setup all members of a group.
		See: ItemSetup
	#*/
	sq_register(vm, GroupSetup, "GroupSetup", _SC(".x"));
	/*#
		Func: GroupSetupScript
		Proto: void:Group group
		Desc: Setup the script object of all members of a group.
		See: ItemSetupScript
	#*/
	sq_register(vm, GroupSetupScript, "GroupSetupScript", _SC(".x"));
	/*#
		Func: GroupReset
		Proto: void:Group group
		Desc: Reset all members of a group.
		See: ItemReset
	#*/
	sq_register(vm, GroupReset, "GroupReset", _SC(".x"));
	/*#
		Func: GroupRenderSetup
		Proto: void:Group group,ResourceFactory factory
		Desc: Setup rendering data for all members of a group.
		Example: GroupRenderSetup(group, g_factory)
		See: ItemRenderSetup
	#*/
	sq_register(vm, GroupRenderSetup, "GroupRenderSetup", _SC(".xx"));

	/*#
		Func: GroupGetItemList
		Proto: Array:Group group
		Desc: Return the group item list.
		Example:
function ListGroupItemNames(group)
{
	local group_name = GroupGetName(group)

	local items = GroupGetItemList(group)
	foreach (item in items)
		print("Item " + ItemGetName(item) + " is a member of group" + group_name + ".")
}
	#*/
	sq_register(vm, GroupGetItemList, "GroupGetItemList", _SC(".x"));

	/*#
		Func: GroupGetRootItem
		Proto: Item:Group group
		Desc: Return the root item of a group.
	#*/
	sq_register(vm, GroupGetRootItem, "GroupGetRootItem", _SC(".x"));
	/*#
		Func: GroupSetRootItem
		Proto: void:Group group,Item root_item
		Desc: Set the root item of a group. All members of a group are linked to its root item if it has one.
	#*/
	sq_register(vm, GroupSetRootItem, "GroupSetRootItem", _SC(".xx"));
	/*#
		Func: GroupSetInvisible
		Proto: void:Group group,bool set_invisible
		Desc: Hide all members of a group.
	#*/
	sq_register(vm, GroupSetInvisible, "GroupSetInvisible", _SC(".xb"));
	/*#
		Func: GroupFindItem
		Proto: item:Group group,string name_to_find
		Desc: Find an item in a group from its name.
	#*/
	sq_register(vm, GroupFindItem, "GroupFindItem", _SC(".xs"));
	/*#
		Func: GroupItemIsMember
		Proto: bool:Group group,Item item_to_test
		Desc: Returns true if item the belongs to the group, false otherwise.
	#*/
	sq_register(vm, GroupItemIsMember, "GroupItemIsMember", _SC(".xx"));
	/*#
		Func: GroupAddItem
		Proto: void:Group group,Item item_to_add
		Desc: Add an item to a group.
	#*/
	sq_register(vm, GroupAddItem, "GroupAddItem", _SC(".xx"));
	/*#
		Func: GroupRemoveItem
		Proto: void:Group group,Item item_to_remove
		Desc: Remove an item from a group.
	#*/
	sq_register(vm, GroupRemoveItem, "GroupRemoveItem", _SC(".xx"));
	/*#
		Func: GroupSetName
		Proto: void:Group group,string name
		Desc: Set the name of a group.
	#*/
	sq_register(vm, GroupSetName, "GroupSetName", _SC(".xs"));
	/*#
		Func: GroupGetName
		Proto: string:Group group
		Desc: Get the name of a group.
	#*/
	sq_register(vm, GroupGetName, "GroupGetName", _SC(".x"));

/*#
	Section: GroupTransform
	Desc: Transformation
#*/
	/*#
		Func: GroupOffsetMatrix
		Proto: void:Group group,matrix4 offset_matrix
		Desc: Apply a 4x4 offset matrix to all group members.
		See: TransformationMatrix
	#*/
	sq_register(vm, GroupOffsetMatrix, "GroupOffsetMatrix", _SC(".xx"));

/*#
	Section: GroupMotion
	Desc: Motion
#*/
	/*#
		Func: GroupSetMotion
		Proto: AnimationSourceGroup:Group group,string motion_name,float blend
		Desc: Set motion on all group items, specify the blend duration, stop all current animation sources.
		See: ItemSetMotion
	#*/
	sq_register(vm, GroupSetMotion, "GroupSetMotion", _SC(".xsn"));
}
