var Utilities = {
	_isIE: null,

	getPrevNode: function(node, nodeName) {
		var checkNode = node.previousSibling;
		while(checkNode != null) {
			if(checkNode.nodeName.toLowerCase() == nodeName.toLowerCase()) {
				return checkNode;
			}
			checkNode = checkNode.previousSibling;
		}
		return null;
	},

	getNextNode: function(node, nodeName) {
		if(node == null) {
			throw "Utilities.getNextNode: node is a null reference";
		}
		var checkNode = node.nextSibling;
		while(checkNode != null) {
			if(checkNode.nodeName.toLowerCase() == nodeName.toLowerCase()) {
				return checkNode;
			}
			checkNode = checkNode.nextSibling;
		}
		return null;
	},

	getAncestorNode: function(node, nodeName) {
		var parent = node.parentNode;
		while(parent != null) {
			if(parent.nodeName.toLowerCase() == nodeName.toLowerCase()) {
				return parent;
			}
			parent = parent.parentNode;
		}
	},

	getImmediateChildNode: function(node, nodeName) {
		for(var i = 0; i < node.childNodes.length; i++) {
			var child = node.childNodes[i];
			if(child.nodeName.toLowerCase() == nodeName.toLowerCase()) {
				return child;
			}
		}
		return null;
	},

	fixEvent: function(event) {
		if(!event) {
			event = window.event;
		}

		if(event.target) {
			// get parent node of text node
			if(event.target.nodeType == 3) event.target = event.target.parentNode;
		} else if(event.srcElement) {
			event.target = event.srcElement;
		}

		return event;
	},

	getPageX: function(event) {
		return event.clientX + Utilities.getScrollXY()[0];
	},

	getPageY: function(event) {
		return event.clientY + Utilities.getScrollXY()[1];
	},

	getScrollXY: function() {
		var scrOfX = 0, scrOfY = 0;
		if(typeof (window.pageYOffset) == 'number') {
			//Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
			//DOM compliant
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		} else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
			//IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		}
		return [scrOfX, scrOfY];
	},

	trim: function(text) {
		if(text == null) return text;
		var ws = " \n\t";
		// trim end
		while(text.length > 0 && ws.indexOf(text.charAt(text.length - 1)) != -1) {
			text = text.substr(0, text.length - 1);
		}
		// trim start
		while(text.length > 0 && ws.indexOf(text.charAt(0)) != -1) {
			text = text.substring(1, text.length);
		}
		return text;
	},

	// makes a string of <characters> repeated <repeat> times.
	makeString: function(characters, repeat) {
		var result = "";
		for(var i = 0; i < repeat; i++) {
			result += characters;
		}
		return result;
	},

	getOffsetTop: function(element) {
		var top = element.offsetTop;
		var parent = element.offsetParent;
		while(parent != null) {
			top += parent.offsetTop;
			parent = parent.offsetParent;
		}
		return top;
	},

	getOffsetLeft: function(element) {
		var left = element.offsetLeft;
		var parent = element.offsetParent;
		while(parent != null) {
			left += parent.offsetLeft;
			parent = parent.offsetParent;
		}
		return left;
	},

	isIE: function() {
		if(Utilities._isIE == null) {
			var ua = navigator.userAgent.toLowerCase();
			Utilities._isIE = ((ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1));
		}
		return Utilities._isIE;
	},

	readStyle: function(element, property) {
		if(element.style[property]) {
			return element.style[property];

		} else if(element.currentStyle) {
			return element.currentStyle[property];

		} else if(document.defaultView && document.defaultView.getComputedStyle) {
			var style = document.defaultView.getComputedStyle(element, null);
			return style.getPropertyValue(property);

		} else {
			return null
		}
	},

	getPositionedOffset: function(element) {
		var position = { x: 0, y: 0 };
		do {
			position.y += element.offsetTop || 0;
			position.x += element.offsetLeft || 0;
			element = element.offsetParent;
			if(element) {
				if(element.tagName == 'BODY') break;
				var p = Utilities.readStyle(element, 'position');
				if(p == 'relative' || p == 'absolute') break;
			}
		} while(element);

		return position;
	},

	checkJsonError: function(data) {
		if(typeof data == "string") {
			if(new RegExp(/^{"error":"(.*)"}$/).test(data)) {
				eval('data='+data);
			}
		}
		
		if(data.error != null) {
			if($.fn.dialog) {
				var errorDialog = $("#errorDialog");
				if(errorDialog.length == 0) {
					errorDialog = $("<div id='errorDialog'>");
					$("body").append(errorDialog);
					errorDialog.dialog(
						{
							modal: true,
							resizable: true,
							autoOpen: false,
							width: 600,
							title: "An Unexpected Error Has Occurred",
							buttons: {
								"Ok": function() {
									$(this).dialog("close");
								}
							}
						}
					);
				}
				errorDialog.html(data.error);
				errorDialog.dialog("open");
			} else alert(data.error);
			return true;
		} else return false;
	}
}

String.prototype.stripHTML = function(){
    var matchTag = /<(?:.|\s)*?>/g;
    return this.replace(matchTag, "");
}

String.prototype.summarise = function(maxChars){
	if(this.length > maxChars) {
		var spaceIndex = this.lastIndexOf(' ', maxChars - 4);
		return this.substr(0, spaceIndex) + " ...";
	} else return this;
}

String.prototype.camelToSentance = function() {
	if(this == null || this.length == 0){
		return this;
	}
	
	var sentance = new String();
	for (var i = 1; i < this.Length; i++){
		var c = this.charAt(i);
		if(c == c.toLowerCase()){
			sentance += c;
		} else {
			sentance += ' ' + c.toLowerCase(c);
		}
	}
	return sentance;
}