﻿Array.prototype.remove = function(from, to)
{
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

var eventCommands = [];

var UIManager = new Class(
{
	initialize: function()
	{
		this.lastState = null;

		this.resizeHandlers = [];
		this.cleanupHandlers = [];
		this.controlRemovalHandlerList = [];
		this.controlRemovalHandlers = {};

		this.viewStateHandlerList = [];
		this.viewStateHandlers = {};

		this.commandHandlerList = [];
		this.commandHandlers = {};

		this.initCommands = [];

		this.attachedDialogState = '';
		this.targetDialog = '';

		this.onSetDialog = function() { };
		this.onReceiveModalPopup = function() { };

		this.onBeforeRequest = function() { };
		this.onAfterRequest = function() { };
	},

	registerResizeHandler: function(handler)
	{
		this.resizeHandlers.push(handler);
	},

	registerCleanupHandler: function(handler)
	{
		this.cleanupHandlers.push(handler);
	},

	registerControlRemovalHandler: function(typeID, handler)
	{
		this.controlRemovalHandlerList.push(typeID);
		this.controlRemovalHandlers[typeID] = handler;
	},

	registerViewStateHandler: function(typeID, handler)
	{
		this.viewStateHandlerList.push(typeID);
		this.viewStateHandlers[typeID] = handler;
	},

	registerCommandHandler: function(action, handler)
	{
		this.commandHandlerList.push(action);
		this.commandHandlers[action] = handler;
	},

	getNestedControl: function(control, controlID)
	{
		//return $(control).getElement("[id='" + controlID + "']");
		return $(control).getElementById(controlID);
	},

	getDialogParameters: function(dialog)
	{
		var dlgParameters = $(dialog.id + "_parameters");

		if (dlgParameters != null)
		{
			return dlgParameters.value;
		}

		return base64Json.encode("{\"__type\":\"de\"}");
	},

	collectDialogState: function(dialog)
	{
		if (dialog == null)
		{
			return {};
		}

		return {
			"DialogID": dialog.id,
			"DialogState": ui.collectViewState(dialog, true),
			"DialogParameters": base64Json.decode(ui.getDialogParameters(dialog))
		}
	},

	getMetaElements: function(dialog)
	{
		var dialogElements = $(dialog.id + "_elements");
		var metaElements = [];

		if (dialogElements != null && dialogElements.value != "")
		{
			var elements = dialogElements.value.split(",");

			for (var i = 0; i < elements.length; i++)
			{
				var dialogElement = elements[i].split(":");

				var metaElement =
				{
					ID: dialogElement[0],
					TypeID: dialogElement[1],
					Control: null
				};

				metaElement.Control = ui.getNestedControl(dialog, metaElement.ID);

				metaElements.push(metaElement);
			}
		}

		return metaElements;
	},

	collectViewState: function(dialog, collectSubStates)
	{
		var controlStates = {};

		controlStates["__type"] = "cs";

		if (dialog == null)
		{
			return controlStates;
		}

		var metaElements = ui.getMetaElements(dialog);

		for (var i = 0; i < metaElements.length; i++)
		{
			var metaElement = metaElements[i];

			if (ui.viewStateHandlerList.contains(metaElement.TypeID))
			{
				if (metaElement.Control != null)
				{
					controlStates[metaElement.ID] = ui.viewStateHandlers[metaElement.TypeID](metaElement.Control);
				}
				else
				{
					if (metaElement.TypeID == "TagEl")
					{
						controlStates[metaElement.ID] = ui.viewStateHandlers[metaElement.TypeID](metaElement.ID);
					}
				}
			}
		}

		return controlStates;
	},

	attachDialogState: function(dialogID)
	{
		this.attachedDialogState = base64Json.encode(this.collectDialogState($(dialogID)));
	},

	overwriteDialogTarget: function(dialogID)
	{
		this.targetDialog = dialogID;
	},

	executeAction: function(dialogID, actionID, actionParams)
	{
		if (this.onBeforeRequest != null)
		{
			this.onBeforeRequest();
		}

		UIService.ExecuteAction(dialogID, actionID, actionParams, this.processCommands);
	},

	handleEvent: function(dialogID, sender, eventName)
	{
		//stateHistory.states[stateHistory.position] = site.buildState();

		if (this.targetDialog != '')
		{
			dialogID = this.targetDialog;
			this.targetDialog = '';
		}

		var dialog = $(dialogID);

		if (dialog == null)
		{
			alert("Could not find dialog '" + dialogID + "'");
			return;
		}

		var viewState = base64Json.encode(this.collectViewState(dialog, false));
		var parameters = $(dialogID + "_parameters").value;

		if (this.onBeforeRequest != null)
		{
			this.onBeforeRequest();
		}

		ui.lastState = viewState;

		UIService.HandleEvent(dialogID, parameters, viewState, sender.id, eventName, this.attachedDialogState, this.processCommands);
		this.attachedDialogState = '';
	},

	load: function()
	{
		try
		{
			this.processCommands(this.initCommands);
		}
		catch (e)
		{

		}

		window.onresize = function()
		{
			ui.onResize();
		}

		ui.onResize();
	},

	executeHandlers: function(handlers, args)
	{
		for (var i = 0; i < handlers.length; i++)
		{
			var handler = handlers[i];

			if (handler != null)
			{
				try
				{
					handler(args);
				}
				catch (e)
				{
					document.title = e;
				}
			}
		}
	},

	onResize: function()
	{
		window.setTimeout("ui.executeHandlers(ui.resizeHandlers)", 0);
	},

	cleanupElement: function(rootElement)
	{
		ui.executeHandlers(ui.cleanupHandlers, rootElement);

		var deList = rootElement.getElements("input[id$=_elements]");

		for (var i = 0; i < deList.length; i++)
		{
			var deMetaElements = ui.getMetaElements(deList[i].getParent());

			for (var e = 0; e < deMetaElements.length; e++)
			{
				var deMetaElement = deMetaElements[e];

				if (ui.controlRemovalHandlerList.contains(deMetaElement.TypeID))
				{
					ui.controlRemovalHandlers[deMetaElement.TypeID](deMetaElement.Control);
				}
			}
		}

		rootElement.empty();
	},

	processCommand: function(command)
	{
		var data = command.Data;

		if (ui.commandHandlerList.contains(command.Action))
		{
			ui.commandHandlers[command.Action](command);
		}
		else
		{
			switch (command.Action)
			{
				case "updateParameters":
					var dialogParams = $(data.DialogID + "_parameters");

					if (dialogParams != null)
					{
						$(data.DialogID + "_parameters").value = data.Parameters;
					}

					break;
				case "redirect":
					document.location.href = data.Url;
					break;
				case "eval":
					eval(data.Script);
					break;
				case "setDialog":
					var pnlContainer = null;

					if (data.ShowAsMP == true)
					{
						pnlContainer = $("mpDialogInner");
					}
					else
					{
						pnlContainer = $(data.Container);
					}

					if (pnlContainer == null)
					{
						break;
					}

					ui.cleanupElement(pnlContainer);

					var mp = $("mp");
					var mpDialog = $("mpDialog");

					mp.setOpacity(0.0);
					mp.setStyles({ display: "block" });

					mpDialog.setOpacity(0.0);
					mpDialog.setStyles({ display: "block" });

					pnlContainer.set("html", data.Dialog);

					//alert(JSON.encode(data.InitCommands));

					if (data.InitCommands && data.InitCommands.length > 0)
					{
						ui.processSubCommands(data.InitCommands);
					}

					if (data.ShowAsMP == true)
					{
						//						if (data.MPWidth != -1)
						//						{
						//							pnlContainer.set("width", data.MPWidth);
						//						}

						if (ui.onReceiveModalPopup != null)
						{
							ui.onReceiveModalPopup();
						}
					}

					//window.scrollTo(0,0);

					if (ui.onSetDialog != null)
					{
						ui.onSetDialog();
					}

					break;
				case "deleteDialog":
					var container = $(data.Container);

					if (container == null)
					{
						break;
					}

					ui.cleanupElement(container);

					break;
				case "cleanup":
					var container = ui.getNestedControl(data.dialogID, data.controlID);

					if (container == null)
					{
						break;
					}

					ui.cleanupElement(container);

					break;
				case "setControl":
					var oldEl = ui.getNestedControl(data.dialogID, data.controlID);

					if (oldEl == null)
					{
						break;
					}

					var tempParent = new Element("div");
					var newEl = null;

					//					if (data.isTable)
					//					{
					var tblEl = new Element("table");
					var tbodyEl = new Element("tbody");
					tblEl.adopt(tbodyEl);
					tbodyEl.set("html", data.controlHTML);

					newEl = tbodyEl.getFirst();
					//					}
					//					else
					//					{
					//						tempParent.set("html", data.controlHTML);
					//						newEl = tempParent.getFirst();
					//					}

					if (newEl == null)
					{
						break;
					}

					newEl.replaces(oldEl);

					break;
				case "setUIProp":
					var el = ui.getNestedControl(data.dialogID, data.controlID);

					if (el == null)
					{
						break;
					}

					el.set(data.key, data.value);

					break;
			}
		}
	},

	processSubCommands: function(subCommands, onFinish)
	{
		if (!subCommands)
		{
			return;
		}

		for (var i = 0; i < subCommands.length; i++)
		{
			try
			{
				ui.processCommand(subCommands[i]);
			}
			catch (e)
			{

			}
		}

		return true;
	},

	processCommands: function(commands, onFinish)
	{
		eventCommands = commands;

		if (!commands)
		{
			return;
		}

		for (var i = 0; i < commands.length; i++)
		{
			try
			{
				ui.processCommand(commands[i]);
			}
			catch (e)
			{

			}
		}

		if (ui.onAfterRequest != null)
		{
			ui.onAfterRequest();
		}

		ui.onResize();

		return true;
	}
});

var ui = new UIManager();