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


		#include "squirrel_binding.h"
		#include "binding_helpers.h"
		#include "script_squirrel/cobject/matrix_decl.h"
		#include "ui/ui.h"
		#include "ui/ui_ace_manager.h"
		#include "ui/ui_cursor.h"
		#include "ui/ui_camera.h"
		#include "ui/widget_canvas.h"
		#include "ui/widget_check.h"
		#include "ui/widget_sizer.h"
		#include "ui/widget_spacer.h"
		#include "ui/widget_staticcontainer.h"
		#include "ui/ui_window.h"
		#include "scene3d/scene.h"
		#include "core/renderer.h"
		#include "script/scripted_object.h"
		#include "script/script_unit.h"

#include "picture/pict_io.h"
		using namespace GS;
		using namespace GS::S2D;
		using namespace GS::Script;


static CObjectType item_derived_types[] = { typetag_UIItem, typetag_UISprite, typetag_Window, typetag_Undefined };
static CObjectType sprite_derived_types[] = { typetag_UISprite, typetag_Window, typetag_Undefined };

Widget	*GetWidget(HSQUIRRELVM vm , int idx);
#define	__SQ_ASSERTSPRITEISWINDOW(__V__)	if	(__V__->GetItemType() != S2D::Item::Type_Window) return sq_throwerror(vm, "Sprite is not a window");

//

SQInteger			WebcamTextureBlit(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
		__SQ_GETSAFEPTRALLOWNULL(t, Render::Texture, typetag_Texture)
		__SQ_GETINT(i)
	t->Blit((char*)(i), 640, 480, 0U, 0U, Render::Texture::FormatRGBA8);

	__SQ_GETEND
		__SQ_RETURN
}

//-----------------------------------------------------------------------------
SQInteger			UIFromNML(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(scene, Scene, typetag_Scene2d)
	__SQ_GETSTRING(path)
	Group *group = NULL;
	if	(!scene->FromMetaFileStoreGroup(path, &group))
		return sq_throwerror(vm, "Failed to load scene.");
//	scene->InstanceSetup();
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(group, typetag_Group)
}
SQInteger			UIFromNMLStoreGroup(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(scene, Scene, typetag_Scene2d)
	__SQ_GETSTRING(path)
	__SQ_GETINT(flag)
	Group *group = NULL;
	if	(!scene->FromMetaFileStoreGroup(path, &group, flag))
		return sq_throwerror(vm, "Failed to load scene.");
//	scene->InstanceSetup();
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(group, typetag_Group)
}
//-----------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowCompare(HSQUIRRELVM vm)
{
	Sprite *wa, *wb;
	if	(!CObject::Get(vm, -2, (void **)&wa, typetag_Window))
		return -1;
	if	(!CObject::Get(vm, -1, (void **)&wb, typetag_Window))
		return -1;
	sq_pop(vm, 2);

	sq_pushbool(vm, wa == wb ? true : false);
	return 1;
}

SQInteger			SceneGetUI(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(scene, S3D::Scene, typetag_Scene3d)
	__SQ_RETURNSAFEPTR(scene->ui.c_ptr(), typetag_Scene2d)
}

SQInteger			UIRenderSetup(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSAFEPTR(f, Core::ResourceFactories, typetag_ResourceFactories)
	__SQ_GETEND
	ui->RenderSetup(f);
	__SQ_RETURN
}
SQInteger			UISetVirtualResolution(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETINT(w)
	__SQ_GETINT(h)
	__SQ_GETEND
	ui->GetDefaultCamera()->resolution.Set((float)w, (float)h);
	__SQ_RETURN
}

SQInteger			UIGetVirtualResolution(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_RETURNVECTOR2(Vector2(ui->GetDefaultCamera()->resolution.x, ui->GetDefaultCamera()->resolution.y))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UIGetScreenToUIMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_RETURNMATRIX3(ui->GetScreenToUIMatrix())
}
SQInteger			UIGetUIToScreenMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_RETURNMATRIX3(ui->GetUIToScreenMatrix())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UIItemCastToSprite(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(i, Item, typetag_UIItem)
	if	(i->GetItemType() != Item::Type_Sprite)
		return sq_throwerror(vm, "UI item cannot be cast to sprite.");
	__SQ_RETURNSAFEPTR((Sprite *)i, typetag_UISprite)
}
SQInteger			UIItemCastToWindow(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(i, Item, typetag_UIItem)
	if	(i->GetItemType() != Item::Type_Window)
		return sq_throwerror(vm, "UI item cannot be cast to window.");
	__SQ_RETURNSAFEPTR((Window *)i, typetag_Window)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UILockToSprite(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSAFEPTR(sprite, Sprite, typetag_Window)
	__SQ_GETEND
	ui->Lock(sprite);
	__SQ_RETURN
}
SQInteger			UIUnlock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	ui->Unlock();
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UISetCommandList(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSTRING(list)
	ACEManager::Get()->LoadACECommandList(list, ui);
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			UIIsCommandListDone(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_RETURNBOOL(ui->IsCommandListDone())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UICursorGetWindowBelow(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(cursor, Cursor, typetag_UICursor)
	Window *w = NULL;
	if	(Item *i = cursor->current_state.item)
		w = i->GetItemType() == Item::Type_Window ? (Window *)i : NULL;
	if	(w == NULL)
		__SQ_RETURNNULL
	__SQ_RETURNSAFEPTR(w, typetag_Window)
}
SQInteger			UICursorGetSpriteBelow(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(cursor, Cursor, typetag_UICursor)
	Sprite *s = NULL;
	if	(Item *i = cursor->current_state.item)
		s = i->GetItemType() == Item::Type_Sprite ? (Sprite *)i : NULL;
	if	(s == NULL)
		__SQ_RETURNNULL
	__SQ_RETURNSAFEPTR(s, typetag_UISprite)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UISetGlobalFadeEffect(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETFLOAT(fade)
	__SQ_GETEND
	ui->SetGlobalFadeEffect(fade);
	__SQ_RETURN
}

SQInteger			UISetGlobalFadeColor(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETINT(r)
	__SQ_GETINT(g)
	__SQ_GETINT(b)
	__SQ_GETEND
	ui->global_fade_color.x = (float)r / 255.f;
	ui->global_fade_color.y = (float)g / 255.f;
	ui->global_fade_color.z = (float)b / 255.f;
	__SQ_RETURN
}

//------------------------------------------------------------------------------
SQInteger			UIWindowCentre(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETEND
	Vector2 pos = (ui->GetCurrentCamera()->resolution - item->GetSize()) * 0.5f + item->GetPivot();
	item->SetPosition(pos.x, pos.y);
	__SQ_RETURN
}
SQInteger			WindowSetParent(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(w, Sprite, typetag_Window)
	__SQ_GETSAFEPTRALLOWNULL(p, Sprite, typetag_Window)
	__SQ_GETEND
	w->SetParent(p);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowSetCommandList(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETSTRING(list)
	ACEManager::Get()->LoadACECommandList(list, sprite);
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			WindowIsCommandListDone(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types))
	__SQ_RETURNBOOL(sprite->IsCommandListDone())
}
SQInteger			WindowResetCommandList(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types))
	sprite->ResetCommandList();
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowSetPosition(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND
	item->SetPosition(x, y);
	__SQ_RETURN
}
SQInteger			WindowSetRotation(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(a)
	__SQ_GETEND
	item->SetRotation(a);
	__SQ_RETURN
}
SQInteger			WindowSetScale(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND
	item->SetScale(x, y);
	__SQ_RETURN
}
SQInteger			WindowSetPivot(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND
	item->SetPivot(x, y);
	__SQ_RETURN
}
SQInteger			WindowSetSize(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND
	item->SetSize(x, y);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetPosition(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNVECTOR2(item->GetPosition())
}
SQInteger			WindowGetPivot(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNVECTOR2(item->GetPivot())
}
SQInteger			WindowGetSize(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNVECTOR2(item->GetSize())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetRect(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNRECT(item->GetRect())
}
SQInteger			WindowGetScreenRect(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNRECT(item->GetScreenRect())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetName(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNSTRING(item->name.c_str())
}
SQInteger			WindowGetTitle(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(w, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(w)

	Widget *title = ((Window *)w)->GetTitleWidget();
	if	(title->GetType() != WidgetTypeText)
		return sq_throwerror(vm, "Window title widget is not a text widget.");

	TextWidget *text = (TextWidget *)title;
	__SQ_RETURNSTRING(text->GetText())
}
SQInteger			WindowSetTitle(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(w, Sprite, typetag_Window)
	__SQ_GETSTRING(title_string)

	__SQ_ASSERTSPRITEISWINDOW(w)

	Widget *title = ((Window *)w)->GetTitleWidget();
	if	(title->GetType() != WidgetTypeText)
		return sq_throwerror(vm, "Window title widget is not a text widget.");

	TextWidget *text = (TextWidget *)title;
	text->SetText(title_string);

	__SQ_GETEND
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetParent(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNSAFEPTR(item->GetParent(), typetag_UIItem)
}

SQInteger			WindowGetChild(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(s, Sprite, typetag_Window)
	__SQ_GETINT(id)
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(s->GetItemType() == S2D::Item::Type_Window ? ((Window *)s)->GetWidget(id) : NULL, typetag_Widget)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowSetZOrder(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types)
	__SQ_GETFLOAT(z)
	__SQ_GETEND
	item->SetZOrder(z);
	__SQ_RETURN
}
SQInteger			WindowGetZOrder(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(item, S2D::Item, item_derived_types))
	__SQ_RETURNFLOAT(item->GetZOrder())
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowSetFlip(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETBOOL(u)
	__SQ_GETBOOL(v)
	__SQ_GETEND
	sprite->sprite_flags.Raise(Sprite::FlagFlipU, asbool(u));
	sprite->sprite_flags.Raise(Sprite::FlagFlipV, asbool(v));
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowSetOpacity(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETFLOAT(o)
	__SQ_GETEND
	sprite->opacity = o;
	__SQ_RETURN
}
SQInteger			WindowGetOpacity(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types))
	__SQ_RETURNFLOAT(sprite->opacity)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetStyle(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types))
	__SQ_RETURNINT(sprite->sprite_flags.Get())
}
SQInteger			WindowSetStyle(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETINT(v)
	__SQ_GETEND
	sprite->sprite_flags = v;
	__SQ_RETURN
}
SQInteger			WindowAddStyle(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETINT(v)
	__SQ_GETEND
	sprite->sprite_flags.Set(v);
	__SQ_RETURN
}
SQInteger			WindowRemoveStyle(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(sprite, Sprite, sprite_derived_types)
	__SQ_GETINT(v)
	__SQ_GETEND
	sprite->sprite_flags.Remove(v);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WindowGetBackgroundPicture(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(w, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(w)
	__SQ_RETURNSAFEPTR(((Window *)w)->background_picture, typetag_Picture)
}
SQInteger			WindowSetBackgroundPicture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(w, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(w)
	__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
	__SQ_GETEND
	((Window *)w)->background_picture = p;
	__SQ_RETURN
}
SQInteger			WindowSetBackgroundColor(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(w, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(w)
	__SQ_GETINT(icolor)
	__SQ_GETEND
	((Window *)w)->background_color = Color(uint(icolor));
	__SQ_RETURN
}
SQInteger			UIDeleteWindow(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSAFEPTR(s, Sprite, typetag_Window)
	__SQ_GETEND
	ui->RemoveItem(s);
	__SQ_RETURN
}
SQInteger			UIDeleteAllItems(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	ui->DeleteAllItems();
	__SQ_RETURN
}
SQInteger			UIAddSprite(HSQUIRRELVM vm)
{
	__SQ_GETSTART(7)
	__SQ_GETSAFEPTR(scene, Scene, typetag_Scene2d)
	__SQ_GETINT(idx)
	__SQ_GETSAFEPTRALLOWNULL(t, Render::Texture, typetag_Texture)
	__SQ_GETFLOAT(px)
	__SQ_GETFLOAT(py)
	__SQ_GETFLOAT(sx)
	__SQ_GETFLOAT(sy)
	Sprite *s = new Sprite;
	if	(!s)
		return sq_throwerror(vm, "Failed to allocate sprite.");
	s->name = String::Format("%d", idx);
	s->SetPosition(px, py);
	s->SetSize(sx, sy);
	s->RenderSetup();
	s->render_data->texture = t;
	scene->AddItem(s, true);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(s, typetag_Window)
}
SQInteger			UIAddNamedSprite(HSQUIRRELVM vm)
{
	__SQ_GETSTART(7)
	__SQ_GETSAFEPTR(scene, Scene, typetag_Scene2d)
	__SQ_GETSTRING(name)
	__SQ_GETSAFEPTRALLOWNULL(t, Render::Texture, typetag_Texture)
	__SQ_GETFLOAT(px)
	__SQ_GETFLOAT(py)
	__SQ_GETFLOAT(sx)
	__SQ_GETFLOAT(sy)
	Sprite *s = new Sprite;
	s->name = name;
	s->SetPosition(px, py);
	s->SetSize(sx, sy);
	scene->AddItem(s, true);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(s, typetag_Window)
}
SQInteger			SpriteSetTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(s, Sprite, typetag_Window)
	__SQ_GETSAFEPTRALLOWNULL(t, Render::Texture, typetag_Texture)
	if	(!s->render_data)
		return sq_throwerror(vm, "Sprite not setup, please call SpriteRenderSetup() before changing its texture.");
	s->render_data->texture = t;
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			SpriteSetUVOrigin(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(s, Sprite, typetag_Window)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND
	s->uv_origin.Set(x, y);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			SpriteRenderSetup(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(s, Sprite, sprite_derived_types)
	__SQ_GETSAFEPTRALLOWNULL(f, Core::ResourceFactories, typetag_ResourceFactories)
	__SQ_GETEND
	s->RenderSetup(f);
	__SQ_RETURN
}

SQInteger			SpriteSetTextureMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETCOBJECTBASE(s, Sprite, sprite_derived_types)
	__SQ_GETMATRIX3(m)
	__SQ_GETEND
	s->uv_matrix = m;
	__SQ_RETURN
}
SQInteger			UIAddNamedWindow(HSQUIRRELVM vm)
{
	__SQ_GETSTART(6)
	__SQ_GETSAFEPTR(scene, Scene, typetag_Scene2d)
	__SQ_GETSTRING(name)
	__SQ_GETFLOAT(px)
	__SQ_GETFLOAT(py)
	__SQ_GETFLOAT(sx)
	__SQ_GETFLOAT(sy)
	Window *w = new Window;
	w->name = name;
	w->SetPosition(px, py);
	w->SetSize(sx, sy);
	scene->AddItem(w, true);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(w, typetag_Window)
}
SQInteger			UIAddNamedBitmapWindow(HSQUIRRELVM vm)
{
	__SQ_GETSTART(7)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSTRING(name)
	__SQ_GETSAFEPTRALLOWNULL(bitmap, Picture, typetag_Picture)
	__SQ_GETFLOAT(px)
	__SQ_GETFLOAT(py)
	__SQ_GETFLOAT(sx)
	__SQ_GETFLOAT(sy)
	Window *w = new Window;
	w->name = name;
	w->SetPosition(px, py);
	w->SetSize(sx, sy);
	w->background_picture = bitmap;
	ui->AddItem(w, true);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(w, typetag_Window)
}
SQInteger			WindowGetCacheTexture(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(w, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(w)
	__SQ_RETURNSAFEPTR(((Window *)w)->GetCache(), typetag_Texture);
}

SQInteger			WindowSetBaseWidget(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(sprite, Sprite, typetag_Window)
	Widget *widget = GetWidget(vm, __sq_stackpos);
	__SQ_GETUPDATESTACK
	__SQ_GETEND

	if	(sprite->GetItemType() == S2D::Item::Type_Window)
		if	(Window *window = (Window *)sprite)
			window->SetBaseWidget(widget);

	__SQ_RETURN
}

SQInteger			WindowForceLayout(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(w, Sprite, typetag_Window)
//	wnd->Render(NULL);
	__SQ_RETURN
}

SQInteger			WindowInvalidate(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(wnd, Sprite, typetag_Window)
	__SQ_ASSERTSPRITEISWINDOW(wnd)
	((Window *)wnd)->Invalidate();
	__SQ_RETURN
}

SQInteger			UISetSkin(HSQUIRRELVM vm)
{
	Scene *sys;
	if	(!CObject::Get(vm, -16, (void **)&sys, typetag_Scene2d))
		return sq_throwerror(vm, "Invalid UI");

	Core::ResourceFactories *f;
	if	(!CObject::Get(vm, -15, (void **)&f, typetag_ResourceFactories))
		return sq_throwerror(vm, "Invalid resource factory.");

	const char *l, *r, *t, *b, *tl, *tr, *bl, *br;
	sq_getstring(vm, -14, &t);
	sq_getstring(vm, -13, &l);
	sq_getstring(vm, -12, &r);
	sq_getstring(vm, -11, &b);
	sq_getstring(vm, -10, &tl);
	sq_getstring(vm, -9, &tr);
	sq_getstring(vm, -8, &bl);
	sq_getstring(vm, -7, &br);

	SQInteger skin_color;
	sq_getinteger(vm, -6, &skin_color);

	SQInteger skin_title_color, skin_title_top, skin_title_bottom, skin_title_size;
	sq_getinteger(vm, -5, &skin_title_color);
	sq_getinteger(vm, -4, &skin_title_top);
	sq_getinteger(vm, -3, &skin_title_bottom);
	sq_getinteger(vm, -2, &skin_title_size);

	const char *skin_title_font;
	sq_getstring(vm, -1, &skin_title_font);

	sys->window_skin = new WindowSkin;

	sys->window_skin->top = f->graphic->LoadPicture(t);
	sys->window_skin->left = f->graphic->LoadPicture(l);
	sys->window_skin->right = f->graphic->LoadPicture(r);
	sys->window_skin->bottom = f->graphic->LoadPicture(b);
	sys->window_skin->top_left = f->graphic->LoadPicture(tl);
	sys->window_skin->top_right = f->graphic->LoadPicture(tr);
	sys->window_skin->bottom_left = f->graphic->LoadPicture(bl);
	sys->window_skin->bottom_right = f->graphic->LoadPicture(br);

	sys->window_skin->color = skin_color;
	sys->window_skin->title_color = skin_title_color;
	sys->window_skin->title_top = skin_title_top;
	sys->window_skin->title_bottom = skin_title_bottom;
	sys->window_skin->title_size = skin_title_size;
//	sys->window_skin->title_font = skin_title_font;

	sq_pop(vm, 15);

	sq_pushbool(vm, true);
	return 1;
}

SQInteger			UIAddCanvasWidget(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETINT(id)
	__SQ_GETINT(w)
	__SQ_GETINT(h)
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(new CanvasWidget((int)id, (int)w, (int)h), typetag_CanvasWidget)
}

SQInteger			CanvasWidgetLock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(c, CanvasWidget, typetag_CanvasWidget)
	__SQ_RETURNSAFEPTR(c->Lock(), typetag_Picture)
}

SQInteger			CanvasWidgetUnlock(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(c, CanvasWidget, typetag_CanvasWidget)
	c->Unlock();
	__SQ_RETURN
}

SQInteger			UIAddSpacerWidget(HSQUIRRELVM vm)
{
	Scene	*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_Scene2d))
		return -1;
	SQInteger id;
	sq_getinteger(vm, -1, &id);
	sq_pop(vm, 2);

	SpacerWidget *wd = NULL;
	if	(ws)
		wd = new SpacerWidget((int)id);
	CObject::Push(vm, wd, typetag_SpacerWidget);
	return 1;
}

SQInteger			UIAddHorizontalSizerWidget(HSQUIRRELVM vm)
{
	Scene *ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_Scene2d))
		return -1;
	SQInteger id;
	sq_getinteger(vm, -1, &id);
	sq_pop(vm, 2);

	SizerWidget	*wd = NULL;
	if	(ws)
		wd = new HSizerWidget((int)id);
	CObject::Push(vm, wd, typetag_SizerWidget);
	return 1;
}

SQInteger			UIAddVerticalSizerWidget(HSQUIRRELVM vm)
{
	Scene *ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_Scene2d))
		return -1;
	SQInteger id;
	sq_getinteger(vm, -1, &id);
	sq_pop(vm, 2);

	SizerWidget	*wd = NULL;
	if	(ws)
		wd = new VSizerWidget((int)id);
	CObject::Push(vm, wd, typetag_SizerWidget);
	return 1;
}

SQInteger			UIAddContainerWidget(HSQUIRRELVM vm)
{
	Scene *ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_Scene2d))
		return -1;
	SQInteger		id;
	sq_getinteger(vm, -1, &id);
	sq_pop(vm, 2);

	ContainerWidget	*wd = NULL;
	if	(ws)
		wd = new ContainerWidget((int)id);
	CObject::Push(vm, wd, typetag_ContainerWidget);
	return 1;
}

Widget				*GetWidget(HSQUIRRELVM vm , int idx)
{
	Widget *wdg = NULL;
	CObjectType	type;

	if	(!CObject::GetType(vm, idx, type))
		return NULL;

	switch (type)
	{
		case typetag_Widget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_Widget);
			break;
		case typetag_SizerWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_SizerWidget);
			break;
		case typetag_CheckWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_CheckWidget);
			break;
		case typetag_ContainerWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_ContainerWidget);
			break;
		case typetag_SpacerWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_SpacerWidget);
			break;
		case typetag_TextWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_TextWidget);
			break;
		case typetag_CanvasWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_CanvasWidget);
			break;
		case typetag_BitmapWidget:
			CObject::Get(vm, idx, (void **)&wdg, typetag_BitmapWidget);
			break;

		default:
			sq_throwerror(vm, "Object is not a widget");
			return NULL;
	}

	if	(!wdg)
	{
		sq_throwerror(vm, "Widget is null");
		return NULL;
	}
	return wdg;
}

#define	__SQ_GETWIDGET(__VAR__)		Widget *__VAR__ = GetWidget(vm, __sq_stackpos); __SQ_GETUPDATESTACK if (!__VAR__) return -1;

SQInteger			CastToWidget(HSQUIRRELVM vm)
{
	Widget			*wdg = GetWidget(vm, -1);
	if	(!wdg)
		return -1;
	sq_pop(vm, 1);
	__SQ_RETURNSAFEPTR(wdg, typetag_Widget)
}

SQInteger			UIDeleteWidget(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETWIDGET(w)
	__SQ_GETEND
	if	(ui && w)	_safe_delete(w);
	__SQ_RETURN
}

SQInteger			SizerAddWidget(HSQUIRRELVM vm)
{
	SizerWidget	*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_SizerWidget))
		return -1;
	CObjectType	widget_type;
	if	(!CObject::GetType(vm, -1, widget_type))
		return -1;

	Widget			*wdg = GetWidget(vm, -1);
	if	(!wdg)
		return -1;
	sq_pop(vm, 2);

	if	(ws && wdg)
		ws->Add(wdg);

	CObject::Push(vm, wdg, widget_type);
	return 1;
}

SQInteger			ContainerAddWidget(HSQUIRRELVM vm)
{
	ContainerWidget	*ws;
	if	(!CObject::Get(vm, -6, (void **)&ws, typetag_ContainerWidget))
		return -1;

	CObjectType	widget_type;
	if	(!CObject::GetType(vm, -5, widget_type))
		return -1;
	Widget			*wdg = GetWidget(vm, -5);
	if	(!wdg)
		return -1;

	float				sx, sy, w, h;
	sq_getfloat(vm, -4, &sx);
	sq_getfloat(vm, -3, &sy);
	sq_getfloat(vm, -2, &w);
	sq_getfloat(vm, -1, &h);
	sq_pop(vm, 6);

	if	(ws && wdg)
	{
		iRect cell_rect((int)sx, (int)sy, (int)(sx + w), (int)(sy + h));
		ws->Add(wdg, cell_rect);
	}
	CObject::Push(vm, wdg, widget_type);
	return 1;
}

SQInteger			ContainerWidgetSetPosition(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(ws, ContainerWidget, typetag_ContainerWidget)
	__SQ_GETWIDGET(wdg)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETEND

	ContainerCell *cell = ws->GetCell(wdg);
	if	(!cell)
		return sq_throwerror(vm, "Widget not in container");

	cell->cell_rect.Offset(int(x - cell->cell_rect.sx), int(y - cell->cell_rect.sy));
	ws->Invalidate();

	__SQ_RETURN
}

//------------------------------------------------------------------------------
SQInteger			WidgetSetEventHandler(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	Widget	*widget = GetWidget(vm, __sq_stackpos);
	__SQ_GETUPDATESTACK
	if	(!widget)
		return sq_throwerror(vm, "Null widget");
	__SQ_GETINT(event)
	__SQ_GETOBJECT(handler)
	__SQ_GETEND
	widget->GetEventTable()->SetHandler((EventCode)event, new Script::SquirrelObject(*GetVMObject(vm), handler));
	__SQ_RETURN
}
SQInteger			WidgetSetEventHandlerWithContext(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	Widget	*widget = GetWidget(vm, __sq_stackpos);
	__SQ_GETUPDATESTACK
	if	(!widget)
		return sq_throwerror(vm, "Null widget");
	__SQ_GETINT(event)
	__SQ_GETOBJECT(context)
	__SQ_GETOBJECT(handler)
	__SQ_GETEND
	widget->GetEventTable()->SetHandler((EventCode)event, new Script::SquirrelObject(*GetVMObject(vm), handler), new Script::SquirrelObject(*GetVMObject(vm), context));
	__SQ_RETURN
}

SQInteger			WindowSetEventHandler(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(window, Sprite, typetag_Window)
	__SQ_GETINT(event)
	__SQ_GETOBJECT(handler)
	__SQ_GETEND
	window->GetEventTable()->SetHandler((EventCode)event, new Script::SquirrelObject(*GetVMObject(vm), handler));
	__SQ_RETURN
}
SQInteger			WindowSetEventHandlerWithContext(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(window, Sprite, typetag_Window)
	__SQ_GETINT(event)
	__SQ_GETOBJECT(context)
	__SQ_GETOBJECT(handler)
	__SQ_GETEND
	window->GetEventTable()->SetHandler((EventCode)event, new Script::SquirrelObject(*GetVMObject(vm), handler), new Script::SquirrelObject(*GetVMObject(vm), context));
	__SQ_RETURN
}
//------------------------------------------------------------------------------

SQInteger			WidgetSetSensitive(HSQUIRRELVM vm)
{
	Widget *w = GetWidget(vm, -2);
	if	(!w)
		return -1;
	SQBool bs;
	sq_getbool(vm, -1, &bs);

	w->GetEventTable()->Enable(bs ? true : false);
	sq_pop(vm, 2);
	return 0;
}

SQInteger			WidgetSetHAlign(HSQUIRRELVM vm)
{
	Widget *w = GetWidget(vm, -2);
	if	(!w)
		return -1;
	SQInteger a;
	sq_getinteger(vm, -1, &a);
	sq_pop(vm, 2);

	w->SetHAlign((Widget::Align)a);
	return 0;
}

SQInteger			WidgetSetVAlign(HSQUIRRELVM vm)
{
	Widget			*wdg = GetWidget(vm, -2);
	if	(!wdg)
		return -1;
	SQInteger		a;
	sq_getinteger(vm, -1, &a);
	sq_pop(vm, 2);

	wdg->SetVAlign((Widget::Align)a);
	return 0;
}

SQInteger			WidgetSetHidden(HSQUIRRELVM vm)
{
	Widget			*wdg = GetWidget(vm, -2);
	if	(!wdg)
		return -1;
	SQBool			hidden;
	sq_getbool(vm, -1, &hidden);
	sq_pop(vm, 2);

	wdg->SetHidden(hidden ? true : false);
	return 0;
}

SQInteger			WidgetGetRect(HSQUIRRELVM vm)
{
	Widget *wdg = GetWidget(vm, -1);
	if	(!wdg)
		return -1;
	sq_pop(vm, 1);

	iRect rect(-1, -1, -1, -1);
	rect = wdg->GetRect();
	PushRect(vm, rect);
	return 1;
}

SQInteger			WidgetIsHidden(HSQUIRRELVM vm)
{
	Widget			*wdg = GetWidget(vm, -1);
	if	(!wdg)
		return -1;
	sq_pop(vm, 1);
	__SQ_RETURNBOOL(wdg->IsHidden())
}

SQInteger			WidgetSetFormattingSize(HSQUIRRELVM vm)
{
	Widget *wdg = GetWidget(vm, -3);
	if	(!wdg)
		return -1;
	SQFloat			h, v;
	sq_getfloat(vm, -2, &h);
	sq_getfloat(vm, -1, &v);
	sq_pop(vm, 3);

	wdg->SetFormattingSize(Vector2(h, v));
	return 0;
}

//------------------------------------------------------------------------------
SQInteger			UIAddBitmapWidget(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Sprite, typetag_Scene2d)
	__SQ_GETINT(id)
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(new BitmapWidget((int)id), typetag_BitmapWidget)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
#define	__SQ_CHECKWIDGETTYPE(__Type)	if (w->GetType() != __Type) return sq_throwerror(vm, "Invalid widget cast.");
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			WidgetToBitmap(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(w, Widget, typetag_Widget)
	__SQ_CHECKWIDGETTYPE(WidgetTypeBitmap)
	__SQ_RETURNSAFEPTR((BitmapWidget *)w, typetag_BitmapWidget)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			BitmapSetPicture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(w, BitmapWidget, typetag_BitmapWidget)
	__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
	__SQ_GETEND
	w->SetPicture(p);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

SQInteger			UIAddTextWidget(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(ws, Scene, typetag_Scene2d)
	__SQ_GETINT(id)
	__SQ_GETSTRING(text)
	__SQ_GETSAFEPTR(font, FontEx, typetag_Font)
	TextWidget *wd = new TextWidget(id, text, font);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(wd, typetag_TextWidget)
}

SQInteger			UIAddCheckWidget(HSQUIRRELVM vm)
{
	Scene	*ws;
	if	(!CObject::Get(vm, -5, (void **)&ws, typetag_Scene2d))
		return -1;
	SQInteger		id;
	sq_getinteger(vm, -4, &id);
	const char		*text;
	sq_getstring(vm, -3, &text);
	const char		*font_name;
	sq_getstring(vm, -2, &font_name);
	SQBool			initial_state;
	sq_getbool(vm, -1, &initial_state);

	CheckWidget	*wd = NULL;
	if	(ws)
	{
//		wd = new CheckWidget(*ws, (int)id, text, Scene::GetFontCache().GetFont(font_name));
		if	(wd)
			wd->SetState(initial_state ? true : false);
	}
	sq_pop(vm, 5);	// Take care of the strings.
	CObject::Push(vm, wd, typetag_CheckWidget);
	return 1;
}

SQInteger			CheckWidgetSetState(HSQUIRRELVM vm)
{
	CheckWidget	*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_CheckWidget))
		return -1;
	SQBool			state;
	sq_getbool(vm, -1, &state);
	sq_pop(vm, 2);

	if	(ws)
		ws->SetState(state ? true : false);
	return 0;
}

SQInteger			CheckWidgetGetState(HSQUIRRELVM vm)
{
	CheckWidget	*ws;
	if	(!CObject::Get(vm, -1, (void **)&ws, typetag_CheckWidget))
		return -1;
	sq_pop(vm, 1);

	bool			state = false;
	if	(ws)
		state = ws->GetState();
	sq_pushbool(vm, state);
	return 1;
}

SQInteger			CheckWidgetSetLabel(HSQUIRRELVM vm)
{
	CheckWidget	*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_CheckWidget))
		return -1;

	const char		*label = NULL;
	sq_getstring(vm, -1, &label);
	if	(ws)
		ws->GetLabel().SetText(label);
	sq_pop(vm, 2);	// Take care of the string.
	return 0;
}

SQInteger			CheckWidgetSetLabelFont(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ws, CheckWidget, typetag_CheckWidget)
	__SQ_GETSAFEPTR(font, FontEx, typetag_Font)
	__SQ_GETEND
	ws->GetLabel().SetFont(font);
	__SQ_RETURN
}

SQInteger			CheckWidgetSetLabelSize(HSQUIRRELVM vm)
{
	CheckWidget	*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_CheckWidget))
		return -1;
	SQInteger		size;
	sq_getinteger(vm, -1, &size);
	sq_pop(vm, 2);

	if	(ws)
		ws->GetLabel().SetFontSize((int)size);
	return 0;
}

SQInteger			CheckWidgetGetText(HSQUIRRELVM vm)
{
	CheckWidget	*ws;
	if	(!CObject::Get(vm, -1, (void **)&ws, typetag_CheckWidget))
		return -1;
	sq_pop(vm, 1);

	TextWidget		*wt = NULL;
	if	(ws)
		wt = &ws->GetLabel();
	CObject::Push(vm, wt, typetag_TextWidget);
	return 1;
}

SQInteger			WidgetToText(HSQUIRRELVM vm)
{
	Widget		*ws;
	if	(!CObject::Get(vm, -1, (void **)&ws, typetag_Widget))
		return -1;
	sq_pop(vm, 1);

	TextWidget	*wt = NULL;
	if	(ws)
		wt = (TextWidget *)ws;
	CObject::Push(vm, wt, typetag_TextWidget);
	return 1;
}

SQInteger			WidgetToCheck(HSQUIRRELVM vm)
{
	Widget		*ws;
	if	(!CObject::Get(vm, -1, (void **)&ws, typetag_Widget))
		return -1;
	sq_pop(vm, 1);

	CheckWidget	*wt = NULL;
	if	(ws)
		wt = (CheckWidget *)ws;
	CObject::Push(vm, wt, typetag_CheckWidget);
	return 1;
}

SQInteger			TextSetAlignment(HSQUIRRELVM vm)
{
	TextWidget		*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_TextWidget))
		return -1;
	SQInteger		a;
	sq_getinteger(vm, -1, &a);
	sq_pop(vm, 2);

	if	(ws)
		ws->SetTextAlignment((TextState::Alignment)a);
	return 0;
}

SQInteger			TextSetFormat(HSQUIRRELVM vm)
{
	TextWidget		*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_TextWidget))
		return -1;
	SQInteger		f;
	sq_getinteger(vm, -1, &f);
	sq_pop(vm, 2);

	if	(ws)
		ws->SetTextFormat((TextState::Format)f);
	return 0;
}

SQInteger			TextSetSize(HSQUIRRELVM vm)
{
	TextWidget		*ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_TextWidget))
		return -1;
	SQInteger		s;
	sq_getinteger(vm, -1, &s);
	sq_pop(vm, 2);

	if	(ws)
		ws->SetFontSize((int)s);
	return 0;
}

SQInteger			TextSetColor(HSQUIRRELVM vm)
{
	TextWidget		*ws;
	if	(!CObject::Get(vm, -5, (void **)&ws, typetag_TextWidget))
		return -1;
	SQInteger		r, g, b, a;
	sq_getinteger(vm, -4, &r);
	sq_getinteger(vm, -3, &g);
	sq_getinteger(vm, -2, &b);
	sq_getinteger(vm, -1, &a);
	sq_pop(vm, 5);

	if	(ws)
		ws->SetFontColor((float)r / 255.f, (float)g / 255.f, (float)b / 255.f, (float)a / 255.f);
	return 0;
}

SQInteger			TextSetText(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ws, TextWidget, typetag_TextWidget)
	__SQ_GETSTRING(txt)
	ws->SetText(txt);
	__SQ_GETEND
	__SQ_RETURN
}

SQInteger			SizerSetDrawDelimiter(HSQUIRRELVM vm)
{
	sq_pop(vm, 2);
	return 0;
}

SQInteger			SizerSetBorderSize(HSQUIRRELVM vm)
{
	SizerWidget *ws;
	if	(!CObject::Get(vm, -5, (void **)&ws, typetag_SizerWidget))
		return -1;

	SQInteger t, b, l, r;
	sq_getinteger(vm, -4, &l);
	sq_getinteger(vm, -3, &t);
	sq_getinteger(vm, -2, &r);
	sq_getinteger(vm, -1, &b);
	sq_pop(vm, 5);

	if	(ws)
		ws->SetBorderSize((float)t, (float)b, (float)l, (float)r);
	return 0;
}

void				IterateTextParameters(HSQUIRRELVM vm, int idx, TextState &state)
{
	sq_pushnull(vm);
	while (sq_next(vm, idx - 1) != SQ_ERROR)
	{
		const char *key;
		if	(sq_getstring(vm, -2, &key) != SQ_ERROR)
		{
			if	(!strcmp(key, "size"))
			{
				SQInteger size;
				sq_getinteger(vm, -1, &size);
				state.SetSize(size);
			}
			else	if	(!strcmp(key, "color"))
			{
				SQInteger icolor;
				if	(sq_getinteger(vm, -1, &icolor) != SQ_ERROR)
				{
					Color color((uint)icolor);
					state.color.x = uint(color.w * 255.f);
					state.color.y = uint(color.z * 255.f);
					state.color.z = uint(color.y * 255.f);
					state.color.w = uint(color.x * 255.f);
				}
			}
			else	if	(!strcmp(key, "align"))
			{
				const char *v;
				if	(sq_getstring(vm, -1, &v) != SQ_ERROR)
				{
							if	(!strcmp(v, "left"))
							state.alignment = TextState::Left;
					else	if	(!strcmp(v, "right"))
							state.alignment = TextState::Right;
					else	if	(!strcmp(v, "center"))
							state.alignment = TextState::Center;
					else	if	(!strcmp(v, "justify"))
							state.alignment = TextState::Justify;
					else
						__LOG_W__ << "unknown text alignment command '" << v << "'.\n";
				}
			}
			else	if	(!strcmp(key, "format"))
			{
				const char *v;
				if	(sq_getstring(vm, -1, &v) != SQ_ERROR)
				{
							if	(!strcmp(v, "standard"))
							state.format = TextState::Line;
					else	if	(!strcmp(v, "paragraph"))
							state.format = TextState::Paragraph;
					else	if	(!strcmp(v, "column"))
							state.format = TextState::Column;
					else
						__LOG_W__ << "unknown text format command '" << v << "'.\n";
				}
			}
			else	if	(!strcmp(key, "tracking"))
			{
				SQFloat tracking;
				sq_getfloat(vm, -1, &tracking);
				state.SetTracking(tracking);
			}
			else	if	(!strcmp(key, "leading"))
			{
				SQFloat leading;
				sq_getfloat(vm, -1, &leading);
				state.SetLeading(leading);
			}
			else
				__LOG_W__ << "unknown text attribute '" << key << "'.\n";
		}
		sq_pop(vm, 2);		// pop key/value.
	}
	sq_pop(vm, 1);		// pop iterator.
}

SQInteger			TextSetParameters(HSQUIRRELVM vm)
{
	TextWidget *ws;
	if	(!CObject::Get(vm, -2, (void **)&ws, typetag_TextWidget))
		return -1;

	TextState state;
	ws->GetTextState(state);
	IterateTextParameters(vm, -1, state);
	ws->SetTextState(state);

	sq_pop(vm, 2);
	return 0;
}

//------------------------------------------------------------------------------
#define	__SQ_GETUISCENESCRIPTOBJECT(__SRC) Script::ScriptedObject *scripted_object = __SRC->scripted_object; if (!scripted_object) return sq_throwerror(vm, "No script system in scene!");

SQInteger			UIGetScriptInstance(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETUISCENESCRIPTOBJECT(ui)
	if	(!scripted_object->GetUnitList().GetCount())
		return sq_throwerror(vm, "No script unit");
	Script::SquirrelObject *o = (Script::SquirrelObject *)scripted_object->GetUnitList()[0]->Self();
	__SQ_RETURNOBJECT(o->object);
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UICreateCursor(HSQUIRRELVM vm)
{
	__SQ_GETSINGLE(__SQ_GETINT(cursor_id))
	Cursor *cursor = new Cursor;
	if	(!cursor)
		return sq_throwerror(vm, "Failed to create a new UI cursor");
	cursor->id = cursor_id;
	__SQ_RETURNMANAGEDSAFEPTR(cursor, typetag_UICursor)	
}
SQInteger			UISetCursorState(HSQUIRRELVM vm)
{
	__SQ_GETSTART(5)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETSAFEPTR(cursor, Cursor, typetag_UICursor)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETBOOL(down)
	__SQ_GETEND
	cursor->current_state.x = x;
	cursor->current_state.y = y;
	cursor->current_state.down = asbool(down);
	ui->UpdateCursor(cursor);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			UISetGlobalMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(ui, Scene, typetag_Scene2d)
	__SQ_GETMATRIX3(mtx)
	__SQ_GETEND	
	ui->offset_matrix = mtx;
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//---------------------------------------------------
void				RegisterUIBinding(HSQUIRRELVM vm)
//---------------------------------------------------
{
/*#
	Topic: UI
	Type: Sprite
	Type: Window
	Type: Widget
	Type: Check
	Type: Container
	Type: UI
	Type: Canvas
	Type: Sizer
	Type: TextWidget
	Type: Bitmap
#*/

/*#
	Section: SceneIO
	Desc: I/O
#*/
	/*#
		Func: UILoad
		Proto: bool:UI,string
		Desc: Append a scene to this scene, returns true on success, false otherwise.
		See: UILoadAndStoreGroup
	#*/
	sq_register(vm, UIFromNML, "UILoad", _SC(".xs"));
	/*#
		Func: UILoadAndStoreGroup
		Proto: UIGroup:UI scene_to_import_to,string path,ImportFlag import_flag
		Desc: Append a scene to this scene, store all appended content in a group.

		Example:
class LevelScene
{
	diablo_ai		=	0
	diablo_fist		=	0

	function OnSetup(scene)
	{
		// Import the Diablo AI character into this scene.
		diablo_ai = SceneLoadAndStoreGroup(scene, "enemy/ai/diablo.nms")
	}
}
	#*/
	sq_register(vm, UIFromNMLStoreGroup, "UILoadAndStoreGroup", _SC(".xsi"));

/*#
	Section: UIManagement
	Desc: UI Management
#*/
	/*#
		Func: UIRenderSetup
		Proto: void:UI,ResourceFactory
		Desc: Setup UI render resources.
	#*/
	sq_register(vm, UIRenderSetup, "UIRenderSetup", _SC(".xx"));
	/*#
		Func: UISetGlobalMatrix
		Proto: void:UI,Matrix3
		Desc: Set the UI global transformation matrix.
	#*/
	sq_register(vm, UISetGlobalMatrix, "UISetGlobalMatrix", _SC(".xx"));
	sq_register(vm, UISetGlobalMatrix, "UISetOffsetMatrix", _SC(".xx"));
	/*#
		Func: UIGetScriptInstance
		Proto: Instance:UI
		Desc: Return the UI script instance.
	#*/
	sq_register(vm, UIGetScriptInstance, "UIGetScriptInstance", _SC(".x"));
	/*#
		Func: SceneGetUI
		Proto: UI:Scene
		Desc: Return the scene UI interface.
	#*/
	sq_register(vm, SceneGetUI, "SceneGetUI", _SC(".x"));
	/*#
		Func: UISetVirtualResolution
		Proto: void:UI,int width,int height
		Desc: Set the UI system virtual resolution in pixels.
	#*/
	sq_register(vm, UISetVirtualResolution, "UISetInternalResolution", _SC(".xnn"));	// compat
	sq_register(vm, UISetVirtualResolution, "UISetVirtualResolution", _SC(".xnn"));
	/*#
		Func: UIGetVirtualResolution
		Proto: Vector2:UI
		Desc: Get the UI system virtual resolution in pixels.
	#*/
	sq_register(vm, UIGetVirtualResolution, "UIGetInternalResolution", _SC(".x"));	// compat
	sq_register(vm, UIGetVirtualResolution, "UIGetVirtualResolution", _SC(".x"));

	/*#
		Func: UIGetScreenToUIMatrix
		Proto: Matrix3:UI
		Desc: Return the UI to normalized screen coordinates transformation matrix.<br>
			  This matrix can be used to transform a normalized screen coordinate to a scene coordinate expressed in pixels.
		See: UIGetVirtualResolution
		Example: 
// With a virtual resolution of 1920x1080 pixels.
local scene_coord = Vector2(0.5, 1) * UIGetScreenToUIMatrix(ui)

// scene_coord now contains Vector2(960.0, 1080.0)
	#*/
	sq_register(vm, UIGetScreenToUIMatrix, "UIGetScreenToUIMatrix", _SC(".x"));
	/*#
		Func: UIGetUIToScreenMatrix
		Proto: Matrix3:UI
		Desc: Return the normalized screen to UI coordinates transformation matrix.<br>
			  This matrix can be used to transform a scene coordinate expressed in pixels to a normalized screen coordinate between 0 and 1.
		See: UIGetVirtualResolution
		Example:
// With a virtual resolution of 1920x1080 pixels.
local norm_screen = Vector2(1920, 1080) * UIGetUIToScreenMatrix(ui)

// norm_screen now contains Vector2(1.0, 1.0)
	#*/
	sq_register(vm, UIGetUIToScreenMatrix, "UIGetUIToScreenMatrix", _SC(".x"));

/*#
	Section: UISkin
	Desc: UI Skin and Appearance
#*/
	/*#
		Func: UISetSkin
		Proto: void:UI,GraphicResourceFactory,string bmp_top,string bmp_left,string bmp_right,string bmp_bottom,string bmp_top_left,string bmp_top_right,string bmp_bottom_left,string bmp_bottom_right,int hex_font_color,int hex_title_color,int space_title_top,int space_title_bottom,int title_font_size,string title_font
		Desc: Set the UI window system skin.
	#*/
	sq_register(vm, UISetSkin, "UISetSkin", _SC(".xxssssssssnnnnns"));

/*#
	Section: UIIO
	Desc: UI Cursor
#*/
	/*#
		Func: UICreateCursor
		Proto: UICursor:int cursor_id
		Desc: Create a new UI system cursor.
	#*/
	sq_register(vm, UICreateCursor, "UICreateCursor", _SC(".i"));
	/*#
		Func: UISetCursorState
		Proto: void:UI,UICursor,float x,float y,bool down
		Desc: Set the current cursor state, the UI system will process cursor events and perform calls to the corresponding handlers. <b>Note:</b> This call will trigger cursor related events immediately.
	#*/
	sq_register(vm, UISetCursorState, "UISetCursorState", _SC(".xxnnb"));
	/*#
		Func: UICursorGetWindowBelow
		Proto: Window:UICursor cursor
		Desc: Return the window under the cursor, returns null is there is no such window.
	#*/
	sq_register(vm, UICursorGetWindowBelow, "UICursorGetWindowBelow", _SC(".x"));
	/*#
		Func: UICursorGetSpriteBelow
		Proto: Sprite:UICursor cursor
		Desc: Return the sprite under the cursor, returns null is there is no such sprite.
	#*/
	sq_register(vm, UICursorGetSpriteBelow, "UICursorGetSpriteBelow", _SC(".x"));
	/*#
		Func: UILock
		Proto: void:UI,Sprite|Window
		Desc: Lock UI to a given sprite/window. All UI cursor events are sent to this sprite/window exclusively until the lock is released.
	#*/
	sq_register(vm, UILockToSprite, "UILock", _SC(".xx"));
	sq_register(vm, UILockToSprite, "UILockToSprite", _SC(".xx"));
	/*#
		Func: UIUnlock
		Proto: void:UI
		Desc: Release the UI sprite/window lock.
	#*/
	sq_register(vm, UIUnlock, "UIUnlock", _SC(".x"));

/*#
	Section: UIGlobal
	Desc: UI Global Effects
#*/
	/*#
		Func: UISetCommandList
		Proto: void:UI,string command_list
		Desc: Set the UI system ACE command list.
	#*/
	sq_register(vm, UISetCommandList, "UISetCommandList", _SC(".xs"));
	/*#
		Func: UIIsCommandListDone
		Proto: bool:UI
		Desc: Returns true if the UI system command list unit is not executing, false otherwise.
	#*/
	sq_register(vm, UIIsCommandListDone, "UIIsCommandListDone", _SC(".x"));
	/*#
		Func: UISetGlobalFadeEffect
		Proto: void:UI,float fade
		Desc: Set the global fade effect intensity (0.0 is fully faded, 1.0 is no effect).
	#*/
	sq_register(vm, UISetGlobalFadeEffect, "UISetGlobalFadeEffect", _SC(".xn"));
	/*#
		Func: UISetGlobalFadeColor
		Proto: void:UI,float r,float g,float b
		Desc: Set the global fade effect color.
	#*/
	sq_register(vm, UISetGlobalFadeColor, "UISetGlobalFadeColor", _SC(".xnnn"));
	/*#
		Func: UIDeleteAllItems
		Proto: void:UI
		Desc: Delete all window and sprite in scene.
	#*/
	sq_register(vm, UIDeleteAllItems, "UIDeleteAllItems", _SC(".x"));

/*#
	Section: UIItem
	Desc: UI Item
#*/
	/*#
		Func: UIItemCastToSprite
		Proto: Sprite:UIItem item
		Desc: Cast an UI item to a UI sprite.
	#*/
	sq_register(vm, UIItemCastToSprite, "UIItemCastToSprite", _SC(".x"));
	/*#
		Func: UIItemCastToWindow
		Proto: Window:UIItem item
		Desc: Cast an UI item to a UI window.
	#*/
	sq_register(vm, UIItemCastToWindow, "UIItemCastToWindow", _SC(".x"));

/*#
	Section: UISprite
	Desc: UI Sprite
#*/
	/*#
		Func: UIAddSprite
		Proto: Window:UI,int id,Texture,float origin_x,float origin_y,float width,float height
		Desc: Create a new sprite. Note: This a legacy wrapper where the id integer is converted to a string and used as the sprite name.
	#*/
	sq_register(vm, UIAddSprite, "UIAddSprite", _SC(".xixnnnn"));
	/*#
		Func: UIAddNamedSprite
		Proto: Window:UI,string name,Texture,float origin_x,float origin_y,float width,float height
		Desc: Create a new sprite.
	#*/
	sq_register(vm, UIAddNamedSprite, "UIAddNamedSprite", _SC(".xsxnnnn"));
	/*#
		Func: UIDeleteSprite
		Proto: void:UI,Sprite
		Desc: Delete a sprite.
	#*/
	sq_register(vm, UIDeleteWindow, "UIDeleteSprite", _SC(".xx"));

	/*#
		Func: SpriteGetZOrder
		Proto: float:Sprite
		Desc: Get the sprite Z-order.
	#*/
	sq_register(vm, WindowGetZOrder, "SpriteGetZOrder", _SC(".x"));
	/*#
		Func: SpriteSetZOrder
		Proto: void:Sprite,float
		Desc: Set the sprite Z-order.
	#*/
	sq_register(vm, WindowSetZOrder, "SpriteSetZOrder", _SC(".xn"));
	/*#
		Func: SpriteSetUVOrigin
		Proto: void:Sprite,float u,float v
		Desc: Set the sprite UV origin in pixels.
	#*/
	sq_register(vm, SpriteSetUVOrigin, "SpriteSetUVOrigin", _SC(".xnn"));
	/*#
		Func: SpriteSetTexture
		Proto: void:Window,Texture
		Desc: Set the sprite texture.
	#*/
	sq_register(vm, SpriteSetTexture, "SpriteSetTexture", _SC(".xx"));
	/*#
	Func: WebcamTextureBlit
	Proto: void:Texture, pointer with a int
	Desc: blit the webcam texture to the texture.
	#*/
	sq_register(vm, WebcamTextureBlit, "WebcamTextureBlit", _SC(".xi"));
	/*#
		Func: SpriteSetTextureMatrix
		Proto: void:Window,Matrix3
		Desc: Set the sprite texture matrix. Note: Do not forget to enable the transform UV style on the sprite for the matrix to be used.
	#*/
	sq_register(vm, SpriteSetTextureMatrix, "SpriteSetTextureMatrix", _SC(".xx"));
	/*#
		Func: SpriteRenderSetup
		Proto: void:Sprite,ResourceFactory
		Desc: Setup the sprite render data.
	#*/
	sq_register(vm, SpriteRenderSetup, "SpriteRenderSetup", _SC(".xx"));

	/*#
		Func: SpriteGetRect
		Proto: Rect:Sprite
		Desc: Return the sprite rect.
	#*/
	sq_register(vm, WindowGetRect, "SpriteGetRect", _SC(".x"));
	/*#
		Func: SpriteGetScreenRect
		Proto: Rect:Sprite
		Desc: Return the sprite rect in the virtual screen coordinate system.
	#*/
	sq_register(vm, WindowGetScreenRect, "SpriteGetScreenRect", _SC(".x"));

	/*#
		Func: SpriteSetCommandList
		Proto: void:Sprite,string command_list
		Desc: Set the sprite command list.
	#*/
	sq_register(vm, WindowSetCommandList, "SpriteSetCommandList", _SC(".xs"));
	/*#
		Func: SpriteResetCommandList
		Proto: void:Sprite
		Desc: Reset the sprite ACE unit.
	#*/
	sq_register(vm, WindowResetCommandList, "SpriteResetCommandList", _SC(".x"));
	/*#
		Func: SpriteIsCommandListDone
		Proto: bool:Sprite
		Desc: Returns true if the sprite ACE unit is idle, false otherwise.
	#*/
	sq_register(vm, WindowIsCommandListDone, "SpriteIsCommandListDone", _SC(".x"));

	/*#
		Func: SpriteGetName
		Proto: string:Sprite
		Desc: Get the sprite name.
	#*/
	sq_register(vm, WindowGetName, "SpriteGetName", _SC(".x"));

	/*#
		Func: SpriteGetParent
		Proto: Window|Sprite:Sprite
		Desc: Get the sprite parent.
	#*/
	sq_register(vm, WindowGetParent, "SpriteGetParent", _SC(".x"));
	/*#
		Func: SpriteSetParent
		Proto: void:Sprite,Window|Sprite
		Desc: Set the sprite parent window or sprite.
	#*/
	sq_register(vm, WindowSetParent, "SpriteSetParent", _SC(".xx"));

	/*#
		Func: SpriteGetPosition
		Proto: Vector2:Sprite
		Desc: Get the sprite position as a vector.
	#*/
	sq_register(vm, WindowGetPosition, "SpriteGetPosition", _SC(".x"));
	/*#
		Func: SpriteSetPosition
		Proto: void:Sprite,float x,float y
		Desc: Set the sprite position.
	#*/
	sq_register(vm, WindowSetPosition, "SpriteSetPosition", _SC(".xnn"));
	/*#
		Func: SpriteSetRotation
		Proto: void:Sprite,float angle
		Desc: Set the sprite rotation (use the Deg() or Rad() macros to specify the unit).
	#*/
	sq_register(vm, WindowSetRotation, "SpriteSetRotation", _SC(".xn"));
	/*#
		Func: SpriteGetSize
		Proto: Vector2:Sprite
		Desc: Get the sprite size as a vector.
	#*/
	sq_register(vm, WindowGetSize, "SpriteGetSize", _SC(".x"));
	/*#
		Func: SpriteSetSize
		Proto: void:sprite,float width,float height
		Desc: Set the sprite size.
	#*/
	sq_register(vm, WindowSetSize, "SpriteSetSize", _SC(".xnn"));
	/*#
		Func: SpriteGetPivot
		Proto: Vector2:Sprite
		Desc: Get the sprite pivot.
	#*/
	sq_register(vm, WindowGetPivot, "SpriteGetPivot", _SC(".x"));
	/*#
		Func: SpriteSetPivot
		Proto: void:Sprite,float pivot_x,float pivot_y
		Desc: Set the sprite pivot.
	#*/
	sq_register(vm, WindowSetPivot, "SpriteSetPivot", _SC(".xnn"));
	/*#
		Func: SpriteSetScale
		Proto: void:Sprite,float scale_x,float scale_y
		Desc: Set the sprite scale.
	#*/
	sq_register(vm, WindowSetScale, "SpriteSetScale", _SC(".xnn"));
	/*#
		Func: SpriteGetOpacity
		Proto: float:sprite
		Desc: Get the sprite opacity.
	#*/
	sq_register(vm, WindowGetOpacity, "SpriteGetOpacity", _SC(".x"));
	/*#
		Func: SpriteSetOpacity
		Proto: void:Sprite,float opacity
		Desc: Set the sprite opacity.
	#*/
	sq_register(vm, WindowSetOpacity, "SpriteSetOpacity", _SC(".xn"));
	/*#
		Func: SpriteSetFlip
		Proto: void:Sprite,bool flip_horizontal,bool flip_vertical
		Desc: Flip the sprite on one or both axises.
	#*/
	sq_register(vm, WindowSetFlip, "SpriteSetFlip", _SC(".xbb"));
	/*#
		Func: SpriteGetStyle
		Proto: SpriteStyle:Sprite
		Desc: Get the sprite style bitflag.
	#*/
	sq_register(vm, WindowGetStyle, "SpriteGetStyle", _SC(".x"));
	/*#
		Func: SpriteSetStyle
		Proto: void:Sprite,SpriteStyle style
		Desc: Set the sprite style bitflag.
	#*/
	sq_register(vm, WindowSetStyle, "SpriteSetStyle", _SC(".xi"));
	/*#
		Func: SpriteAddStyle
		Proto: void:Sprite,SpriteStyle style
		Desc: Add a style to the sprite style bitflag.
	#*/
	sq_register(vm, WindowAddStyle, "SpriteAddStyle", _SC(".xi"));
	/*#
		Func: SpriteRemoveStyle
		Proto: void:Sprite,SpriteStyle style
		Desc: Remove a style from the sprite style bitflag.
	#*/
	sq_register(vm, WindowRemoveStyle, "SpriteRemoveStyle", _SC(".xi"));

	/*#
		Func: UISpriteCentre
		Proto: void:UI,Sprite
		Desc: Centre a sprite on screen.
	#*/
	sq_register(vm, UIWindowCentre, "UISpriteCentre", _SC(".x"));

	/*#
		Func: SpriteSetEventHandler
		Proto: void:Sprite,UIEvent event,function callback
		Desc: Set a native Squirrel function as the callback function to a specific UI event.
	#*/
	sq_register(vm, WindowSetEventHandler, "SpriteSetEventHandler", _SC(".xnc"));
	/*#
		Func: SpriteSetEventHandlerWithContext
		Proto: void:Sprite,UIEvent event,instance context,function callback
		Desc: Set a native Squirrel function as the callback function to a specific UI event, the calling context can be specified (eg. a class instance to callback to one of its member function).
	#*/
	sq_register(vm, WindowSetEventHandlerWithContext, "SpriteSetEventHandlerWithContext", _SC(".xn.c"));

/*#
	Section: UIWindow
	Desc: UI Window
#*/
	/*#
		Func: UIAddNamedWindow
		Proto: Window:UI,string name,float origin_x,float origin_y,float width,float height
		Desc: Create a new named window.
	#*/
	sq_register(vm, UIAddNamedWindow, "UIAddNamedWindow", _SC(".xsnnnn"));
	/*#
		Func: UIAddNamedBitmapWindow
		Proto: Window:UI,String name,Picture,float origin_x,float origin_y,float width,float height
		Desc: Create a new named bitmap window.
	#*/
	sq_register(vm, UIAddNamedBitmapWindow, "UIAddNamedBitmapWindow", _SC(".xsxnnnn"));
	/*#
		Func: UIDeleteWindow
		Proto: void:UI,Window
		Desc: Delete a window.
	#*/
	sq_register(vm, UIDeleteWindow, "UIDeleteWindow", _SC(".xx"));

	/*#
		Func: WindowGetZOrder
		Proto: float:Window
		Desc: Get the window Z-order.
	#*/
	sq_register(vm, WindowGetZOrder, "WindowGetZOrder", _SC(".x"));
	/*#
		Func: WindowSetZOrder
		Proto: void:Window,float
		Desc: Set the window Z-order.
	#*/
	sq_register(vm, WindowSetZOrder, "WindowSetZOrder", _SC(".xn"));
	/*#
		Func: WindowSetTitle
		Proto: void:window,string title
		Desc: Set the window title.
	#*/
	sq_register(vm, WindowSetTitle, "WindowSetTitle", _SC(".xs"));
	/*#
		Func: WindowGetTitle
		Proto: string:window
		Desc: Get the window title.
	#*/
	sq_register(vm, WindowGetTitle, "WindowGetTitle", _SC(".x"));
	/*#
		Func: WindowSetBaseWidget
		Proto: void:window,widget
		Desc: Set the window base widget.
	#*/
	sq_register(vm, WindowSetBaseWidget, "WindowSetBaseWidget", _SC(".xx"));

	/*#
		Func: WindowGetRect
		Proto: Rect:Window
		Desc: Return the window rect.
	#*/
	sq_register(vm, WindowGetRect, "WindowGetRect", _SC(".x"));
	/*#
		Func: WindowGetScreenRect
		Proto: Rect:Window
		Desc: Return the window rect in the virtual screen coordinate system.
	#*/
	sq_register(vm, WindowGetScreenRect, "WindowGetScreenRect", _SC(".x"));

	/*#
		Func: WindowSetCommandList
		Proto: void:window,string command_list
		Desc: Set the window command list.
	#*/
	sq_register(vm, WindowSetCommandList, "WindowSetCommandList", _SC(".xs"));
	/*#
		Func: WindowResetCommandList
		Proto: void:window
		Desc: Reset the window ACE unit.
	#*/
	sq_register(vm, WindowResetCommandList, "WindowResetCommandList", _SC(".x"));
	/*#
		Func: WindowIsCommandListDone
		Proto: bool:window
		Desc: Returns true if the window ACE unit is idle, false otherwise.
	#*/
	sq_register(vm, WindowIsCommandListDone, "WindowIsCommandListDone", _SC(".x"));

	/*#
		Func: WindowGetName
		Proto: string:window
		Desc: Get the window name.
	#*/
	sq_register(vm, WindowGetName, "WindowGetName", _SC(".x"));

	/*#
		Func: WindowGetChild
		Proto: widget:window,int id
		Desc: Get a window widget from its id.
	#*/
	sq_register(vm, WindowGetChild, "WindowGetChild", _SC(".xn"));
	/*#
		Func: WindowGetParent
		Proto: Window|Sprite:Window
		Desc: Get the window parent.
	#*/
	sq_register(vm, WindowGetParent, "WindowGetParent", _SC(".x"));
	/*#
		Func: WindowSetParent
		Proto: void:Window,Window|Sprite
		Desc: Set the window parent window or sprite.
	#*/
	sq_register(vm, WindowSetParent, "WindowSetParent", _SC(".xx"));

	/*#
		Func: WindowGetPosition
		Proto: Vector2:Window
		Desc: Get the window position as a vector.
	#*/
	sq_register(vm, WindowGetPosition, "WindowGetPosition", _SC(".x"));
	/*#
		Func: WindowSetPosition
		Proto: void:Window,float x,float y
		Desc: Set the window position.
	#*/
	sq_register(vm, WindowSetPosition, "WindowSetPosition", _SC(".xnn"));
	/*#
		Func: WindowSetRotation
		Proto: void:Window,float angle
		Desc: Set the window rotation (use the Deg() or Rad() macros to specify the unit).
	#*/
	sq_register(vm, WindowSetRotation, "WindowSetRotation", _SC(".xn"));
	/*#
		Func: WindowGetSize
		Proto: Vector2:Window
		Desc: Get the window size as a vector.
	#*/
	sq_register(vm, WindowGetSize, "WindowGetSize", _SC(".x"));
	/*#
		Func: WindowSetSize
		Proto: void:Window,float width,float height
		Desc: Set the window size.
	#*/
	sq_register(vm, WindowSetSize, "WindowSetSize", _SC(".xnn"));
	/*#
		Func: WindowGetPivot
		Proto: Vector2:Window
		Desc: Get the window pivot.
	#*/
	sq_register(vm, WindowGetPivot, "WindowGetPivot", _SC(".x"));
	/*#
		Func: WindowSetPivot
		Proto: void:Window,float pivot_x,float pivot_y
		Desc: Set the window pivot.
	#*/
	sq_register(vm, WindowSetPivot, "WindowSetPivot", _SC(".xnn"));
	/*#
		Func: WindowSetScale
		Proto: void:Window,float scale_x,float scale_y
		Desc: Set the window scale.
	#*/
	sq_register(vm, WindowSetScale, "WindowSetScale", _SC(".xnn"));
	/*#
		Func: WindowGetOpacity
		Proto: float:Window
		Desc: Get the window opacity.
	#*/
	sq_register(vm, WindowGetOpacity, "WindowGetOpacity", _SC(".x"));
	/*#
		Func: WindowSetOpacity
		Proto: void:Window,float opacity
		Desc: Set the window opacity.
	#*/
	sq_register(vm, WindowSetOpacity, "WindowSetOpacity", _SC(".xn"));
	/*#
		Func: WindowSetFlip
		Proto: void:Window,bool flip_horizontal,bool flip_vertical
		Desc: Flip the window on one or both axises.
	#*/
	sq_register(vm, WindowSetFlip, "WindowSetFlip", _SC(".xbb"));
	/*#
		Func: WindowGetStyle
		Proto: SpriteStyle:Window
		Desc: Get the window style bitflag.
	#*/
	sq_register(vm, WindowGetStyle, "WindowGetStyle", _SC(".x"));
	/*#
		Func: WindowSetStyle
		Proto: void:Window,SpriteStyle style
		Desc: Set the window style bitflag.
	#*/
	sq_register(vm, WindowSetStyle, "WindowSetStyle", _SC(".xn"));
	/*#
		Func: WindowAddStyle
		Proto: void:Window,SpriteStyle style
		Desc: Add a style to the window style bitflag.
	#*/
	sq_register(vm, WindowAddStyle, "WindowAddStyle", _SC(".xn"));
	/*#
		Func: WindowRemoveStyle
		Proto: void:Window,SpriteStyle style
		Desc: Remove a style from the window style bitflag.
	#*/
	sq_register(vm, WindowRemoveStyle, "WindowRemoveStyle", _SC(".xn"));

	/*#
		Func: WindowGetBackgroundPicture
		Proto: Picture:Window
		Desc: Get the window background picture.
	#*/
	sq_register(vm, WindowGetBackgroundPicture, "WindowGetBackgroundPicture", _SC(".x"));
	/*#
		Func: WindowSetBackgroundPicture
		Proto: void:Window,Picture
		Desc: Set the window background picture.
	#*/
	sq_register(vm, WindowSetBackgroundPicture, "WindowSetBackgroundPicture", _SC(".xx"));
	/*#
		Func: WindowSetBackgroundColor
		Proto: void:Window,int hex_color
		Desc: Set the window background color.
	#*/
	sq_register(vm, WindowSetBackgroundColor, "WindowSetBackgroundColor", _SC(".xn"));

	/*#
		Func: UIWindowCentre
		Proto: void:UI,Window
		Desc: Centre the window on screen.
	#*/
	sq_register(vm, UIWindowCentre, "UIWindowCentre", _SC(".xx"));

	/*#
		Func: WindowForceLayout
		Proto: void:Window
		Desc: Force a complete update of the window layout.
	#*/
	sq_register(vm, WindowForceLayout, "WindowForceLayout", _SC(".x"));
	/*#
		Func: WindowInvalidate
		Proto: void:Window
		Desc: Force a complete update of the window layout and content.
	#*/
	sq_register(vm, WindowInvalidate, "WindowInvalidate", _SC(".x"));
	/*#
		Func: WindowGetCacheTexture
		Proto: texture:Window
		Desc: Returns the texture object that is used to display the window via the engine renderer.
	#*/
	sq_register(vm, WindowGetCacheTexture, "WindowGetCacheTexture", _SC(".x"));

	/*#
		Func: WindowSetEventHandler
		Proto: void:Window,UIEvent event,function callback
		Desc: Set a native Squirrel function as the callback function to a specific UI event.
	#*/
	sq_register(vm, WindowSetEventHandler, "WindowSetEventHandler", _SC(".xnc"));
	/*#
		Func: WindowSetEventHandlerWithContext
		Proto: void:Window,UIEvent event,instance context,function callback
		Desc: Set a native Squirrel function as the callback function to a specific UI event, the calling context can be specified (eg. a class instance to callback to one of its member function).
	#*/
	sq_register(vm, WindowSetEventHandlerWithContext, "WindowSetEventHandlerWithContext", _SC(".xn.c"));

	/*#
		Func: WindowRenderSetup
		Proto: void:Window,ResourceFactory
		Desc: Setup the window render data.
	#*/
	sq_register(vm, SpriteRenderSetup, "WindowRenderSetup", _SC(".xx"));

/*#
	Section: UIWidget
	Desc: UI Widget
#*/
	/*#
		Func: UIDeleteWidget
		Proto: void:UI,Widget
		Desc: Delete a widget.
	#*/
	sq_register(vm, UIDeleteWidget, "UIDeleteWidget", _SC(".xx"));
	/*#
		Func: UIAddCanvasWidget
		Proto: Widget:UI,int id,int width,int height
		Desc: Create a new canvas widget.
	#*/
	sq_register(vm, UIAddCanvasWidget, "UIAddCanvasWidget", _SC(".xnnn"));
	/*#
		Func: UIAddHorizontalSizerWidget
		Proto: Widget:UI,int id
		Desc: Create a new horizontal sizer widget.
	#*/
	sq_register(vm, UIAddHorizontalSizerWidget, "UIAddHorizontalSizerWidget", _SC(".xn"));
	/*#
		Func: UIAddVerticalSizerWidget
		Proto: Widget:UI,int id
		Desc: Create a new vertical sizer widget.
	#*/
	sq_register(vm, UIAddVerticalSizerWidget, "UIAddVerticalSizerWidget", _SC(".xn"));
	/*#
		Func: UIAddContainerWidget
		Proto: Widget:UI,int id
		Desc: Create a new container widget.
	#*/
	sq_register(vm, UIAddContainerWidget, "UIAddContainerWidget", _SC(".xn"));
	/*#
		Func: UIAddSpacerWidget
		Proto: Widget:UI,int id
		Desc: Create a new spacer widget.
	#*/
	sq_register(vm, UIAddSpacerWidget, "UIAddSpacerWidget", _SC(".xn"));
	/*#
		Func: UIAddBitmapWidget
		Proto: Widget:UI,int id
		Desc: Create a new bitmap widget.
	#*/
	sq_register(vm, UIAddBitmapWidget, "UIAddBitmapWidget", _SC(".xn"));
	/*#
		Func: UIAddTextWidget
		Proto: TextWidget:UI,int id,string text,Font font
		Desc: Create a new static text widget.
	#*/
	sq_register(vm, UIAddTextWidget, "UIAddTextWidget", _SC(".xnsx"));
	/*#
		Func: UIAddCheckWidget
		Proto: Widget:UI,int id,string text,string font,bool initial_state
		Desc: Create a new checkbox widget.
	#*/
	sq_register(vm, UIAddCheckWidget, "UIAddCheckWidget", _SC(".xnssb"));

/*#
	Section: CanvasWidget
	Desc: Widget Canvas, a freely drawable widget
#*/
	/*#
		Func: CanvasWidgetLock
		Proto: picture:canvas
		Desc: Lock the widget returning a user drawable picture object.
	#*/
	sq_register(vm, CanvasWidgetLock, "CanvasWidgetLock", _SC(".x"));
	/*#
		Func: CanvasWidgetUnlock
		Proto: void:canvas
		Desc: Unlock this widget canvas.<br><b>Note:</b> The picture object obtained through CanvasWidgetLock is not valid after calling this function.
	#*/
	sq_register(vm, CanvasWidgetUnlock, "CanvasWidgetUnlock", _SC(".x"));

/*#
	Section: SizerWidget
	Desc: Widget Sizer
#*/
	/*#
		Func: SizerSetDrawDelimiter
		Proto: void:sizer,bool draw
		Desc: Draw/hide sizer delimiter.
	#*/
	sq_register(vm, SizerSetDrawDelimiter, "SizerSetDrawDelimiter", _SC(".xb"));
	/*#
		Func: SizerSetBorderSize
		Proto: void:sizer,int left,int top,int right,int bottom
		Desc: Set sizer border size.
	#*/
	sq_register(vm, SizerSetBorderSize, "SizerSetBorderSize", _SC(".xnnnn"));
	/*#
		Func: SizerAddWidget
		Proto: void:sizer,widget
		Desc: Add a widget to a sizer.
	#*/
	sq_register(vm, SizerAddWidget, "SizerAddWidget", _SC(".xx"));

/*#
	Section: ContainerWidget
	Desc: Widget Container
#*/
	/*#
		Func: ContainerAddWidget
		Proto: void:container,widget,float origin_x,float origin_y,float width,float height
		Desc: Add a widget at specified position to the container.
	#*/
	sq_register(vm, ContainerAddWidget, "ContainerAddWidget", _SC(".xxnnnn"));
	/*#
		Func: ContainerWidgetSetPosition
		Proto: void:container,widget,float origin_x,float origin_y
		Desc: Set a widget position in its container.
	#*/
	sq_register(vm, ContainerWidgetSetPosition, "ContainerWidgetSetPosition", _SC(".xxnn"));

/*#
	Section: BitmapWidget
	Desc: Widget Bitmap
#*/
	/*#
		Func: BitmapSetPicture
		Proto: void:bitmap,string bitmap
		Desc: Set bitmap widget bitmap from resource.
	#*/
	sq_register(vm, BitmapSetPicture, "BitmapSetPicture", _SC(".xs"));

/*#
	Section: TextWidget
	Desc: Widget Text
#*/
	/*#
		Func: TextSetAlignment
		Proto: void:TextWidget,TextAlign align
		Desc: Set widget text alignment method.
	#*/
	sq_register(vm, TextSetAlignment, "TextSetAlignment", _SC(".xn"));
	/*#
		Func: TextSetFormat
		Proto: void:TextWidget,TextFormat format
		Desc: Set widget text formatting method.
	#*/
	sq_register(vm, TextSetFormat, "TextSetFormat", _SC(".xn"));
	/*#
		Func: TextSetSize
		Proto: void:TextWidget,int size
		Desc: Set widget text font size.
	#*/
	sq_register(vm, TextSetSize, "TextSetSize", _SC(".xn"));
	/*#
		Func: TextSetColor
		Proto: void:TextWidget,int r,int g,int b,int a
		Desc: Set widget text color.
	#*/
	sq_register(vm, TextSetColor, "TextSetColor", _SC(".xnnnn"));
	/*#
		Func: TextSetText
		Proto: void:TextWidget,string text
		Desc: Set widget text.
	#*/
	sq_register(vm, TextSetText, "TextSetText", _SC(".xs"));
	/*#
		Func: TextSetParameters
		Proto: void:TextWidget,table param
		Desc: Set widget text parameters.<br>
		The following table keys are available:<br>
		<ul>
		<li><b>'color'</b>: Hexadecimal RGBA (eg. Red: xff0000ff)
		<li><b>'align'</b>: TextAlign
		<li><b>'format'</b>: TextFormat
		<li><b>'tracking'</b>: Integer value specifying an extra space between glyphs.
		<li><b>'heading'</b>: Integer value specifying an extra space between lines.
		</ul>
	#*/
	sq_register(vm, TextSetParameters, "TextSetParameters", _SC(".xt"));

/*#
	Section: CheckWidget
	Desc: Widget Check
#*/
	/*#
		Func: CheckWidgetSetLabel
		Proto: void:check,string text
		Desc: Set check widget text label.
	#*/
	sq_register(vm, CheckWidgetSetLabel, "CheckWidgetSetLabel", _SC(".xs"));
	/*#
		Func: CheckWidgetSetLabelFont
		Proto: void:Check,Font font
		Desc: Set check widget text font.
	#*/
	sq_register(vm, CheckWidgetSetLabelFont, "CheckWidgetSetLabelFont", _SC(".xx"));
	/*#
		Func: CheckWidgetSetLabelSize
		Proto: void:check,int size
		Desc: Set check widget font size.
	#*/
	sq_register(vm, CheckWidgetSetLabelSize, "CheckWidgetSetLabelSize", _SC(".xn"));
	/*#
		Func: CheckWidgetSetState
		Proto: void:check,bool state
		Desc: Set check widget state.
	#*/
	sq_register(vm, CheckWidgetSetState, "CheckWidgetSetState", _SC(".xb"));
	/*#
		Func: CheckWidgetGetState
		Proto: bool:check
		Desc: Get check widget state.
	#*/
	sq_register(vm, CheckWidgetGetState, "CheckWidgetGetState", _SC(".x"));
	/*#
		Func: CheckWidgetGetText
		Proto: string:check
		Desc: Get check widget text label.
	#*/
	sq_register(vm, CheckWidgetGetText, "CheckWidgetGetText", _SC(".x"));

/*#
	Section: MiscWidget
	Desc: Widget
#*/
	/*#
		Func: WidgetToBitmap
		Proto: bitmap:widget
		Desc: Cast widget to bitmap widget.
	#*/
	sq_register(vm, WidgetToBitmap, "WidgetToBitmap", _SC(".x"));
	/*#
		Func: WidgetToText
		Proto: text:widget
		Desc: Cast widget to static text widget.
	#*/
	sq_register(vm, WidgetToText, "WidgetToText", _SC(".x"));
	/*#
		Func: WidgetToCheck
		Proto: check:widget
		Desc: Cast widget to check widget.
	#*/
	sq_register(vm, WidgetToCheck, "WidgetToCheck", _SC(".x"));

	/*#
		Func: WidgetSetEventHandler
		Proto: void:widget,UIEvent event,function callback
		Desc: Set a native Squirrel function as the widget event callback.
	#*/
	sq_register(vm, WidgetSetEventHandler, "WidgetSetEventHandler", _SC(".xnc"));
	/*#
		Func: WidgetSetEventHandlerWithContext
		Proto: void:widget,UIEvent event,instance context,function callback
		Desc: Set a native Squirrel function in a specific context (ie. a class) as a widget event callback.
	#*/
	sq_register(vm, WidgetSetEventHandlerWithContext, "WidgetSetEventHandlerWithContext", _SC(".xn.c"));
	/*#
		Func: WidgetSetSensitive
		Proto: void:widget,bool sensitive
		Desc: Enable/disable mouse/keyboard event on a widget.
	#*/
	sq_register(vm, WidgetSetSensitive, "WidgetSetSensitive", _SC(".xb"));
	/*#
		Func: WidgetGetRect
		Proto: rect:widget
		Desc: Return widget rect in window space.
	#*/
	sq_register(vm, WidgetGetRect, "WidgetGetRect", _SC(".x"));
	/*#
		Func: WidgetSetHAlign
		Proto: void:widget,WidgetAlign alignment
		Desc: Set widget horizontal alignment.
	#*/
	sq_register(vm, WidgetSetHAlign, "WidgetSetHAlign", _SC(".xn"));
	/*#
		Func: WidgetSetVAlign
		Proto: void:widget,WidgetAlign alignment
		Desc: Set widget vertical alignment.
	#*/
	sq_register(vm, WidgetSetVAlign, "WidgetSetVAlign", _SC(".xn"));
	/*#
		Func: WidgetSetHidden
		Proto: void:widget,bool hidden
		Desc: Show/hide widget.
	#*/
	sq_register(vm, WidgetSetHidden, "WidgetSetHidden", _SC(".xb"));
	/*#
		Func: WidgetIsHidden
		Proto: bool:widget
		Desc: Return true if the widget is hidden, false otherwise.
	#*/
	sq_register(vm, WidgetIsHidden, "WidgetIsHidden", _SC(".x"));
	/*#
		Func: WidgetSetFormattingSize
		Proto: void:widget,float ratio_x,float ratio_y
		Desc: Set widget formatting size ratio.
	#*/
	sq_register(vm, WidgetSetFormattingSize, "WidgetSetFormattingSize", _SC(".xnn"));
	/*#
		Func: CastToWidget
		Proto: Widget:WidgetDerived
		Desc: Cast any complex widget (such as containers, sizer, etc...) to its base widget.
	#*/
	sq_register(vm, CastToWidget, "CastToWidget", _SC(".x"));

	// Push defines.
	sq_pushroottable(vm);

	sq_pushstring(vm, "NullWindow", -1); CObject::Push(vm, NULL, typetag_Window); sq_newslot(vm, -3, true);

	/*#
		Enum: SpriteStyle
		Values: StyleBlendAdditive,StyleBlendOpaque,StyleNonSensitive,StyleResolutionInvariant,
		StyleNoDecoration,StyleTransformUV,StyleNoTitleBar,StyleMovable,StyleSnapToPixel
	#*/
	sq_pushstring(vm, "StyleBlendAdditive", -1); sq_pushinteger(vm, Sprite::FlagBlendAdditive); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleNonSensitive", -1); sq_pushinteger(vm, Sprite::FlagNonSensitive); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleResolutionInvariant", -1); sq_pushinteger(vm, Sprite::FlagResolutionInvariant); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleTransformUV", -1); sq_pushinteger(vm, Sprite::FlagTransformUV); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleSnapToPixel", -1); sq_pushinteger(vm, Sprite::FlagSnapToPixel); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleBlendOpaque", -1); sq_pushinteger(vm, Sprite::FlagBlendOpaque); sq_newslot(vm, -3, true);
#if	1
	sq_pushstring(vm, "StyleNoBlend", -1); sq_pushinteger(vm, Sprite::FlagBlendOpaque); sq_newslot(vm, -3, true);	// COMPAT
#endif

	/*#
		Enum: WindowStyle
		Values: StyleNoDecoration,StyleNoTitleBar
	#*/
	sq_pushstring(vm, "StyleNoDecoration", -1); sq_pushinteger(vm, Window::FlagNoDecoration); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "StyleNoTitleBar", -1); sq_pushinteger(vm, Window::FlagNoTitleBar); sq_newslot(vm, -3, true);

	/*#
		Enum: WidgetAlign
		Values: WidgetAlignDefault,WidgetAlignLeft,WidgetAlignTop,WidgetAlignMiddle,WidgetAlignRight,WidgetAlignBottom
	#*/
	sq_pushstring(vm, "WidgetAlignDefault", -1); sq_pushinteger(vm, Widget::AlignNone); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WidgetAlignLeft", -1); sq_pushinteger(vm, Widget::AlignLeft); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WidgetAlignTop", -1); sq_pushinteger(vm, Widget::AlignTop); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WidgetAlignMiddle", -1); sq_pushinteger(vm, Widget::AlignMiddle); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WidgetAlignRight", -1); sq_pushinteger(vm, Widget::AlignRight); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WidgetAlignBottom", -1); sq_pushinteger(vm, Widget::AlignBottom); sq_newslot(vm, -3, true);

	/*#
		Enum: TextAlign
		Desc: Text alignment.
		Values: TextAlignLeft,TextAlignRight,TextAlignCenter,TextAlignJustify
	#*/
	sq_pushstring(vm, "TextAlignLeft", -1); sq_pushinteger(vm, TextState::Left); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextAlignRight", -1); sq_pushinteger(vm, TextState::Right); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextAlignCenter", -1); sq_pushinteger(vm, TextState::Center); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextAlignJustify", -1); sq_pushinteger(vm, TextState::Justify); sq_newslot(vm, -3, true);

	/*#
		Enum: TextFormat
		Desc: Text formatting.
		Values: TextFormatStandard,TextFormatParagraph,TextFormatLine,TextFormatColumn
	#*/
	sq_pushstring(vm, "TextFormatStandard", -1); sq_pushinteger(vm, TextState::Line); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextFormatLine", -1); sq_pushinteger(vm, TextState::Line); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextFormatParagraph", -1); sq_pushinteger(vm, TextState::Paragraph); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "TextFormatColumn", -1); sq_pushinteger(vm, TextState::Column); sq_newslot(vm, -3, true);

	/*#
		Enum: UIEvent
		Values:	EventCursorDown,EventCursorHit,EventCursorUp,
		EventCursorEnter,EventCursorLeave,EventCursorMove
	#*/
	sq_pushstring(vm, "EventCursorDown", -1); sq_pushinteger(vm, Event_CursorDown); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "EventCursorHit", -1); sq_pushinteger(vm, Event_CursorHit); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "EventCursorUp", -1); sq_pushinteger(vm, Event_CursorUp); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "EventCursorEnter", -1); sq_pushinteger(vm, Event_CursorEnter); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "EventCursorLeave", -1); sq_pushinteger(vm, Event_CursorLeave); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "EventCursorMove", -1); sq_pushinteger(vm, Event_CursorMove); sq_newslot(vm, -3, true);

	sq_pop(vm, 1);
}
