﻿var UIDialog = new Class(
{
	initialize: function(uiManager)
	{
		this.typeID = "dlg";
		this.elType = "object";
		this.dialogs = [];

		this.preInitHandlers = { "dlg": this.init };
		this.initHandlers = {};

		ui.registerViewStateHandler(this.typeID, this.collectViewState);
		ui.registerCleanupHandler(this.cleanupDialogs);
		ui.registerControlRemovalHandler(this.typeID, this.cleanupDialog);

		this.deIgnore = "__type";
	},

	registerPreInitHandler: function(typeID, handler)
	{
		uiDialog.preInitHandlers[typeID] = handler;
	},

	registerInitHandler: function(typeID, handler)
	{
		uiDialog.initHandlers[typeID] = handler;
	},

	collectViewState: function(dialog)
	{
		var dialogData = dialog.retrieve("clientData");
		var dialogElements = dialog.retrieve("elements");
		var dialogParams = dialogData["_p"];

		var dialogState = uiDialog.collectDialogState(dialog, dialogElements);

		var viewState = {
			"__type": "vs",
			"State": dialogState,
			"Parameters": dialogParams
		};

		return viewState;
	},

	handleEvent: function()
	{
		var control = this.elControl;
		var eventName = this.eventName;

		var dialog = control.retrieve("dialog");
		var dialogData = dialog.retrieve("clientData");
		var dialogElements = dialog.retrieve("elements");

		var dialogParams = dialogData["_p"];
		var dialogTypeID = dialogData["_dt"];

		//var viewState = base64Json.encode(ui.collectViewState(dialog, false));
		var dialogState = base64Json.encode(uiDialog.collectDialogState(dialog, dialogElements));

		if (ui.onBeforeRequest != null)
		{
			ui.onBeforeRequest();
		}

		var eventParams = { "dialogID": dialogTypeID, "dialogParams": dialogParams, "dialogState": dialogState, "controlID": control.id, "eventName": eventName, "siteState": "" };
		var eventParamsJSON = JSON.encode(eventParams);

		var reqEvent = new Request(
		{
			url: "/UIService.asmx/HandleEvent",
			urlEncoded: false,
			method: "post",
			data: eventParamsJSON,
			headers: { "Content-Type": "application/json; charset=utf-8", "Accept": "application/json" },
			onSuccess: function(retVal)
			{
				var commands = JSON.decode(retVal)["d"];
				ui.processCommands(commands);
			},
			onFailure: function(instance)
			{
				//alert(JSON.encode(instance));
			}
		});

		reqEvent.send();
	},

	collectDialogState: function(dialog, elements)
	{
		var dialogState = { "__type": "cs" };

		for (var element in elements)
		{
			var el = elements[element];

			var typeID = el["_t"];
			var elControl = el.instance;

			var viewStateHandler = ui.viewStateHandlers[typeID];

			if ($defined(viewStateHandler))
			{
				dialogState[element] = viewStateHandler(elControl);
			}
		}

		return dialogState;
	},

	preInitElements: function(dialog, elements)
	{
		for (var element in elements)
		{
			var el = elements[element];

			var typeID = el["_t"];
			var elControl = el.instance;
			var controlEvents = el["events"];

			var preInitHandler = uiDialog.preInitHandlers[typeID];

			if (preInitHandler != null)
			{
				preInitHandler(elControl, el);
			}

			if (controlEvents != null)
			{
				for (var controlEvent in controlEvents)
				{
					if (controlEvent == uiDialog.deIgnore)
					{
						continue;
					}

					var eventData = controlEvents[controlEvent];
					var actions = eventData["a"];

					for (var i = 0; i < actions.length; i++)
					{
						var action = actions[i];

						var obj = window[action["o"]];

						if ($defined(obj))
						{
							var method = obj[action["m"]];

							if ($defined(method)) // && $type(method) == 'function'
							{
								elControl.addEvent(controlEvent, method.bindWithEvent(elControl, action["p"]));
							}
						}
					}

					if (eventData["s"])
					{
						var handleEventContext = { "eventName": controlEvent, "elControl": elControl };

						elControl.addEvent(controlEvent, uiDialog.handleEvent.bind(handleEventContext));
					}
				}
			}
		}
	},

	initElements: function(dialog, elements)
	{
		for (var element in elements)
		{
			var el = elements[element];

			var typeID = el["_t"];
			var elControl = el.instance;

			var initHandler = uiDialog.initHandlers[typeID];

			elControl.fireEvent("__init");

			if (initHandler != null)
			{
				initHandler(elControl, el);
			}
		}
	},

	init: function(dialog, clientData)
	{
		uiDialog.dialogs.push(dialog);

		var elements = {};

		for (var control in clientData)
		{
			var controlClientData = clientData[control];

			if ($type(controlClientData) != uiDialog.elType)
			{
				continue;
			}

			var elControl = ui.getSubElement(dialog, control);

			if (elControl == null)
			{
				continue;
			}

			controlClientData["instance"] = elControl;

			elControl.store("dialog", dialog);
			elControl.store("clientData", controlClientData);

			elements[control] = controlClientData;
		}

		dialog.store("clientData", clientData);
		dialog.store("elements", elements);

		try
		{
			uiDialog.preInitElements(dialog, elements);
			uiDialog.initElements(dialog, elements);
		}
		catch (e)
		{
			alert(JSON.encode(e));
		}
	},

	cleanupDialog: function(dialog)
	{
		var elements = dialog.retrieve("elements");

		for (var element in elements)
		{
			var el = elements[element];

			var typeID = el["_t"];
			var elControl = el.instance;

			var removalHandler = ui.elementRemovalHandlers[typeID];

			if (removalHandler != null)
			{
				removalHandler(elControl);
			}
		}
	},

	cleanupDialogs: function(rootElement)
	{
		var filteredDialogs = [];

		for (var i = 0; i < uiDialog.dialogs.length; i++)
		{
			var dialog = uiDialog.dialogs[i];

			if (dialog == null)
			{
				continue;
			}

			if (!rootElement.hasChild(dialog))
			{
				filteredDialogs.push(dialog);
			}
			else
			{
				uiDialog.cleanupDialog(dialog);
			}
		}

		uiDialog.dialogs = filteredDialogs;
	}
});

var uiDialog = new UIDialog();
