

/********** Cookie Functions **********/

/** retrieves expiration dates in proper format **/
function getExpirationDate(days, hours, minutes) {
	var expirationDate = new Date();
	if(typeof days == "number" && typeof hours == "number" && typeof minutes == "number") {
		expirationDate.setDate(expirationDate.getDate() + parseInt(days));
		expirationDate.setHours(expirationDate.getHours() + parseInt(hours));
		expirationDate.setMinutes(expirationDate.getMinutes() + parseInt(minutes));
		return expirationDate.toGMTString();
	} else {
		return false;
	}
}

/** called by getCookie to parse a cookie 
  * returns an integer - the offset of the name/value pair
  **/
function getCookieValue(offset) {
	var endstring = document.cookie.indexOf(";", offset);
	if(endstring == -1) {
		endstring = document.cookie.length;
	}
	return unescape(document.cookie.substring(offset, endstring));
}

/** retrieves a cookie 
  * returns a String - the cookie value 
  **/
function getCookie(name) {
	var arg = name + "=";
	var argLength = arg.length;
	var cookieLength = document.cookie.length;
	var i=0;
	while(i < cookieLength) {
		var j = i + argLength;
		if(document.cookie.substring(i,j) == arg) {
			return getCookieValue(j);
		}
		i = document.cookie.indexOf(" ",i) + 1;
		if(i==0) break;
	}
	return "";
}

/** sets a cookie 
  * returns nothing
  **/
function setCookie(name, value, expires, path, domain, secure) {
	document.cookie = name + "=" + escape(value) +
		((expires) ? "; expires=" + expires : "") +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure=" : "");
}

/** delete a cookie 
  * returns nothing
  **/
function deleteCookie(name, path, domain) {
	if(getCookie(name)) {
		document.cookie = name + "=" +
			((path) ? "; path=" + path : "") +
			((domain) ? "; domain=" + domain : "") +
			"; expires=Thu, 01-Jan-70 00:00:01 GMT";
	}
}

/** checks to see if cookies are enabled and turned on 
  * returns true or false
  **/
function cookiesEnabled() {
	var cookieEnabled = false;
	if(typeof document.cookie == "string") {
		if(document.cookie.length == 0) {
			document.cookie = "test";
			cookieEnabled = (document.cookie == "test");
			document.cookie = "";
		}
	} else {
		cookieEnabled = true;
	}
	return cookieEnabled;
}


/********** Form Functions **********/

/** clear all textfields of a form
  * returns nothing
  */
function clearTextFields() {
	var allInputs = document.getElementsByTagName("input");
	for(var i=0; i<allInputs.length; i++) {
		if(allInputs[i].type == "text") {
			allInputs[i].value = "";
		}
	}
}

/** resets all select inputs to the first choice
  * returns nothing
  */
function resetSelections() {
	var allInputs = document.getElementsByTagName("select");
	for(var i=0; i<allInputs.length; i++) {
		allInputs[i].selectedIndex = 0;
	}
}

/** sets all checkboxes on (true) or off (false)
  * bool is true to check the boxes or false to uncheck the boxes
  * returns nothing
  */
function setAllCheckboxes(bool) {
	var allInputs = document.getElementsByTagName("input");
	for(var i=0; i<allInputs.length; i++) {
		if(allInputs[i].type == "checkbox") {
			allInputs[i].checked = bool;
		}
	}
}

/** sets the focus and selects all text in the desired element of the desired form
  * formName is the name of the form
  * elementName is the name of the element
  * returns nothing
  */
function setFocus(elementName, formName) {
	var element = (elementName && formName) ? document.forms[formName].elements[elementName] : ((document.getElementById && document.getElementById(elementName)) ? document.getElementById(elementName) : '');
	element.focus();
	element.select();
}

/** sets the focus to the indicated field when the limit is reached in the current field
  * input is the name of the input field
  * next is the field to which the focus will move
  * evt is the keypress event
  * limit is the maximum number of characters is the field
  * if limit is left empty, the input field's "maxlength" attribute is used
  * Example of usage: <input type="text" name="field1" onkeyup="autoTab(this, 4, 'field2', event)">
  * In this example, when field1 contains 4 characters, it will autoTab to field2
  * returns nothing
  */
function autoTab(input, next, evt, limit) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    limit = (!limit) ? input.getAttribute("maxlength") : limit;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : ((evt.which) ? evt.which : 0));
    if (charCode > 31 && input.value.length >= limit) {
    	input.form.elements[next].focus();
    }
    
}


/********** Validation Functions **********/

/** checks to see if the parameter is a number 
  * can have a plus or minus at the beginning
  * can have a decimal point and any number of integers or decimals
  * returns true or false
  **/
function isDigit(digit) {
	digit = digit.toString();
	var re = /^[-+]?\d*\.?\d*$/;
	return (!digit.match(re)) ? false : true;
}

/** checks to see if the parameter is a valid email address 
  * with username, an @ symbol, a domain, and at least one dot after the @
  * returns true or false
  **/	
function isValidEmail(email) {
	var re = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
	return (!email.match(re)) ? false : true;
}

/** checks to see if the browser supports object detection 
  * object detection is much more reliable than browser detection
  * returns true or false
  **/
function supportsObjectDetection() {
	return (document.getElementById) ? true : false;
}

/** returns the client operating system
  * returns a String containing the OS or Unknown
  **/
function getClientOS() {
	if(navigator.userAgent.indexOf("Win") != -1) {
		return "Windows";
	} else if(navigator.userAgent.indexOf("Mac") != -1) {
		return "Macintosh";
	} else if(navigator.userAgent.indexOf("X11") != -1) {
		return "X11";
	} else {
		return "Unknown";
	}
}

/** checks to see that at least one radio button has been selected
  * radio is the radio form element
  * returns true if on is selected, false if none are selected
  **/
function radioChecked(radio) {
	var valid = false;
	for(var i = 0; i < radio.length; i++) {
		if(radio[i].checked) {
			return true;
		}
	}
	return false;
}
	
/********** Formatting Functions **********/

/** formats a number
  * num is the number to format
  * decimalPlaces is the number of decimal places
  * withCommas is a boolean to add commas or not
  * returns a String - the formatted number
  */
function formatNumber(num, decimalPlaces, withCommas) {
	num = parseFloat(stripCommas(num)); // converts strings to floats
	if(!isNaN(num)) {
		/** multiply value by 10 to the decimalPlaces power;
		  * round the result to the nearest integer;
		  * convert to a string;
		  * exponent means the value is out of range for this function
		  */
		var str = "" + Math.round(eval(num) * Math.pow(10, decimalPlaces));
		if(str.indexOf("e") != -1) {
			return "Out of Range";
		}
		
		/** for small numbers, pad zeros to the left
		  */
		while(str.length < decimalPlaces) {
			str = "0" + str;
		}

		/** find decimal position and return the assembled package
		 */
		var decimalPoint = str.length - decimalPlaces;
		
		if(withCommas) {
			return formatCommas(str.substring(0,decimalPoint)) + "." + str.substring(decimalPoint, str.length);
		} else {
			return str.substring(0,decimalPoint) + "." + str.substring(decimalPoint, str.length);
		}
	} else {
		return "NaN";
	}
}

/** formats a number string with commas
  * numString is the number to format
  * returns a String - the number with proper comma placement
  */
function formatCommas(numString) {
	var re = /(-?\d+)(\d{3})/;
	num = numString + ''; // makes sure it's a string
	while(re.test(num)) {
		num = num.replace(re, "$1,$2");
	}
	return num;
}

/** strips a number string of commas
  * numString is the number to format
  * returns a String - the number without commas
  */
function stripCommas(numString) {
	var re = /,/g;
	return numString.replace(re,"");
}

String.prototype.trim = function() {
	a = this.replace(/^\s+/, '');
	return a.replace(/\s+$/, '');
};

/********** Conversion/Math Functions **********/

/** converts a hexadecimal number to a decimal number
  * hex is the number to convert
  * returns an int - the decimal number
  */
function hexToDec(hex) {
	return parseInt(hex, 16);
}

/** converts a decimal number to a hexadecimal number
  * dec is the number to convert
  * returns a String - the hexadecimal equivalent of the decimal
  */
function decToHex(dec) {
	dec = parseInt(dec, 10);
	
	if(!isNaN(dec)) {
		if(dec > 255) {
			return "Out of Range (0-255)";
		}
		hexChars = "0123456789ABCDEF";
		var i = dec % 16;
		var j = (dec - i) / 16;
		result = "0x";
		result += hexChars.charAt(j) + hexChars.charAt(i);
		return result;
	} else {
		return "NaN";
	}
}

/** converts a binary number to a decimal number
  * bin is the number to convert
  * returns an int - the decimal number
  */
function binToDec(bin) {
	return parseInt(bin, 2);
}

/** generates a random number
  * low is the low range
  * high is the high range
  * JavaScript has no seed regen, so this is pseudo-random at best.
  * returns -1 on error
  * returns a random number on success
  */
function getRandom(high, low) {
	if(!high || !isDigit(high)) {
		return -1;
	} else {
		high = parseInt(high);
	}
	
	if(!low) {
		low = 0;
	} else if(!isDigit(low)) {
		return -1;
	} else {
		low = parseInt(low);
	}

	return Math.floor(Math.random() * (high - low + 1)) + low;
}

/**
  * Prevents users from using the contextual menu
  * use with <script>document.oncontextmenu = blockContextMenu</script> after utilities.js loads;
  * doesn't appear to work in IE Mac
  * does not prevent drag and drop of images
  */
function blockContextMenu(evt) {
    evt = (evt) ? evt : event;
    var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
    if (elem && elem.tagName && elem.tagName.toLowerCase() == "img") {
        if (evt.cancelBubble) {
            evt.cancelBubble = true;
        } else {
        	evt.preventDefault();
        	evt.stopPropagation();
        }
    } 
    return false;
}


/********** Array Functions **********/

/** sorts an array of numbers in ascending order
  * To use this call myArray.sort(compareNumbers)
  */
function compareNumbers(a, b) {
	return a-b;
}

/** sorts an array of numbers in descending order
  * To use this call myArray.sort(compareNumbersDesc)
  */
function compareNumbersDesc(a, b) {
	return b-a;
}

function compareStrings(a, b) {
	if(a < b) return -1;
	if(b < a) return 1;
	return 0;
}

function compareStringsIgnoreCase(a, b) {
	if(a.toLowerCase < b.toLowerCase) return -1;
	if(b.toLowerCase < a.toLowerCase) return 1;
	return 0;
}

function compareStringsDesc(a, b) {
	if(b < a) return -1;
	if(a < b) return 1;
	return 0;
}

function compareStringsDescIgnoreCase(a, b) {
	if(b.toLowerCase < a.toLowerCase) return -1;
	if(a.toLowerCase < b.toLowerCase) return 1;
	return 0;
}

/********** Calendar Functions **********/
function getNow() {
	return new Date();
}

function getCurrentYear() {
	var date = new Date();
	return date.getFullYear();
}

function getCurrentMonth() {
	var date = new Date();
	return date.getMonth();
}

function getCurrentDay() {
	var date = new Date();
	return date.getDate();
}

function getDayOfTheWeek(indate) {
	if(indate) {
		date = new Date(indate);
	} else {
		date = new Date();
	}
	return date.getDay();
}

function getFirstDayOfMonth(month, year) {
	var date = new Date(year, month, 1);
	return date.getDay();
}

function getMonthLength(month, year) {
	var nextMonth = new Date(year, month+1, 1);
	nextMonth.setHours(nextMonth.getHours() - 3);
	return nextMonth.getDate();
}

function getCurrentTime() {
	var date = new Date();
	return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
}


/********** Window Functions **********/

/** opens a new, fully functional window
  * url is the url to open in the window
  * name is the name of the window for future reference
  * height is the desired outside height of the window
  * width is the desired outside width of the window
  * centered is a boolean indicating whether or not to center the window
  * returns a reference to the new window
  */
function openWindow(url, name, height, width, centered) {
	var options  = "height=" + height
		options += ", width=" + width;
		options += ", menubar=1";
		options += ", status=1";
		options += ", resizeable=1";
		options += ", scrollbars=1";
		options += ", titlebar=1";
		options += ", toolbar=1";
	if(centered) {
		options += ", left=" + parseInt((screen.availWidth/2) - (width/2));
		options += ", top="  + parseInt((screen.availHeight/2) - (height/2));
	}
	return window.open(url, name, options);
}

/** opens a new, fully functional window
  * url is the url to open in the window
  * name is the name of the window for future reference
  * height is the desired outside height of the window
  * width is the desired outside width of the window
  * left is the desired left edge of the window
  * top is the desired top edge of the window
  * menubar is a boolean indicating whether or not to enable the menubar
  * status is a boolean indicating whether or not to enable the status area
  * resizeable is a boolean indicating whether or not to allow the user to resize the window
  * scrollbars is a boolean indicating whether or not to enable the scrollbars if necessary
  * titlebar is a boolean indicating whether or not to enable the titlebar
  * toolbar is a boolean indicating whether or not to enable the toolbar
  * returns a reference to the new window
  */
function openCustomWindow(url, name, height, width, left, top, menubar, status, resizeable, scrollbars, titlebar, toolbar) {
	var options  = "height=" + height
		options += ", width=" + width;
		options += ", left=" + left;
		options += ", top="  + top;
		options += ", menubar=" + menubar;
		options += ", status=" + status;
		options += ", resizeable=" + resizeable;
		options += ", scrollbars=" + scrollbars;
		options += ", titlebar=" + titlebar;
		options += ", toolbar=" + toolbar;
	return window.open(url, name, options);
}

/** breaks frames if the window is opened in a frame
  *
  */
function breakFrames() {
	if(top != self) {
		top.location.href = location.href;
	}
}

function getPageEventCoords(evt) {
	var coords = {left:0, top:0};
	evt = (evt) ? evt : ((window.event) ? event : null);
	if(evt.pageX) {
		coords.left = evt.pageX;
		coords.top = evt.pageY;
	} else if(evt.clientX) {
		coords.left = evt.clientX + document.body.scrollLeft - document.body.clientLeft;
		coords.top = evt.clientY + document.body.scrollTop - document.body.clientTop;
		if(document.body.parentElement && document.body.parentElement.clientLeft) {
			var bodParent = document.body.parentElement;
			coords.left += bodParent.scrollLeft - bodParent.clientLeft;
			coords.top  += bodParent.scrollTop  - bodParent.clientTop;
		}
	}
	return coords;
}

function getPositionedEventCoords(evt) {
	evt = (evt) ? evt : ((window.event) ? event : null);
	//var elem = (evt.target) ? evt.target : evt.srcElement;
	var coords = {left:0, top:0};
	if(evt.layerX) {
		var borders = {left:parseInt(getElementByStyle("posButton", "borderLeftWidth", "border-left-width")),
						top:parseInt(getElementByStyle("posButton", "borderTopWidth",  "border-top-width"))};
		coords.left = evt.layerX - borders.left;
		coords.top  = evt.layerY - borders.top;
	} else if(evt.offsetX) {
		coords.left = evt.offsetX;
		coords.top  = evt.offsetY;
	}
	evt.cancelBubble = true;
	return coords;
}

function getElementByStyle(elemID, IEStyleAttr, CSSStyleAttr) {
	var elem = document.getElementById(elemID);
	if(elem && elem.currentStyle) {
		return elem.currentStyle[IEStyleAttr];
	} else if(window.getComputedStyle) {
		var compStyle = window.getComputedStyle(elem, "");
		return compStyle.getPropertyValue(CSSStyleAttr);
	}
	return "";
}

function setScreenResolutionCookie() {
	setCookie('screen_resolution', screen.width+"x"+screen.height, getExpirationDate(360, 1, 1));
}

function checkScreenResolution(width,height) {
	if(width != screen.width || height != screen.height) {
		setScreenResolutionCookie();
	}
}

/********** Navigation Functions **********/
/** Navigate to a url in a select box
  * choice is the form element chosen
  * Example: <select name="chooser" id="chooser" onchange="navigate(this)">...</select>
  */
function navigate(choice) {
	var url = choice.options[choice.selectedIndex].value;
	if(url) {
		location.href = url;
	}
}


/********** CSS Functions **********/
function toggleLayer(myLayer) {
	if(document.getElementById) {
		var myStyle = (document.getElementById(myLayer))?document.getElementById(myLayer).style:false;
		myStyle.display = myStyle.display?"":"block";
	} else if(document.all) {
		var myStyle = document.all[myLayer].style;
		myStyle.display = myStyle.display?"":"block";
	} else if(document.myLayers) {
		var myStyle = document.layers[myLayer].style;
		myStyle.display = myStyle.display?"":"block";
	}
}

		
