-- STATE MANAGEMENT FUNCTIONS

-- Pushes an State and passes parameters to it simulating a Dialog
function DisplayStateDialog(dialogData)
	gStateOperation = 1;
	gDialogTable = dialogData;
	DebugOut(tostring(dialogData.name));
	gPush = true;
	gIsDialog = 1;
	dofile(dialogData[1]);
	DebugOut("Dialog: before loop");
	while true do
		local gMessage = WaitForMessage(1);
		if gMessage then
			if VerifyCloseState(gMessage) then
				break;
			end
		end
	end
	DebugOut("Dialog: exit loop");
	gDialogTable = nil;
	gIsDialog = 0;
	return dialogData;
end

-- Pushes a newly created state
function PushState(dialogData)
	if type(dialogData) == "table" then
		gDialogTable = dialogData;
		dialogData = gDialogTable[1];
	end
	gPush = true;
	dofile(dialogData);
	gDialogTable = nil;
end

-- Swapt to a newly created state
function SwapToState(dialogData)
	if type(dialogData) == "table" then
		gDialogTable = dialogData;
		dialogData = gDialogTable[1];
	end
	gPush = false;
	dofile(dialogData);
	gDialogTable = nil;
end

-- DYNAMIC CREATION FUNCTIONS

-- Allows fixing the table if needed by specific types before creation
-- To allow fixing behavior for a type create a function named Creating<type>
-- where <type> must be replaced by the DisplayObject type needing fixes
function BlgCreating(t)
	if _G["Creating"..tostring(t.typename)] then
		_G["Creating"..tostring(t.typename)](t);
	end
end

-- Performs the dynamic creation of the state mainly in Lua
-- First it creates the State itself and later the DisplayObject hierarchy
function MakeState(t)
	local currStyle = gCurrentDefaultStyle;

	CreateState(t);
	MakeDisplayHierarchy(t);

	SetDefaultStyle(currStyle);
	PostStateCreate(t);

	InsertState(gPush);
end

-- Performs the DisplayObject hierarchy creation
-- it creates the children for the current DisplayObject on the Stack (defaults to Stage)
-- this function will be later called recursively by every child
function MakeDisplayHierarchy(t, doPost)
	local currStyle = gCurrentDefaultStyle;
	SetDefaultStyle(nil);

	for i,v in ipairs(t) do
		v();
	end

	SetDefaultStyle(currStyle);

	if doPost == nil or doPost == true then
		PostChildrenCreate(t);
	end
end

-- This function is the responsible for the DisplayObject creation
-- and the one to recursively create children also
-- After creation it pops the last DisplayObjectContainer from a temporary Stack
-- used to keep track of the current parent to add children correctly

-- If something special must happen after creation create a Make<type> function
-- where <type> must be replaced by the DisplayObject type needing special treatment
function DoDisplayObject(t)
	GenericDisplayObjectCreate(t);
	if _G["Make"..tostring(t.typename)] then
		_G["Make"..tostring(t.typename)](t);
	else
		MakeDisplayHierarchy(t);
	end
	PopDisplayObject();
end

function Animate(t)
	return function()
		AddMovieClipAnimation(t);
	end
end



-- BUTTON CREATION FUNCTIONS

-- Manages special table fixing before cretion for Button
function CreatingBlgButton(t)
	if t.overState == nil then
		t.overState = t.upState;
	end

	if t.downState == nil then
		t.downState = t.overState;
	end

	if t.disabledState == nil then
		t.disabledState = t.upState;
	end

	t.dynamiclist = {};

	PrepareButtonState(t, "upState");
	PrepareButtonState(t, "overState");
	PrepareButtonState(t, "downState");
end

-- Prepares a single button state
function PrepareButtonState(t, key)
	if type(t[key]) == "table" then
		local count = 0;

		for i, v in ipairs(t[key]) do
			if type(v) == "function" then
				table.insert(t, v);
				count = count + 1;
			end
		end

		if count > 0 then
			t[key] = { push = true, count = count };
			table.insert(t.dynamiclist, t[key]);
		end
	end
end

-- Manages special behavior after creation for Button
function MakeBlgButton(t)
	for i, v in ipairs(t.dynamiclist) do
		local funcCount = v.count;
		local count = 0;

		for i = 1, funcCount do
			count = count + 1;
			t[i]();
		end

		PopDisplayObject();
	end
end

CreatingBlgCheckBox = CreatingBlgButton;
MakeBlgCheckox = MakeBlgButton;

function BlgBreakFlow()
	return function()
		InsertBreakFlow();
	end
end

function BlgSetNextCell(x, y)
	return function()
		SetNextLayoutCell(x, y);
	end
end