FlowBasis.Api = new Object();

FlowBasis.defineNamespace = function(namespace) {
	var parts = namespace.split('.');	
	var current = FlowBasis;
	for (var i = 0; i < parts.length; i++) {		
		var part = parts[i];
		if (current[part]) {
			current = current[part];
		}
		else {
			var newNamespace = new Object();
			current[part] = newNamespace;
			current = newNamespace;
		}		
	}
};

FlowBasis.Api.extendClass = function(derivedClass, parentClass) {
	for (var member in parentClass.prototype) {
		derivedClass.prototype[member] = parentClass.prototype[member];
	}
};

FlowBasis.each = function(obj, callback) {
	if (obj != null) {
		if (obj.length === undefined) {
			for (var i in obj) {
				callback(obj[i], i);
			}
		}
		else {
			for (var i = 0; i < obj.length; i++) {
				callback(obj[i], i);
			}
		}
	}
};

// Standard dialogs for the site.

FlowBasis.defineNamespace('UI');


FlowBasis.UI.alert = function(message, callback) {	
	
	if (FlowBasis.UI.alertDialog == null) {
		
		YAHOO.util.Dom.addClass(document.body, 'yui-skin-sam');
		
		var dialog = FlowBasis.YUI.createDialog(
			'flowbasis-alert-panel',
			{
				width: null,				
				'buttons': [
					{
						text: 'OK', 
						handler: function() {
							this.hide();	
							
							if (FlowBasis.UI.alertDialog.callback) {
								FlowBasis.UI.alertDialog.callback();
							}
						} 
					}
				]
			},
			null,
			document.createElement('div')
		);		
			
		FlowBasis.UI.alertDialog = dialog;
	}
	
	var bodyDiv = document.createElement('div');
	bodyDiv.innerHTML = message;
	FlowBasis.UI.alertDialog.setBody(bodyDiv);			
	
	FlowBasis.UI.alertDialog.callback = callback;
	FlowBasis.UI.alertDialog.show();	
};


FlowBasis.UI.confirm = function(header, messageInnerHTML, confirmCallback) {
	FlowBasis.confirmDialog.confirm(header, messageInnerHTML, confirmCallback);
}



/* Control base class */
FlowBasis.UI.Control = function() {
}

FlowBasis.UI.Control.prototype.invoke = function(method, params, callback) {
	FlowBasis.rpc.invoke(this.rpcUri, method, params, callback);
};

FlowBasis.UI.Control.prototype.invokeAndWait = function(method, params, callback) {
	FlowBasis.rpc.invokeAndWait(this.rpcUri, method, params, callback);
};


/* Wait dialog */

FlowBasis.waitDialog = {
	
	waitDialog : null,
	
	show : function() {
			
		YAHOO.util.Dom.addClass(document.body, 'yui-skin-sam');
		
		if (FlowBasis.waitDialog.waitDialog == null) {
			var waitPanel = new YAHOO.widget.Panel('site-wait-panel', {
				width: '250px',
				fixedcenter: true,
				close: false,
				draggable: false,
				modal: true,
				visible: false,
				zindex: 1000
			});
			
			waitPanel.setHeader('Loading, please wait...');
			
			var bodyDiv = document.createElement('div');
			bodyDiv.style.textAlign = 'center';
			
			var progressBar = document.createElement('img');			
			progressBar.src = FlowBasis.paths.themeRoot + '/img/progressBar.gif';
			bodyDiv.appendChild(progressBar);
			
			waitPanel.setBody(bodyDiv);
			waitPanel.render(document.body);
			FlowBasis.waitDialog.waitDialog = waitPanel;
		}
				
		FlowBasis.waitDialog.waitDialog.show();
	},
	
	hide : function() {
		if (FlowBasis.waitDialog.waitDialog != null) {
			FlowBasis.waitDialog.waitDialog.hide();
		}
	}
};
	
	
// Confirm dialog.
	
FlowBasis.confirmDialog = {
	confirmDialog : null,
	confirmCallback : null,
	
	// confirmCallback is a function with prototype function(confirmed).
	confirm : function(header, messageInnerHTML, confirmCallback) {
		
		if (FlowBasis.confirmDialog.confirmDialog == null) {
			var dialog = FlowBasis.YUI.createDialog(
				'sitelib-confirm-dialog',
				{
					width: null,						
					
					'buttons': [
						{ 	
							text: 'No', 
							handler: function() { 
								this.hide();
								if (FlowBasis.confirmDialog.confirmCallback) {
									FlowBasis.confirmDialog.confirmCallback(false);
								}
							} 
						},
						{
							text: 'Yes', 
							handler: function() {
								this.hide(); 
								if (FlowBasis.confirmDialog.confirmCallback) {
									FlowBasis.confirmDialog.confirmCallback(true);
								}									
							} 
						}
					]
				},
				header,
				document.createElement('div')
			);		
			
			FlowBasis.confirmDialog.confirmDialog = dialog;
		}
		
		FlowBasis.confirmDialog.confirmCallback = confirmCallback;
		FlowBasis.confirmDialog.confirmDialog.setHeader(header);
		
		var bodyDiv = document.createElement('div');
		bodyDiv.innerHTML = messageInnerHTML;
		FlowBasis.confirmDialog.confirmDialog.setBody(bodyDiv);			
		
		FlowBasis.confirmDialog.confirmDialog.show();
	}
};
	
	
// Standard YUI helpers.
	
FlowBasis.YUI = {
		
	dialogCloseButtons : [
		{ 	
			text: 'Close', 
			handler: function() { this.hide(); } 
		}
	],
	
	createDialog : function(dialogID, customOptions, header, bodyDiv) {
	
		YAHOO.util.Dom.addClass(document.body, 'yui-skin-sam');
		
		var fadeEffect = null;
		if (YAHOO.widget.ContainerEffect) {
			fadeEffect = {
				effect: YAHOO.widget.ContainerEffect.FADE, 
				duration: 0.25
			};
		}
	
		var options = {
			width: '600px',
			fixedcenter: true,
			close: false,
			draggable: false,
			modal: true,
			visible: false,
			zindex: 1000,
			'buttons': FlowBasis.YUI.dialogCloseButtons,
			effect: fadeEffect
		};
		
		if (customOptions != null) {
			for (var option in customOptions) {
				options[option] = customOptions[option];
			}
		}
		
		var dialog = new YAHOO.widget.Dialog(dialogID, options);
		
		if (bodyDiv != null) {				
			dialog.setBody(bodyDiv);
		}
		
		if (header != null) {
			dialog.setHeader(header);
		}
		
		dialog.render(document.body);
		
		return dialog;
	}
	
};
	
	
// Helper for JSON services.
	
FlowBasis.rpc = {
		
	invoke : function(url, method, params, callback) {
		
		if (url == null) {
			url = window.location;
		}
		
		JsonServiceClient.invoke(url, method, params, callback);		
	},
	
	/*
	 * invokeAndWait will invoke an rpc method and popup the waiting dialog
	 * until the request finishes.
	 */
	invokeAndWait : function(url, method, params, callback, options) {
	
		FlowBasis.waitDialog.show();
		
		FlowBasis.rpc.invoke(
			url, method, params,
			function (response) {
				FlowBasis.waitDialog.hide();
				
				if (response.error != null) {					
					if (options && options.suppressDefaultErrorMessage) {
						// callback is responsible for showing error.
					}
					else {
						
						var errorMessage;
						
						if (response.error.message) {
							errorMessage = response.error.message;
						}
						else {
							errorMessage = 'Error with no error message.';
						}
						
						FlowBasis.UI.alert(
							errorMessage,
							function() {
								if (callback) {
									callback(response);
								}
							});
						
						// callback will be called from alert callback.
						return;
					}
				}
				
				if (callback) {
					callback(response);
				}
			});		
	},
	
	
	/*
	 * invokeWaitAndReload will invoke an rpc method and popup the waiting dialog
	 * until the request finishes, and then reload the page.
	 */
	invokeWaitAndReload : function(url, method, params) {
	
		FlowBasis.waitDialog.show();
		
		FlowBasis.rpc.invokeAndWait(
			url, method, params,
			function (response) {
                FlowBasis.waitDialog.show();
				window.location.reload();
			});		
	},
	
	
	/*
	 * updateElement will invoke and rpc method and replace the div
	 * with a waiting progress bar until the response returns.
	 */
	updateElement : function(divID, url, method, params, callback) {
	
		if (divID.tagName) {
			var element = divID;
		}
		else {
			var element = document.getElementById(divID);
		}
		
		var region = YAHOO.util.Dom.getRegion(divID);
		var regionWidth = region.right - region.left;
		var regionHeight = region.bottom - region.top;
		
		element.innerHTML =
			'<div style="width: ' + regionWidth + 'px; height: ' + regionHeight + 'px">' +
			'<img src="' + FlowBasis.paths.themeRoot + '/img/progressBar.gif" style="padding: 10px;" />' +
			'</div>';		
	
		FlowBasis.rpc.invoke(
			url, method, params,
			function(response) {		
				if (response.error == null) {
					element.innerHTML = response.result;
				}
				else {
					element.innerHTML = response.error.message;
				}
				
				if (callback) {
					callback(response);
				}
			}
		);
	}
	
};
	
	
FlowBasis.debug = {
		
	printObject : function(element, name, obj, maxDepth) {
		
		if (!maxDepth) {
			maxDepth = 0;
		}
	
		element.innerHTML = '';
		element.appendChild(document.createTextNode(name + ': '));
		
		if ((typeof(obj) != 'object') && (typeof(obj) != 'array')) {
			element.appendChild(document.createTextNode(obj));
		}
		else {				
			if (maxDepth > 0) {
				
				var listElement = null;
				
				FlowBasis.each(obj, function(value, index) {
					if (listElement == null) {
						listElement = document.createElement('ul');
						listElement.style.marginLeft = '15px';
					}
					
					var itemElement = document.createElement('li');
					FlowBasis.debug.printObject(itemElement, index, value, maxDepth - 1);
					
					listElement.appendChild(itemElement);
				});
				
				if (listElement != null) {
					element.appendChild(listElement);
				}
			}
		}
	}
	
};


/*
 * FlowBasis.Dom - helpers for DOM manipulation.
 */

FlowBasis.defineNamespace('Dom');

FlowBasis.Dom.getRadioInputValue = function(radioInputElements) {
	if (radioInputElements) {
		var count = radioInputElements.length;
		for (var radioIndex = 0; radioIndex < count; radioIndex++) {
			var radio = radioInputElements[radioIndex];		
			
			if (radio.checked) {
				return radio.value;
			}
		}
	}
	
	return null;
};

FlowBasis.Dom.setRadioInputValue = function(radioInputElements, value) {
	if (radioInputElements) {
		var count = radioInputElements.length;
		for (var radioIndex = 0; radioIndex < count; radioIndex++) {
			var radio = radioInputElements[radioIndex];		
			if (radio.value == value) {
				radio.checked = true;
				break;
			}
		}
	}
};

FlowBasis.Dom.getParentByTagName = function(node, tagName) {
	if (node == null) {
		return null;
	}
	
	node = node.parentNode;
	while (node != null) {
		if (node.tagName == tagName) {
			return node;
		}
		node = node.parentNode;
	}
};

/*
 * Retrieve node of form containing this node.
 */
FlowBasis.Dom.getNodeForm = function(node) {
	return FlowBasis.Dom.getParentByTagName(node, 'FORM');
};


/*
 * Retrieve child input node by name.
 */
FlowBasis.Dom.getChildInputNodeByName = function(node, inputName) {
	if (node == null) {
		return null;
	}
	
	if (node.tagName == 'INPUT' && node.name == inputName) {
		return node;
	}
	
	var childNodes = node.childNodes;
	if (childNodes != null) {
		for (var i = 0; i < childNodes.length; i++) {
			var foundNode = FlowBasis.Dom.getChildInputNodeByName(childNodes[i], inputName);
			if (foundNode != null) {
				return foundNode;
			}
		}
	}
};


FlowBasis.Dom.rerunScriptsLoaded = [];
FlowBasis.Dom.rerunScripts = function(element) {
    if (element.nodeName == "SCRIPT") {
        var scriptSrc = element.src;
        if (scriptSrc != null && scriptSrc.length > 0) {
            // try to dynamically load script
            var found = false;
            for (var i = 0; i < FlowBasis.Dom.rerunScriptsLoaded.length; i++) {
                if (FlowBasis.Dom.rerunScriptsLoaded[i] == scriptSrc) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                FlowBasis.Dom.rerunScriptsLoaded.push(element.src);
                var head = document.getElementsByTagName('head')[0];
                var script = document.createElement('script');
                script.src = scriptSrc;
                if (element.type != null) {
                    script.type = element.type;
                }
                head.appendChild(script);
            }
        }
        else {
            // evaluate script
            eval(element.innerHTML);
        }
    }
    else {
        var childNodes = element.children;
        if (childNodes != null) {
            for (var i = 0; i < childNodes.length; i++) {
                FlowBasis.Dom.rerunScripts(childNodes[i]);
            }
        }
    }
}

