//Browser extensions
/*
$extend(Browser,{
	 getHost : function(url){return new URI(url).get('host');}
	,getQueryStringValue : function(key, url){return new URI(url).getData(key);}
	,getQueryStringValues : function(url){return new URI(url).getData();}
	,getPort : function(url){return new URI(url).get('port');}
	});
*/
//Date extensions
Date.implement({
	dateFormat : function () {
		return this.format('%m/%d/%Y');
		//intDt = this.getDate();
		//intMn = this.getMonth();
		//intYr = this.getFullYear();
		//return intMn + '/' + intDt + '/' + intYr;
		}
	});
//Number extensions
Number.implement({
	 numberFormat : function (decimals, dec_point, thousands_sep) {
	 	return this.format({
	 		 'decimal':dec_point
	 		,'group':thousands_sep
	 		,'decimals':decimals
	 		});
		//decimals = Math.abs(decimals) + 1 ? decimals : 2;
		//dec_point = dec_point || '.';
		//thousands_sep = thousands_sep || ',';
		//var matches = /(-)?(\d+)(\.\d+)?/.exec((isNaN(this) ? 0 : this) + '');
		//var remainder = matches[2].length > 3 ? matches[2].length % 3 : 0;
		//return (matches[1] ? matches[1] : '') + (remainder ? matches[2].substr(0, remainder) + thousands_sep : '') + matches[2].substr(remainder).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep) + (decimals ? dec_point + (+matches[3] || 0).toFixed(decimals).substr(2) : '');
		}
	,formatPercent : function () {
		return this.formatPercentage();
		//var threeDec = new String((this * 100).toFixed(3).toFloat().numberFormat(3) + '%');
		//while (threeDec.indexOf("0%") > 0) threeDec = threeDec.replace("0%", "%");
		//return threeDec.replace(".%", "%");
		}
	,formatCurrency : function () {
		return "$" + this.toFixed(2).toFloat().numberFormat();
		}
	});
//String extensions
String.implement({
	 strip : function () {
		arrChars = this.clean().split("");
		arrChars.each(function(item,indx,arr){if (isNaN(item) || item == ' ') arr[indx] = '';});
		return arrChars.join("");
		}
	,formatPhone : function () {
		strResult = "";
		this.strip().split("").each(function(item,indx,arr){
			if (indx == 0) strResult += "(";
			if (indx == 3) strResult += ") ";
			if (indx == 6) strResult += "-";
			strResult += item;
			});
		return strResult;
		}
	,formatSSN : function () {
		strResult = "";
		this.strip().split("").each(function(item,indx,arr){
			if (indx == 3) strResult += "-";
			if (indx == 5) strResult += "-";
			strResult += item;
			});
		return strResult;
		}
	,formatEIN : function () {
		strResult = "";
		this.strip().split("").each(function(item,indx,arr){
			if (indx == 2) strResult += "-";
			strResult += item;
			});
		return strResult;
		}
	,right : function (len) {
		if (len <= 0) return "";
		else if (len > this.length) return this;
		else {
			var iLen = this.length;
			return this.substring(iLen, iLen - len);
			}
		}
	,left : function (len) {
		if (len <= 0) return "";
        else if (len > this.length) return this;
        else return this.substring(0, len);
		}
	,mid : function (start, len) {
        if (start < 0 || len < 0) return "";
		else {
	        var iEnd;
	        var iLen = this.length;
	        if (start + len > iLen) iEnd = iLen;
	        else iEnd = start + len;
	        return this.substring(start, iEnd);
	        }
		}
	,isDate : function () {
		var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
		var matchArray = this.match(datePat);
		if (matchArray == null) return false;
		month = matchArray[1];
		day = matchArray[3];
		year = matchArray[5];
		if (month < 1 || month > 12) return false;
		if (day < 1 || day > 31) return false;
		if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) return false;
		if (month == 2) {
			var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
			if (day > 29 || (day == 29 && !isleap)) return false;
			}
		return true;
		}
	});
//DOM extensions
Element.implement({
	 sumOfChildrenWidths : function (tag) {
		intChildWidthSum = 0;
		arrChildren = this.getChildren(tag);
		al = arrChildren.length;
		for (n = 0; n < al; n++) {
			if (arrChildren[n].getStyle("display") != "none") {
				if (arrChildren[n].getSize().x > 0) intChildWidthSum += arrChildren[n].getSize().x;
				else if (arrChildren[n].getStyle('width').toInt() > 0) intChildWidthSum += arrChildren[n].getStyle('width').toInt();
				else if (arrChildren[n].getProperties('width').width != null) intChildWidthSum += arrChildren[n].getProperty('width').toInt();
				}
			}
		return intChildWidthSum;
		}
	,sumOfChildrenHeights : function (tag) {
		intChildHeightSum = 0;
		arrChildren = this.getChildren(tag);
		al = arrChildren.length;
		for (n = 0; n < al; n++) {
			if (arrChildren[n].getStyle("display") != "none") {
				if (arrChildren[n].getSize().y > 0) intChildHeightSum += arrChildren[n].getSize().y;
				else if (arrChildren[n].getStyle('height').toInt() > 0) intChildHeightSum += arrChildren[n].getStyle('height').toInt();
				else if (arrChildren[n].getProperties('height').height != null) intChildHeightSum += arrChildren[n].getProperty('height').toInt();
				}
			}
		return intChildHeightSum;
		}
	,maxOfChildrenWidths : function (tag) {
		intChildWidthMax = 0;
		arrChildren = this.getChildren(tag);
		al = arrChildren.length;
		for (n = 0; n < al; n++) {
			if (arrChildren[n].getStyle("display") != "none") {
				if (arrChildren[n].getSize().x > 0) { if (arrChildren[n].getSize().x > intChildWidthMax) intChildWidthMax = arrChildren[n].getSize().x; }
				else if (arrChildren[n].getStyle('width').toInt() > intChildWidthMax) { intChildWidthMax = arrChildren[n].getStyle('width').toInt(); }
				else if (arrChildren[n].getProperties('width').width.toInt() > intChildWidthMax) { intChildWidthMax = arrChildren[n].getProperty('width').toInt(); }
				}
			}
		return intChildWidthMax;
		}
	,maxOfChildrenHeights : function (tag) {
		intChildHeightMax = 0;
		arrChildren = this.getChildren(tag);
		al = arrChildren.length;
		for (n = 0; n < al; n++) {
			if (arrChildren[n].getStyle("display") != "none") {
				if (arrChildren[n].getSize().y > 0) { if (arrChildren[n].getSize().y > intChildHeightMax) intChildHeightMax = arrChildren[n].getSize().y; }
				else if (arrChildren[n].getStyle('height').toInt() > intChildHeightMax) { intChildHeightMax = arrChildren[n].getStyle('height').toInt(); }
				else if (arrChildren[n].getProperties('height').height.toInt() > intChildHeightMax) { intChildHeightMax = arrChildren[n].getProperty('height').toInt(); }
				}
			}
		return intChildHeightMax;
		}
	});
//Form.Validator extensions
Form.Validator.add("validate-integer-allow-zero", {
	 errorMsg: "Please enter an integer in this field."
	,test: function (field) {
		if (field.value == "") return true;
		else return (field.value == field.value.strip());
		}
	});
Form.Validator.add("validate-one-checked-by-parent", {
	 errorMsg: "You must provide a selection for one of the items above."
	,test: function (field) {
		arrElemClasses = field.className.split(" ");
		al = arrElemClasses.length;
		for (c = 0; c < al; c++) {
			if (arrElemClasses[c].left(8) == "parentID") {
				var parentID = arrElemClasses[c].substr(9);
				}
			}
		blnReturn = false;
		$$('#'+parentID+' input[type=radio]').each(function(el){if (el.checked) blnReturn = true;});
		return blnReturn;
		}
	});
Form.Validator.add("validate-companion", {
	 errorMsg: "You must also enter a "
	,test: function (field) {
		arrElemClasses = field.className.split(" ");
		al = arrElemClasses.length;
		for (c = 0; c < al; c++) {
			if (arrElemClasses[c].left(11) == "companionID") {
				var companionID = arrElemClasses[c].substr(12);
				}
			}
		if ($(companionID).value == "") {
			al = arrElemClasses.length
			for (c = 0; c < al; c++) {
				if (arrElemClasses[c].substr(0, 13) == "companionText") {
					companionText = arrElemClasses[c].substr(14);
					}
				}
			}
		if (companionText != "") {
			this.errorMsg += companionText.replace(/%20/g, " ") + ".";
			return false;
			}
		else return true;
		}
	});
Form.Validator.add("validate-words", {
	 errorMsg: "Numbers are not permitted within this field."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			reNums = /[\d]/;
			return !reNums.test(field.value);
			}
		}
	});
Form.Validator.add("validate-expiry", {
	 errorMsg: "The expiration date provided is not valid."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			arrElemClasses = field.className.split(" ");
			al = arrElemClasses.length;
			for (c = 0; c < al; c++) {
				if (arrElemClasses[c].left(5) == "month") {
					var monthID = arrElemClasses[c].substr(6);
					}
				}
			for (c = 0; c < al; c++) {
				if (arrElemClasses[c].left(4) == "year") {
					var yearID = arrElemClasses[c].substr(5);
					}
				}
			if ($(monthID).selectedIndex > 0 && $(yearID).selectedIndex > 0) {
				var cDate = new Date();
				var xDate = new Date(($(monthID).selectedIndex) + '/1/' + ($(yearID).options[$(yearID).selectedIndex].value));
				if (xDate < cDate) return false;
				else return true;
				}
			else if ($(monthID).hasFocus() || $(yearID).hasFocus()) return true;
			else return false;
			}
		}
	});
Form.Validator.add("validate-atleastonealpha", {
	 errorMsg: "At least one letter is required."
	,test: function (field) {
		if (field.value == "") return true;
		else return isNaN(field.value);
		}
	});
Form.Validator.add("validate-atleastonenumeric", {
	 errorMsg: "At least one numeral is required."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			var arrInts = ('0,1,2,3,4,5,6,7,8,9').split(',');
			for (x = 0; x < arrInts.length; x++) {
				if (field.value.indexOf(arrInts[x]) > -1) return true;
				}
			return false;
			}
		}
	});
Form.Validator.add("validate-nomatch", {
	errorMsg: "This field cannot match the "
	,test: function(field){
		arrElemClasses = field.className.split(" ");
		al = arrElemClasses.length;
		for (c = 0; c < al; c++) {
			if (arrElemClasses[c].left(10) == "matchInput") {
				var matchID = arrElemClasses[c].substr(11);
				}
			}
		if (field.value == $(matchID).value) {
			for (c = 0; c < al; c++) {
				if (arrElemClasses[c].left(9) == "matchName") {
					var matchText = arrElemClasses[c].substr(10);
					}
				}
			this.errorMsg += (matchText + ".").replace("%20", " ");
			return false;
			}
		else return true;
		}
	});
Form.Validator.add("validate-zip-usa", {
	 errorMsg: "Enter a properly formatted, 5-digit United States zip code."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			var usZip = /^\d{5}$/i;
			return usZip.test(field.value);
			}
		}
	});
Form.Validator.add("validate-zip-canada", {
	 errorMsg: "Enter a properly formatted Canadian zip code."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			var caZip = /^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$/i;
			return caZip.test(field.value);
			}
		}
	});
Form.Validator.add("validate-ssn", {
	 errorMsg: "Enter your 9-digit Social Security Number."
	,test: function (field) {
		if (field.value != "") {
			var reSSN = /^\d{3}\-\d{2}\-\d{4}$/;
			return reSSN.test(field.value.formatSSN());
			}
		else return true;
		}
	});
Form.Validator.add("validate-ein", {
	 errorMsg: "Enter your 9-digit Employer Identification Number."
	,test: function (field) {
		if (field.value != "") {
			var reEIN = /^\d{2}\-\d{7}$/;
			return reEIN.test(field.value.formatEIN());
			}
		else return true;
		}
	});
Form.Validator.add("validate-phone", {
	 errorMsg: "Enter a 10-digit phone number."
	,test: function (field) {
		if (field.value != "") {
			var rePhone = /^\(\d{3}\)\s\d{3}\-\d{4}$/;
			return rePhone.test(field.value.formatPhone());
			}
		else return true;
		}
	});
Form.Validator.add("validate-numerals", {
	 errorMsg: "Enter a number."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			arrElemClasses = field.className.split(" ");
			for (c = 0; c < arrElemClasses.length; c++) {
				if (arrElemClasses[c].substr(0, 9) == "numLength") var requiredNumeralCount = arrElemClasses[c].substr(10).toInt();
				}
			if (isNaN(requiredNumeralCount) || field.value == "") return true;
			else this.errorMsg = "Enter a " + requiredNumeralCount + "-digit number.";
			if (field.value.strip().length == requiredNumeralCount) return true;
			else return false;
			}
		}
	});
Form.Validator.add("validate-usernameavailable", {
	//make sure that the username is available
	 errorMsg: "The name entered is already in use. Please try a different name."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			var objAvailCheck = new Request({
				 url : window.location.protocol + "//" + window.location.hostname + "/_scripts/checkUsernameAvailability.asp"
				,async : false
				,method : "post"
				,headers : {"Content-Type" : "application/x-www-form-urlencoded"}
				,result : false
				,onSuccess : function (rT, rX) { this.result = eval(rT) }
				})
			objAvailCheck.send("login=" + field.value);
			return objAvailCheck.result;
			}
		}
	});
Form.Validator.add("validate-emailavailable", {
	//make sure that the email address is not already registered
	 errorMsg: "The email address entered is already registered. Please use a different one."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			var objAvailCheck = new Request({
				 url : window.location.protocol + "//" + window.location.hostname + "/_scripts/checkEmailAvailability.asp"
				,async : false
				,method : "post"
				,headers : {"Content-Type" : "application/x-www-form-urlencoded"}
				,result : false
				,onSuccess : function (rT, rX) { this.result = eval(rT) }
				})
			objAvailCheck.send("email=" + field.value);
			return objAvailCheck.result;
			}
		}
	});
Form.Validator.add("validate-sponsorid", {
	//make sure that the email address is not already registered
	 errorMsg: "The promo number you entered is not valid. Please check the number."
	,test: function (field) {
		if (field.value == "") return true;
		else {
			arrElemClasses = field.className.split(" ");
			al = arrElemClasses.length;
			for (c = 0; c < al; c++) {
				if (arrElemClasses[c].substr(0, 2) == "cp") var compPlanID = arrElemClasses[c].substr(3);
				}
			var objAvailCheck = new Request({
				 url : window.location.protocol + "//" + window.location.hostname + "/_scripts/checkSponsorID.asp"
				,async : false
				,method : "post"
				,headers : {"Content-Type" : "application/x-www-form-urlencoded"}
				,result : false
				,onSuccess : function (rT, rX) { this.result = eval(rT) }
				})
			objAvailCheck.send("s=" + field.value + "&cp=" + compPlanID);
			return objAvailCheck.result;
			}
		}
	});
Form.Validator.add("validate-login", {
	//loginnames can only contain a-z, 0-9, dashes and underscores
	 errorMsg: "Usernames only contain a-z, 0-9, hyphens and underscores."
	,test: function (field) {
		if (field.value != "") {
			var reLogin = /[a-zA-Z0-9\-\_]/;
			return reLogin.test(field.value);
			}
		else return true;
		}
	});
Form.Validator.add("validate-future-date", {
	//verify the input is a date and is in the future
	 errorMsg: "The date entered must be a future date."
	,test: function(field){
		if (field.value == "") return true;
		else {
			if (field.value.isDate()) {
				var fvd = new Date(field.value);
				var tdy = new Date();
				if (fvd > tdy) return true;
				else return false;
				}
			else return false;
			}
		}
	});
//Patch MooTools Request.HTML for WebKit
Request.HTML.implement({
	processHTML: function(text){
		var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
		text = (match) ? match[1] : text;
		var container = new Element('div');
		return $try(function(){
			var root = '<root>' + text + '</root>', doc;
			if (Browser.ie){
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = false;
				doc.loadXML(root);
				}
			else doc = new DOMParser().parseFromString(root, 'text/html');
			root = doc.getElementsByTagName('root')[0];
			for (var i = 0, k = root.childNodes.length; i < k; i++){
				var child = Element.clone(root.childNodes[i], true, true);
				if (child) container.grab(child);
				}
			return container;
			}) || container.set('html', text);
		}
	});

