/// <reference path="prototype.js" />
var HO = {
	Version: '1.0.1',
	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()
// 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);
	},
	
	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>
		    var objRegExp = /-?[0-9]+\.[0-9]{2}$/;

		if( objRegExp.test(this)) {
			objRegExp.compile('^-');
			var inputValue = this.addCommas();
			if (objRegExp.test(inputValue)){
				inputValue = '(' + inputValue.replace(objRegExp,'') + ')';
			}
			return '$' + inputValue;
		} 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
	//****************************
	isNumeric: function() {
	    /// <summary>dertermins if numeric string is a number</summary>
	    /// <returns>boolean</returns>
		return /^[-+]?\d+(\.\d+)?$/.test(this.trim());
	},
	
	isSignedInteger: function() {
	    /// <summary>dertermins if numeric string is a signed integer</summary>
	    /// <returns>boolean</returns>
	    return /^[-+]?\d+$/.test(this.trim());
	},
	
	isPostiveInteger: function() {
	    /// <summary>dertermins 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>dertermins if numeric string is a US Date</summary>
	    /// <returns>boolean</returns>
	    var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
	 
		//check to see if in correct format
		if(!objRegExp.test(this))
			return false; //doesn't match pattern, bad date
		else {
			var strSeparator = this.substring(2,3) //find date separator
			var arrayDate = this.split(strSeparator); //split date into month, day, year

			var arrayLookup = {
				'01' : 31, '03' : 31, '04' : 30, '05' : 31, '06' : 30,'07' : 31,
				'08' : 31, '09' : 30, '10' : 31, '11' : 30, '12' : 31
			};

			var intDay = parseInt(arrayDate[1],10); 

			//check if month value and day value agree
			if(arrayLookup[arrayDate[0]] != null) {
				if(intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
				return true;
			}
	    
			var intMonth = parseInt(arrayDate[0],10);
			if (intMonth == 2) {
				var intYear = parseInt(arrayDate[2]);
				if (intDay > 0 && intDay < 29) {
					return true;
				} else if (intDay == 29) {
					if ((intYear % 4 == 0) && (intYear % 100 != 0) || (intYear % 400 == 0)) {
						// year div by 4 and ((not div by 100) or div by 400) -> ok
						return true;
					}   
				}
			}
		}  
		return false; //any other values, bad date
	},

	isUSZipCode: function() {
	    /// <summary>dertermins 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>dertermins 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};
	}
}

