/// <reference path="prototypePacked.js" />
var HO = {
	Version: '1.0.3',
	Copyright: 'Copyright (c)HarborObjects',
	Author: 'Glenn Byron',
	prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
}

// Prototype now needs to be at least version 1.6, and this function
// does not check for release canidate 1 (rc1)
if((typeof Prototype=='undefined') || HO.prototypeVersion < 1.6)
    throw ("HO requires the Prototype JavaScript framework >= 1.6");
      
HO.isIE = navigator.appVersion.match(/MSIE/) == "MSIE";

// ************************************************
// Extend JavaScript String object
//
// The following functions have been added
// to the JavaScirpt String function.
//
// trimLeft()
// trimRight()
// trim()
// padLeft()
// padRight()
// left(n)
// right(n)
// cleanSeperators() - used to remove common seperators in phone numbers, etc.
// cleanCurrency()
// restoreCurrency()
// removeCommas() - for numbers
// addCommas() - for numbers
// restoreUSPhone()
// isNumeric()
// isSignedInteger()
// isPostiveInteger()
// isUSCurrency()
// isUSDate()
// isUSZipCode()
// isUSPhone()
// ************************************************
Object.extend(String.prototype, {
	trimLeft: function() {
		/// <summary>romoves spaces from left side</summary>
		/// <returns>string</returns>
		return this.replace(/^\s+/, '');
	},
	trimRight: function() {
		/// <summary>romoves spaces from right side</summary>
		/// <returns>string</returns>
		return this.replace(/\s+$/, '');
	},
	trim: function() {
		/// <summary>romoves spaces from both sides</summary>
		/// <returns>string</returns>
		return this.trimRight().trimLeft()
	},

	padLeft: function(chr, num) {
		/// <summary>right-aligns the characters in this instance</summary>
		/// <param name="chr">padding character</param>
		/// <param name="num">minumum width</param>
		/// <returns>string</returns>
		var re = new RegExp(".{" + num + "}$");
		var pad = "";

		do {
			pad += chr;
		} while (pad.length < num)
		return re.exec(pad + this);
	},

	padRight: function(chr, num) {
		/// <summary>left-aligns the characters in this instance</summary>
		/// <param name="chr">padding character</param>
		/// <param name="num">minumum width</param>
		/// <returns>string</returns>
		var re = new RegExp("^.{" + num + "}");
		var pad = "";

		do {
			pad += chr;
		} while (pad.length < num)
		return re.exec(this + pad);
	},

	left: function(num) {
		/// <summary>left part of the string</summary>
		/// <param name="num">number of characters</param>
		/// <returns>string</returns>
		if (num <= 0)
			return "";
		else if (num > String(this).length)
			return this;
		else
			return String(this).substring(0, num);

	},
	right: function(num) {
		/// <summary>right part of the string</summary>
		/// <param name="num">number of characters</param>
		/// <returns>string</returns>
		if (num <= 0)
			return "";
		else if (num > String(this).length)
			return this;
		else {
			var iLen = String(this).length;
			return String(this).substring(iLen, iLen - num);
		}
	},
	cleanSeperators: function() {
		/// <summary>remove common seperators in phone numbers, etc.</summary>
		/// <returns>string</returns>
		return this.replace(/[\(\)\.\-\/\s,]/g, "");
	},

	cleanCurrency: function() {
		/// <summary>removes non-numeric currency characters</summary>
		/// <returns>string</returns>
		var objRegExp = /\(/;
		var strMinus = '';

		if (objRegExp.test(this)) strMinus = '-';

		objRegExp = /\)|\(|[,]/g;
		var inputValue = this.replace(objRegExp, '');

		if (inputValue.indexOf('$') >= 0) {
			inputValue = inputValue.substring(1, inputValue.length);
		}
		return strMinus + inputValue;
	},

	restoreCurrency: function() {
		/// <summary>formats a numeric string to currency</summary>
		/// <returns>string</returns>


		if (this.isUSCurrency) {
			var inputValue = this.cleanCurrency();
			sign = (inputValue == (inputValue = Math.abs(inputValue)));
			inputValue = Math.floor(inputValue * 100 + 0.50000000001);
			cents = inputValue % 100;
			inputValue = Math.floor(inputValue / 100).toString();
			if (cents < 10) {
				cents = "0" + cents;
			}
			var inputValue = inputValue.addCommas();
			return (((sign) ? '' : '-') + '$' + inputValue + '.' + cents);

		} else
			return this;
	},

	removeCommas: function() {
		/// <summary>removes commas</summary>
		/// <returns>string</returns>
		var objRegExp = /,/g;
		return this.replace(objRegExp, '');
	},

	addCommas: function() {
		/// <summary>adds commas to numeric string</summary>
		/// <returns>string</returns>

		var inputValue = this.trim().removeCommas();
		len = inputValue.indexOf(".");
		if (len == -1) {
			len = inputValue.length;
			out = "";
		} else {
			out = inputValue.substring(len);
		}

		for (var i = 0; i < len; i++) {
			if (i != 0 && i % 3 == 0) {
				out = "," + out
			}
			out = inputValue.charAt(len - i - 1) + out
		}
		return out
	},

	restoreUSPhone: function() {
		/// <summary>formats a 10 character numeric string to a phone number format</summary>
		/// <returns>string</returns>

		if (this == '') return this;
		var n1 = this.substring(0, 3)
		var n2 = this.substring(3, 6)
		var n3 = this.substring(6, 10)
		return ("(" + n1 + ") " + n2 + "-" + n3)
	},

	//****************************
	//Check for types of things
	//****************************
	isSignedNumeric: function() {
		/// <summary>determines if numeric string is a number</summary>
		/// <returns>boolean</returns>
		return /^[-+]?\d+(\.\d+)?$/.test(this.trim());
	},

	isPositiveNumeric: function() {
		/// <summary>determines if numeric string is a number</summary>
		/// <returns>boolean</returns>
		return /^\d+(\.\d+)?$/.test(this.trim());
	},

	isSignedInteger: function() {
		/// <summary>determines if numeric string is a signed integer</summary>
		/// <returns>boolean</returns>
		return /^[-+]?\d+$/.test(this.trim());
	},

	isPostiveInteger: function() {
		/// <summary>determines if numeric string is a postive integer</summary>
		/// <returns>boolean</returns>
		return /^\d+$/.test(this.trim());
	},

	isUSCurrency: function() {
		/// <summary>if numeric string is currency format that allows optional $, optional \";-\" (MinusSignNegative) OR \"()\" (ParenNegative) but not both, optional cents, and optional commas separating thousands. Minus sign can be before or after $, but parens must be outside the $.</summary>
		/// <returns>boolean</returns>
		return /^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$/.test(this.trim());
	},

	isUSDate: function() {
		/// <summary>determines if numeric string is a US Date</summary>
		/// <returns>boolean</returns>

		var datePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{2}|\d{4})$/;
		var matchArray = this.match(datePattern);

		//Check valid format
		if (matchArray == null) { return false; }

		month = matchArray[1];
		day = matchArray[3];
		year = matchArray[5];

		// check month range
		if (month < 1 || month > 12) { return false; }

		//Check day range
		if (day < 1 || day > 31) { return false; }

		//Check months with 30 days
		if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) { return false; }

		//Check Feb days
		if (month == 2) {
			var leapYr = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
			if (day > 29 || (day > 28 && !leapYr)) { return false; }
		}

		return true;
		
	},

	isUSTime: function(checkAMPM) {

		/// <summary>determines if a string is a US time</summary>
		// Expected format is HH:MM:SS AM/PM. The seconds and AM/PM are optional.
		/// <returns>boolean</returns>

		var objRegExp = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;

		//check to see if in correct format
		if (!objRegExp.test(this))
			return false; //doesn't match pattern, bad time
		else {
			var matchArray = this.match(objRegExp);
			hour = matchArray[1];
			minute = matchArray[2];
			second = matchArray[4];
			ampm = matchArray[6];

			if (second == "") { second = null; }
			if (ampm == "") { ampm = null }

			//Hour must be between 1 and 12 or 0 and 23 for military time
			if (hour < 0 || hour > 23) {
				return false;
			}
			//must specify AM or PM
			if (hour <= 12 && ampm == null && checkAMPM == true) {
				return false;
			}
			//can't specify AM or PM for military time
			if (hour > 12 && ampm != null) {
				return false;
			}
			//Minute must be between 0 and 59
			if (minute < 0 || minute > 59) {
				return false;
			}
			//Second must be between 0 and 59
			if (second != null && (second < 0 || second > 59)) {
				return false;
			}
			return true;
		}
		return false; //any other values, bad time
	},

	isUSZipCode: function() {
		/// <summary>determines if string is a 5 digit US Zip Code</summary>
		/// <returns>boolean</returns>
		var objRegExp = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
		return objRegExp.test(this);
	},

	isUSPhone: function() {
		/// <summary>determines if string is a US phone number with area code</summary>
		/// <returns>boolean</returns>
		var cleanNumber = this.cleanSeperators();
		if ((cleanNumber.isPostiveInteger() && cleanNumber.cleanSeperators().length == 10) || cleanNumber == '') {
			return true;
		} else {
			return false;
		}
	}
}, false);

// ******************************
// Two functions to get the postion and size 
// of the current window so you can postion 
// things like windows
// 
// getPageScroll()
// getPageSize()
// ******************************
HO.WindowUtilities = {
 	getPageScroll :function() {
		var yScroll;

		if (self.pageYOffset) {
			yScroll = self.pageYOffset;
		} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
			yScroll = document.documentElement.scrollTop;
		} else if (document.body) {// all other Explorers
			yScroll = document.body.scrollTop;
		}
		return yScroll;
	},

	// getPageSize()
	// Returns properties with page width, height and window width, height
	// Core code from - quirksmode.org
	// Edit for Firefox by pHaez
	// Edit to return properties and not an array by Glenn Byron @ Dynamic Digital Media Group
	getPageSize: function(){
		var xScroll, yScroll;
	
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
	
		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
	
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}

		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = windowWidth;
		} else {
			pageWidth = xScroll;
		}
		return {pageWidth: pageWidth, pageHeight: pageHeight, windowWidth: windowWidth, windowHeight: windowHeight};
	}
}
