/**
* Collection of helper methods gathered in the Util object.
*/

var Util = new Object();

/**
* Finds an HTML element by its ID
*/
Util.getElement = function(id) {
	var actualDocument;
	var actualId;
	var idPath = id.split(":");
	if (idPath.length == 2 && idPath[0] == "parent") {
		actualDocument = window.parent.document;
		actualId = idPath[1];
	} else if (idPath.length == 3 && idPath[0] == "sibling") {
		var siblingElement = Util.getElement("parent:" + idPath[1]);
		if (siblingElement.contentWindow) {
			actualDocument = siblingElement.contentWindow.document;
		} else {
			actualDocument = siblingElement.document;
		}
		actualId = idPath[2];
	} else {
		actualDocument = document;
		actualId = id;
	}
	// cross-browser function to get an object's style object given its id
	if(actualDocument.getElementById) {
		// W3C DOM
		return actualDocument.getElementById(actualId);
	} else if (actualDocument.all) {
		// MSIE 4 DOM
		return actualDocument.all(actualId);
	} else if (actualDocument.layers) {
		// NN 4 DOM.. note: this won't find nested layers
		return actualDocument.layers[actualId];
	} else {
		return false;
	}
}

Util.getElementByTagName = function(tagName) {
	var nodeList = document.getElementsByName(tagName);
	if (nodeList && nodeList[0]) {
		return nodeList[0];
	} else {
		return null;
	}
}

Util.findAttribute = function(element, attributeName) {
	var attribute;
	while (element && element.attributes) {
		for (var i = 0; i < element.attributes.length; i++) {
			if (element.attributes.item(i).nodeName.toLowerCase() == attributeName.toLowerCase())
				attribute = element.attributes.item(i).nodeValue;
		}
		if (attribute) {
			if (typeof(attribute) == "object") {
				attribute = attribute.value;
			}
			break;
		} else {
			element = element.parentNode;
		}
	}
	return attribute;
}

Util.debug = function(name, obj) {
	var str = "";
	str += name + "[";
	for (var property in obj) {
		str += property + " :: ";
	}
	str += "]";
	alert(str);
}

Util.printHtmlTree = function(element, indent) {
	var str = "";
	if (element) {
		if (element.tagName) {
			str += indent + element.tagName;
			if (element.id)  {
				str += " (id=" + element.id + ")";
			}
			str += "\n";
		} else if (element.className) {
			str += indent + element.className + "\n";
		} else {
			str += indent + "->\n";
		}
		if (element.childNodes) {
			var children = element.childNodes;
			for (var i = 0; i < children.length; i++) {
				str += Util.printHtmlTree(children[i], indent + "   ");
			}
		}
	} else {
		str += indent + "null\n";
	}
	return str;
}

/**
* Creates a new HTML element of a specific type and appends it
* to the parent element.
* DEPRECATED use dojo.dom.insert... instead
*/
Util.createElement = function(type, parent) {
	var element = document.createElement(type);
	if (!parent || !parent.appendChild) {
		parent = document.body;
	}
	parent.appendChild(element);
	return element;
}

/**
* Gets a specific style property of an HTML element.
*/
Util.getStyle = function(element, property) {
	if (element.style) {
		return element.style[property];
	} else {
		return null;
	}
}

/**
* Changes a specific style property of an HTML element.
*/
Util.setStyle = function(element, property, value) {
	if (element && element.style) {
		element.style[property] = value;
	}
}

Util.setEnabled = function(element, enabled) {
	if (element) {
		element.disabled = !enabled;
	}
}

/**
* Gets the style property 'width' of an HTML element.
*/
Util.getWidth = function(element) {
	return this.getStyle(element, "width");
}

/**
* Changes the style property 'width' of an HTML element.
*/
Util.setWidth = function(element, width) {
	this.setStyle(element, "width", width);
}

/**
* Gets the style property 'height' of an HTML element.
*/
Util.getHeight = function(element) {
	return this.getStyle(element, "height");
}

/**
* Changes the style property <code>height</code> of an HTML element.
*/
Util.setHeight = function(element, height) {
	this.setStyle(element, "height", height);
}

/**
* Change the visibility of an object given its id.
*/
Util.changeVisibility = function(id, visible) {
	var element = getElement(id);
	if (element && element.style) {
		element.style = visible;
	}
}

Util.display = function(element, display) {
	if (element) {
		if (display) {
			element.style.display = "block";
		} else {
			element.style.display = "none";
		}
	}
}

Util.moveTo = function(id, xCoord, yCoord) {
	var element = getElement(id);
	if (element && element.style) {
		element.style.left = xCoord;
		element.style.top = yCoord;
	}
}

/**
* Returns the absolute horizontal position of an HTML element.
*/
Util.getHorizontalPosition = function(element) {
	if (element) {
		var x = 0;
		while (element.offsetParent) {
			x += element.offsetLeft;
			element = element.offsetParent;
		}
		return x;
	} else {
		return 0;
	}
}

/**
* Returns the absolute vertical position of an HTML element.
*/
Util.getVerticalPosition = function(element) {
	if (element) {
		var y = 0;
		while (element.offsetParent) {
			// don't take divs into account
			if (element.tagName.toLowerCase()!="div") {
				y += element.offsetTop;
			}
			element = element.offsetParent;
		}
		return y;
	} else {
		return 0;
	}
}

/**
* Returns the width of a specific frame or the whole window.
*/
Util.getWindowWidth = function(frame) {
	if (frame) {
		var frameWidth = Util.getWidth(frame);
		if (typeof(frameWidth) != "undefined" && parseInt(frameWidth)) {
			return parseInt(frameWidth);
		}
		if (frame.contentWindow && frame.contentWindow.innerWidth) {
			return frame.contentWindow.innerWidth;
		} else if (frame.contentWindow && frame.contentWindow.document && frame.contentWindow.document.documentElement && frame.contentWindow.document.documentElement.clientWidth) {
			return frame.contentWindow.document.documentElement.clientWidth;
		} else if (frame.contentWindow && frame.contentWindow.document && frame.contentWindow.document.body && frame.contentWindow.document.body.clientWidth) {
			return frame.contentWindow.document.body.clientWidth;
		}
	} else {
		if (window.innerWidth) {
			return window.innerWidth;
		} else if (window.document && window.document.documentElement && window.document.documentElement.clientWidth) {
			return window.document.documentElement.clientWidth;
		} else if (window.document && window.document.body && window.document.body.clientWidth) {
			return window.document.body.clientWidth;
		}
	}
	return 800;
}

/**
* Returns the height of a specific frame or the whole window.
*/
Util.getWindowHeight = function(frame) {
	if (frame) {
		var frameHeight = Util.getHeight(frame);
		if (typeof(frameHeight) != "undefined" && parseInt(frameHeight)) {
			return parseInt(frameHeight);
		}
		if (frame.contentWindow && frame.contentWindow.innerHeight) {
			return frame.contentWindow.innerHeight;
		} else if (frame.contentWindow && frame.contentWindow.document && frame.contentWindow.document.documentElement && frame.contentWindow.document.documentElement.clientHeight) {
			return frame.contentWindow.document.documentElement.clientHeight;
		} else if (frame.contentWindow && frame.contentWindow.document && frame.contentWindow.document.body && frame.contentWindow.document.body.clientHeight) {
			return frame.contentWindow.document.body.clientHeight;
		}
	} else {
		if (window.innerHeight) {
			return window.innerHeight;
		} else if (window.document && window.document.documentElement && window.document.documentElement.clientHeight) {
			return window.document.documentElement.clientHeight;
		} else if (window.document && window.document.body && window.document.body.clientHeight) {
			return window.document.body.clientHeight;
		}
	}
	return 600;
}

// event methods --------------------------------------------------------------

Util.getEvent = function(event) {
	if (event) {
		return event;
	} else {
		return window.event;
	}
}

Util.stopEventBubble = function(event) {
	if (event.stopPropagation) {
		event.stopPropagation();
	} else {
		event.cancelBubble = true;
	}
}

Util.setEventReturnValue = function(myEvent, value) {
	if (typeof(event) == "undefined" && !value) {
		myEvent.preventDefault();
	} else {
		event.returnValue = value;
	}
}

Util.addEvent = function(element, name, functor) {
	if (typeof(event) == "undefined") {
		element.addEventListener(name, functor, false);
	} else {
		element[name] = functor;
	}
}

Util.removeEvent = function(element, name, functor) {
	if (typeof(event) == "undefined") {
		element.removeEventListener(name, functor, false);
	} else {
		element[name] = null;
	}
}

Util.getEventTarget = function(event) {
	var target;
	if (!event) {
		event = window.event;
	}
	if (event) {
		if (event.target) {
			target = event.target;
		} else if (event.srcElement) {
			target = event.srcElement;
		}
		if (target && target.nodeType == 3) { // defeat Safari bug
			target = target.parentNode;
		}
	}
	return target;
}

// Deprecated: use dojo.html.getCursorPosition(event) instead
Util.getMousePosition = function(event) {
	var position = new Array(2);
	position[0] = 0;
	position[1] = 0;
	if (!event) {
		event = window.event;
	}
	if (event.pageX || event.pageY) {
		position[0] = event.pageX;
		position[1] = event.pageY;
	} else if (event.clientX || event.clientY) {
		position[0] = event.clientX + document.body.scrollLeft;
		position[1] = event.clientY + document.body.scrollTop;
	}
	return position;
}

// misc -----------------------------------------------------------------------

Util.under_development = function() {
	alert("Sorry, this functionality is under development !");
}

Util.fullScreen = function(url, name, modal) {
	var fullScreenOptions = "menubar=no,resizable=yes,scrollbars=no,status=no,toolbar=no,location=no";
	var dimOptions = "top=" + 2 + ",left=" + 2 + ",width=" + (screen.availWidth - 15) + ",height=" + (screen.availHeight - 40);
	var win;
	// FIXME: RGR: this code is buggy as showModalDialog method use a different set
	// of parameter (dialogHeight instead of height for instance).
	if (modal) {
		if (window.showModalDialog) {
			window.showModalDialog(url,window,dimOptions+","+fullScreenOptions);
		} else {
			win = window.open(url, name, dimOptions+","+fullScreenOptions+",modal=yes");
			window.onfocus = function(){
				if (win.closed == false){win.focus();}
			}
		}
	} else {
		win = window.open(url, name, dimOptions + "," + fullScreenOptions);
	}
	return win;
}

Util.popupCentered = function(url, name, width, height, additionalOptions, delta, windowOpener) {
	var top = (screen.availHeight - height) / 2;
	var left = (screen.availWidth - width) / 2;
	if (delta) {
		top += delta;
		left += delta;
	}
	var options = "top=" + top + ",left=" + left + ",width=" + width + ",height=" + height;
	if (additionalOptions) {
		options += "," + additionalOptions;
	}
	if (! windowOpener) {
		windowOpener = window;
	}
	var popup = windowOpener.open(url, name, options, false);
	if (! popup.opener) {
      popup.opener = windowOpener;
    }
    return popup;
}

Util.preloadImage = function(src) {
	var preloaded = new Image();
	preloaded.src = src;
}

Util.submitFormToUrl = function(newUrl, form)	{
	var submitForm;
	if (form) {
		submitForm = form;
	} else {
		submitForm = document.forms[0];
	}
	if (submitForm) {
		submitForm.action = newUrl;
		if (submitForm.onsubmit) {
			var canSubmit = submitForm.onsubmit();
			if (canSubmit) {
				submitForm.submit();
			}
		} else {
			submitForm.submit();
		}
	}
}

Util.selectAs = function(checkbox, field) {
	if (field && checkbox) {
		for (i = 0; i < field.length; i++) {
			if (! field[i].disabled) {
				field[i].checked = checkbox.checked;
			}
		}
	}
}

Util.selectAll = function(field) {
	if (field) {
		for (i = 0; i < field.length; i++) {
			if (! field[i].disabled) {
				field[i].checked = true;
			}
		}
	}
}

Util.unselectAll = function(field) {
	if (field) {
		for (i = 0; i < field.length; i++) {
			if (! field[i].disabled) {
				field[i].checked = false;
			}
		}
	}
}

Util.disableFormButtons = function(formId) {
	var formElement = Util.getElement(formId);
	if (formElement) {
  		for(var j = 0; j < formElement.elements.length; j++) {
			var currentElement = formElement.elements[j];
			var type = currentElement.type.toLowerCase();
			if (type == "button" || type == "submit" || type == "image") {
				currentElement.disabled = true;
			}
		}
	}
}

Util.onlyDigits = function(e) {
	var keynum;
 	var accepted;

 	if(window.event) { // IE
  		keynum = e.keyCode
 	} else if(e.which) { // Netscape/Firefox/Opera
  		keynum = e.which
 	}
	accepted = !/\D/.test(String.fromCharCode(keynum));
	switch (e.keyCode) {
		case 8: // backsp
	  	case 13: // enter
	  	case 37: // arrow left
	  	case 38: // arrow up
	  	case 39: // arrow right
	  	case 40: // arrow down
	  	case 46: // del
	   	accepted = true;
	   	break;
	}
	return accepted;
}
