﻿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 UIManager = new Class(
{
	initialize : function()
	{
		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() { };
	},

	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 + "']");
	},

	collectDialogState : function(dialog)
	{
		if (dialog == null)
		{
			return { };
		}

		return {
			"DialogID" : dialog.id,
			"DialogTypeID" : dialog.getProperty("typeid"),
			"DialogState" : ui.collectViewState(dialog, true),
			"DialogParameters" : base64Json.decode($(dialog.id + "_parameters").value)
		}
	},

	getMetaControls : function(dialog)
	{
		var dialogControls = $(dialog.id + "_controls");
		var metaControls = [ ];

		if (dialogControls.value != "")
		{
			var controls = dialogControls.value.split(",");

			for (var i = 0; i < controls.length; i++)
			{
				var dialogControl = controls[i].split(":");

				var metaControl =
				{
					ID      : dialogControl[0],
					TypeID  : dialogControl[1],
					Control : null					
				};

				metaControl.Control = ui.getNestedControl(dialog, metaControl.ID);

				metaControls.push(metaControl);
			}
		}

		return metaControls;
	},

	collectViewState : function(dialog, collectSubStates)
	{
		var controlStates = { };

		controlStates["__type"] = "cs";

		if (dialog == null)
		{
			return controlStates;
		}

		var metaControls = ui.getMetaControls(dialog);

		for (var i = 0; i < metaControls.length; i++)
		{
			var metaControl = metaControls[i];

			if (ui.viewStateHandlerList.contains(metaControl.TypeID))
			{
				if (metaControl.Control != null)
				{
					controlStates[metaControl.ID] = ui.viewStateHandlers[metaControl.TypeID](metaControl.Control);
				}
			}
		}

		if (collectSubStates == true)
		{
			var metaDialogs = $(dialog.id + "_dialogs");

			if (metaDialogs.value != "")
			{
				var dialogs = metaDialogs.value.split(",");

				for (var i = 0; i < dialogs.length; i++)
				{
					var dialogState = ui.collectViewState($(dialogs[i]), true);

					var temp = {};

					temp["__type"] = "vs";
					temp["State"] = dialogState;
					temp["Parameters"] = base64Json.decode($(dialogs[i] + "_parameters").value);

					controlStates[dialogs[i]] = temp;
				}
			}
		}

		return controlStates;
	},

	attachDialogState : function(dialogID)
	{
		this.attachedDialogState = base64Json.encode(this.collectDialogState($(dialogID)));
	},

	overwriteDialogTarget : function(dialogID)
	{
		this.targetDialog = dialogID;
	},

	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 dialogTypeID = dialog.getProperty("typeid");
		var viewState = base64Json.encode(this.collectViewState(dialog, false));
		var parameters = $(dialogID + "_parameters").value;

		if (this.onBeforeRequest != null)
		{
			this.onBeforeRequest();
		}

		UIService.HandleEvent(dialogID, dialogTypeID, parameters, viewState, sender.id, eventName, this.attachedDialogState, this.processCommands);
		this.attachedDialogState = '';
	},

	load : function()
	{
		this.processCommands(this.initCommands);
	},
	
	processCommands : function(commands, onFinish)
	{
		if (!commands)
		{
			return;
		}

		for (var i = 0; i < commands.length; i++)
		{
			var command = commands[i];
			var data = command.Data;

			if (ui.commandHandlerList.contains(command.Action))
			{
				ui.commandHandlers[command.Action](command);
			}
			else
			{
				switch (command.Action)
				{
					case "update":
						var isModalPopup = data.IsModalPopup;
						var ajaxPanel = null;

						if (isModalPopup == true)
						{
							ajaxPanel = $("mpDialogInner");
						}
						else
						{
							ajaxPanel = $(data.AjaxPanel);
						}

						if (ajaxPanel == null)
						{
							alert("Could not find ajax panel to update");
							return;
						}

						ajaxPanel.setHTML(data.Content);

						if (data.ResetScroll == true)
						{
							window.scrollTo(0,0);
						}

						if (isModalPopup == true)
						{
							if (ui.onReceiveModalPopup != null)
							{
								ui.onReceiveModalPopup();
							}
						}

						break;
					case "redirect":
						document.location.href = data.Url;
						break;
					case "eval":
						eval(data.Script);
						break;
					case "setDialog":
						var ajaxPanel = $(data.AjaxPanel);

						if (ajaxPanel == null)
						{
							break;
						}

						ajaxPanel.setHTML(data.Content);

						if (data.InitCommands && data.InitCommands.length > 0)
						{
							ui.processCommands(data.InitCommands);
						}

						window.scrollTo(0,0);

						if (ui.onSetDialog != null)
						{
							ui.onSetDialog();
						}

						break;
					case "deleteDialog":
						var ajaxPanel = $(data.AjaxPanel);

						if (ajaxPanel == null)
						{
							break;
						}

						ajaxPanel.empty();

						break;
				}
			}
		}

		if (ui.onAfterRequest != null)
		{
			ui.onAfterRequest();
		}

		if (onFinish != null)
		{
			onFinish();
		}

		return true;
	}
});

var ui = new UIManager();