/**
 * @author Nick Verbeck <nick@activewebsite.com>
 * @since 10/13/2008
 */
jUtilities = {
	Version: 0.1
}
jUtilities.Eval = {
	isAlien: function(a) {return this.isObject(a) && typeof a.constructor != 'function';},
	isArray: function(a) {return this.isObject(a) && a.constructor == Array;},
	isBoolean: function(a) {return typeof a == 'boolean';},
	isEmpty: function(o) {
		var i, v;
		if (this.isObject(o)) {for (i in o) {v = o[i];if (this.isUndefined(v) && this.isFunction(v)) {return false;}}}
		return true;
	},
	isFunction: function(a) {return typeof a == 'function';},
	isNull: function(a) {return a === null;},
	isNumber: function(a) {a = Number(a); return typeof a == 'number';/* && this.isFinite(a); */},
	isObject: function(a) {return (a && typeof a == 'object') || this.isFunction(a);},
	isString: function(a) {return typeof a == 'string';},
	isUndefined: function(a) {return typeof a == 'undefined';},
	isEmail: function(a) {var tester = new RegExp("^[\\w-_\.]*[\\w-_\.]\@[\\w]\.+[\\w]+[\\w]$"); return tester.test(a);}
}
$E = jUtilities.Eval;

jUtilities.Graphics = {
	getAbsolutePosition: function(el) {
		var SL = 0, ST = 0;
		var is_div = /^div$/i.test(el.tagName);
		if (is_div && el.scrollLeft) {SL = el.scrollLeft;}
		if (is_div && el.scrollTop) {ST = el.scrollTop;}
		var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
		if (el.offsetParent) {var tmp = jUtilities.Graphics.getAbsolutePosition(el.offsetParent); r.x += tmp.x; r.y += tmp.y;}
		return r;
	}
}
$G = jUtilities.Graphics;
$GetAbsPos = jUtilities.Graphics.getAbsolutePosition;

jUtilities.Date = {}
jUtilities.Date.dateToStr = function(date, stringFormat){
	var stringFormat = format.toArray();
	var date = this.date;
	returnStr = "";

	for(i=0; i<stringFormat.length; i++){
		str = stringFormat[i];

		switch(str){
			case "H":
				returnStr += jUtilities.Date.addLeading(date.getHours());
				break;
			case "h":
				returnStr += jUtilities.Date.addLeading(jUtilities.Date.get12Hour(date.getHours()));
				break;
			case "g":
				returnStr += jUtilities.Date.get12Hour(date.getHours());
				break;
			case "G":
				returnStr += date.getHours();
				break;
			case "a":
				returnStr += jUtilities.Date.getMeridiem(date.getHours());
				break;
			case "A":
				returnStr += String(jUtilities.Date.getMeridiem(date.getHours())).toUpperCase();
				break;
			case "i":
				returnStr += jUtilities.Date.addLeading(date.getMinutes());
				break;
			case "Y":
				returnStr += date.getFullYear();
				break;
			case "d":
				returnStr += jUtilities.Date.addLeading(date.getDate());
				break;
			case "D":
				returnStr += jUtilities.Date.get3Day(date.getDay());
				break;
			case "m":
				returnStr += jUtilities.Date.addLeading((date.getMonth()+1));
				break;
			case "M":
				returnStr += jUtilities.Date.get3Month(date.getMonth());
				break;
			case "n":
				returnStr += (date.getMonth()+1);
				break;
			default:
				returnStr += str;
		}
	}

	return String(returnStr);
}
jUtilities.Date.addLeading = function(time){
	if (String(time).length <= 1) {time = "0" + time;}
	return time;
}
jUtilities.Date.get12Hour = function(hour){
	if(hour == 0){hour = 12;}
	if(hour > 12){hour = hour-12;}
	return hour;
}
jUtilities.Date.getMeridiem = function(hour){
	var mer = "";
	if (hour >= 0 && hour <= 11) {mer = "am";}else {mer = "pm";}
	return mer;
}
jUtilities.Date.get3Day = function(day){
	var week = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
	return week[day];
}
jUtilities.Date.get3Month = function(month){
	var year = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	return year[month];
}
jUtilities.Date.getMonthFrom3 = function(month){
	var year = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	return year.indexOf(month);
}
jUtilities.Date.strToDate = function(string, format){
	format = format.toArray();
	var place = 0;
	var date = new Date();
	var year = '';
	var month = '';
	var day = '';
	var hour = '';
	var minute = '';
	var sec = '';
	var am = '';
	for(i=0; i<format.length; i++){
		switch(format[i]){
			case "y":
				year += string.substr(place,1);
				place++;
				break;
			case "m":
				month += string.substr(place,1);
				place++;
				break;
			case "d":
				if(string.substr(place,1) != ' '){
					day += string.substr(place,1);
					place++;
				}
				break;
			case "h":
				hour += string.substr(place,1);
				place++;
				break;
			case "i":
				minute += string.substr(place,1);
				place++;
				break;
			case "s":
				sec += string.substr(place,1);
				place++;
				break;
			case 'a':
				am += string.substr(place,2);
				place += 2;
				break;
			default:
				place++;
		}
	}
	if (minute != '') {date.setMinutes(minute);}
	if (sec != '') {date.setSeconds(sec);}
	if(am == 'pm' || am == 'PM'){date.setHours(hour+12);}
	else if (am == 'am' || am == 'AM') {date.setHours(hour);}
	else {date.setHours(hour);}
	if(month != ''){
		if(jUtilities.Eval.isNumber(month)){date.setMonth(Number(month) -1);} 
		else {date.setMonth(jUtilities.Date.getMonthFrom3(month));}
	}
	if (day != '') {date.setDate(day);}
	if (year != '') {date.setYear(year);}
	return date;
}
$Date = jUtilities.Date;

/**
 * StringBuilder Class
 * 
 * Assemables a string faster
 * 
 * From K. Collins http://www.codeproject.com/KB/scripting/stringbuilder.aspx
 * 
 * @author K. Collins
 * @since 6/13/2008
 * @param {Object} value
 */
function StringBuilder(value){this.strings = new Array("");this.append(value);}
StringBuilder.prototype.append = function (value){if (value){this.strings.push(value);}}
StringBuilder.prototype.clear = function (){this.strings.length = 1;}
StringBuilder.prototype.toString = function (){return this.strings.join("");}

$WKT = function(collection){
	collection = $A(collection);
	if(collection.length > 1){
		WKT = 'POLYGON((';
	} else {
		WKT = 'POINT(';
	}
	count = false;
	collection.each(
		function(iter){
			if(count){
				WKT += ','+ iter.Longitude +' '+ iter.Latitude;
			} else {
				WKT += iter.Longitude +' '+ iter.Latitude;
				count = true;
			}
		}
	);
	if(collection.length > 1){
		WKT += ','+ collection[0].Longitude +' '+ collection[0].Latitude;
	}
	
	if(collection.length > 1){
		WKT += '))';
	} else {
		WKT += ')';
	}
	return WKT;
}

$RWKT = function(wkt){
	//var testPattern = /^(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+$/; //Test Pattern
	var getPattern = '^(POINT|POLYGON)[\(]+([^\)]+)[\)]+$'; //Get Points Pattern
	var reg = new RegExp(getPattern, 'g');
	reg.compile(getPattern, 'g');
	var matches = reg.exec(wkt);
	try{
		if(matches[2]){
			var points = matches[2].split(',');
			var shape = new Array();
			for(var i = 0; i<points.length; i++){
				var temp = points[i].split(' ');
				shape.push({
					Latitude: temp[1],
					Longitude: temp[0]
				});
			}
			return shape;
		} else {
			return false;
		}
	} catch(e){
		return false;
	}
}

Number.prototype.addCommas = function(){
	nStr = this;
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {x1 = x1.replace(rgx, '$1' + ',' + '$2');}
	return x1 + x2;
}
Number.prototype.precisionRound = function(precision) {
	if (precision==null) precision = 2;
	var factor = Math.pow(10,precision);
	return Math.round(this * factor) / factor
};
String.prototype.toProperCase = function(){return this.toLowerCase().replace(/\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1);})}
String.prototype.toDate = function(format){return jUtilities.Date.strToDate(this, format);}
String.prototype.trim = function() {return this.replace(/^\s+|\s+$/g,"");}
String.prototype.ltrim = function() {return this.replace(/^\s+/,"");}
String.prototype.rtrim = function() {return this.replace(/\s+$/,"");}
Date.prototype.toStr = function(format){return jUtilities.Date.dateToStr(this, format);}
Array.prototype.ksort = function() {
	var nArr = new Array();
	var tArr = new Array();
	for(i in this){tArr.push(i);}
	tArr = tArr.sort();
	for(i in tArr){nArr[tArr[i]] = this[tArr[i]];}
	return nArr;
}

Element.addMethods({
	isVisible: function(element, depth){
		if(depth == null){depth = 0;}
		if(depth > 10){return true;}
		element = $(element);
		if(element == document.body){
			return true;
		} else if(!element.visible()){
			return false;
		} else {
			return $(element.parentNode).isVisible(depth+1);
		}
	},
	appendChildChain: function(el, child){
		el.appendChild(child);
		return el;
	}
});
