/**
 * @package 
 * @author {@link mailto:ss@toolboxstudios.com Steve Simons, Toolbox Studios, Inc.}
 * @license http://toolboxstudios.com Contact about usage
 * @revision $Revision: 1.20 $
 * @copyright Copyright 2008
**/


function format_text(str) {
	if (str.toString != null)
		str = str.toString();
	return str.replace(/(^ +| +$)/g,'');
}
function format_string(str) {
	return format_text(str);
}
function field_text(obj) {
	if (obj && obj.type && (obj.type == 'text' || obj.type == 'textarea'))
		obj.value = format_text(obj.value);
}
function field_string(obj) {
	field_text(obj);
}



function format_date(str) {
	var result = '';
	str = format_text(str);
	if (str.length>0) {
		var curDate = new Date();
		var dateparts = (str.replace(/[^0-9]+/g,'-') + '---').split('-');
		if (dateparts[1].length == 0) {
			dateparts[1] = dateparts[0];
			dateparts[0] = '';
		}
		var Mth = parseInt(dateparts[0].replace(/^0+/,''));
		if (isNaN(Mth) || Mth<1 || Mth>12)
			Mth = curDate.getMonth() + 1;
		var Day = parseInt(dateparts[1].replace(/^0+/,''));
		if (isNaN(Day) || Day<1 || Day>31)
			Day = curDate.getDay();
		var Year = parseInt(dateparts[2].replace(/^0+/,''));
		if (isNaN(Year))
			Year = curDate.getFullYear();
		if (Year<1000)
			Year+= 2000;
		result = (Mth<10 ? '0' + Mth : Mth) + '/' + (Day<10 ? '0' + Day : Day) + '/' + Year;
	}
	return result;
}

function field_date(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_date(obj.value);
}



function format_hoursMinutesSeconds(str) {
	str = format_text(str);
	var cln = str.replace(/[^0-9:]/g,"") + '::';
	var parts = new Array();
	var part;
	while (parts.length<3) {
		part = (cln.indexOf(':')>0 ? cln.substr(0,cln.indexOf(':')) : '0');
		cln = cln.replace(/^[^:]*:(.*)$/,'$1');
		parts[parts.length] = parseInt(part.replace(/^0*([0-9]+)$/,'$1'));
	}
	var hrs = parts[0];
	var mins = parts[1];
	var secs = parts[2];
	if (secs>59) {
		mins += Math.floor(secs/60);
		secs %= 60;
	}
	if (mins>59) {
		hrs += Math.floor(mins/60);
		mins %= 60;
	}
	var result = hrs.toString();
	result += ':' + (mins<10 ? '0' : '') + mins.toString();
	result += ':' + (secs<10 ? '0' : '') + secs.toString();
	return result;
}

function field_hoursMinutesSeconds(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_hoursMinutesSeconds;
}



function format_time(timestr) {
	var result = '';
	timestr = format_text(timestr);
	if (timestr.length>0) {
		var curDate = new Date();
		var timeparts = timestr.replace(/([^0-9]+)/g, " ").split(' ');
		var hours = parseInt(timeparts[0].replace(/^0+/,''));
		var mins = (timeparts[1] ? parseInt(timeparts[1].replace(/^0+/,'')) : 0);
		var ampm = timestr.replace(/([^aApP]+)/g,"");
		if (isNaN(hours) || hours > 24 || hours < 0) {
			hours = curDate.getHours();
			ampm = '';
		}
		if (isNaN(mins) || mins > 59 || mins < 0) {
			mins = 0; // curDate.getMinutes();
		}
		if (hours > 12) {
			ampm = 'P';
			hours = hours % 12;
		}
		else {
			if ((ampm.length == 0 || !ampm.match('[aA]')) && (hours < 7 || hours == 12)) 
				ampm = 'P';
		}
		if (hours == 0) 
			hours = 12;
		ampm = (ampm.match('[Pp]') ? 'PM' : 'AM');
		var hr = '00' + hours;
		var mn = '00' + mins;
		result = hr.substring(hr.length - 2,hr.length) + ':' + mn.substring(mn.length - 2,mn.length) + ' ' + ampm;
	}
	return result;
}

function field_time(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_time(obj.value);
}



function format_datetime(datetime) {
	datetime = format_text(datetime);
	var result = datetime.replace(/^[ ]+/,'');
	var fw = datetime.indexOf(' ');
	result = (fw>0
			? format_date(result.substring(0,fw)) + ' ' + format_time(result.substring(fw+1,result.length))
			: format_date(result)
		);
	return result;
}

function field_datetime(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_datetime(obj.value);
}



function format_decimal(str,decimals) {
	str = format_text(str);
	if (typeof decimals == 'string') 
		decimals = parseInt(decimals);
	if (decimals == undefined || isNaN(decimals) || decimals < 0 || decimals > 5) 
		decimals = 0;
	var multi = Math.pow(10,decimals);
	var value = Math.floor(parseFloat('0' + str.replace(/[^0-9\.]/g,'')) * multi + 0.5);
	var frac = '00000' + (value % multi);
	var intval = Math.floor(value / multi).toString();
	for (var c = intval.length - 3;c>0;c -= 3) 
		intval = intval.substring(0,c) + ',' + intval.substring(c,intval.length);
	return (str.match(/^-.*/) ? '-' : '') + intval + (decimals>0 ? '.' : '') + frac.substring(frac.length-decimals,frac.length);
}

function field_decimal(obj,decimals) {
	if (typeof decimals == 'string') 
		decimals = parseInt(decimals);
	if (decimals == undefined || isNaN(decimals) || decimals < 0 || decimals > 5) 
		decimals = 0;
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_decimal(obj.value,decimals);
}



function format_number(str) {
	return str.replace(/[^0-9]/g,'');
}

function field_number(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_number(obj.value);
}



function format_dollar(amount,decimals) {
	if (typeof decimals == 'string') 
		decimals = parseInt(decimals);
	if (decimals == undefined || isNaN(decimals) || decimals < 0 || decimals > 5) 
		decimals = 2;
	return format_decimal(amount,decimals);
}
function format_currency(amount,decimals) {
	return format_dollar(amount,decimals);
}

function field_dollar(obj,decimals) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_dollar(obj.value,decimals);
}
function field_formatdollar(obj,decimals) {
	field_dollar(obj,decimals);
}
function field_currency(obj,decimals) {
	field_dollar(obj,decimals);
}



function format_phone(str) {
	str = format_text(str);
	return str.replace(/[^0-9\(\)/-]/g,'');
}

function field_phone(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_phone(obj.value);
}


function format_email(address) {
	address = format_text(address);
	return format_text(address);
}
function valid_email(address) {
	address = format_text(address);
	return (address.search(/^[a-z0-9'"\._-]+@([a-z][a-z0-9_-]+\.)+[a-z_-]+$/i) != -1);
}
function valid_emailaddress(address) {
	return valid_email(address);
}
function validate_email(obj,errmsg) {
	obj.value = obj.value.replace(/^ +/,'').replace(/ +$/,'');
	var result = valid_email(obj.value);
	if (obj.value.length>0 && !valid_email(obj.value)) {
		alert(errmsg);
		obj.select();
		obj.focus();
	}
}
function field_email(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_email(obj.value);
}



function format_url(url) {
	url = format_text(url);
	return (url.length > 0 && url.search(/^([a-z]{3,6}:\/\/|\/|\.)/) == -1 ? 'http://' : '') + url;
}
function field_url(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_url(obj.value);
}



function valid_creditcard(cardNumber, specificCardType) {
	var isValid = false;
	var cardNumbersOnly = cardNumber.replace(/ /g,"");
	var cardNumberLength = cardNumbersOnly.length;
	if (cardNumberLength > 0) {
		var ccTypes = new Array('mc','visa','amex','discover','diners','enroute');
		if (typeof specificCardType != "undefined" && specificCardType != '')
			ccTypes = new Array(specificCardType);
		for (var c = 0; !isValid && c < ccTypes.length; c++) {
			cardType = ccTypes[c];
			var lengthIsValid = false;
			var prefixIsValid = false;
			var prefixRegExp;
			switch(cardType) {
				case 'mc':
				case "mastercard":
						lengthIsValid = (cardNumberLength == 16);
						prefixRegExp = /^5[1-5]/;
					break;
				case "visa":
						lengthIsValid = (cardNumberLength == 16 || cardNumberLength == 13);
						prefixRegExp = /^4/;
					break;
				case "amex":
						lengthIsValid = (cardNumberLength == 15);
						prefixRegExp = /^3(4|7)/;
					break;
				case 'dc':
				case 'dinersclub':
				case 'diners':
				case 'cb':
				case 'carte blanche':
				case' carte':
						lengthIsValid = (cardNumberLength == 14);
						prefixRegExp = /^3(0[0-5]|[36])/;
					break;
				case 'disc':
				case 'discover':
						lengthIsValid = (cardNumberLength == 16);
						prefixRegExp = /^6011/;
					break;
				case 'enroute':
						lengthIsValid = (cardNumberLength == 15);
						prefixRegExp = /^2(014|149)/;
					break;
				default:
						prefixRegExp = /^$/;
					break;
			}
			prefixIsValid = prefixRegExp.test(cardNumbersOnly);
			isValid = prefixIsValid && lengthIsValid;
		}
	}
	if (isValid) {
		var numberProduct;
		var numberProductDigitIndex;
		var checkSumTotal = 0;
		for (digitCounter = cardNumberLength - 1; digitCounter >= 0; digitCounter--) {
			checkSumTotal += parseInt (cardNumbersOnly.charAt(digitCounter));
			digitCounter--;
			numberProduct = String((cardNumbersOnly.charAt(digitCounter) * 2));
			for (var productDigitCounter = 0; productDigitCounter < numberProduct.length; productDigitCounter++) {
				checkSumTotal += parseInt(numberProduct.charAt(productDigitCounter));
			}
		}
		isValid = (checkSumTotal % 10 == 0);
	}
	return isValid;
}

function validate_creditcard(obj,errmsg) {
	var result = true;
	field_creditcard(obj);
	if (obj.value.length > 0 && !valid_creditcard(obj.value)) {
		result = false;
		alert(errmsg);
		obj.select();
		obj.focus();
	}
	return result;
}
function format_creditcard(value) {
	return value.replace(/[^\d]/g,'');
}
function field_creditcard(obj) {
	if (obj && obj.type && obj.type == 'text')
		obj.value = format_creditcard(obj.value);
}


/***************************/

// Find matching label for an object. Will be either with an id = elem.name + 'Label', or scan through labels for matching 'for'
function elementsLabel(elem) {
	var lbl = (elem && elem.name ? document.getElementById(elem.name.replace(/^([a-z0-9_-]+).*$/i,'$1') + 'Label') : false);
	if (!lbl && elem && elem.name) {
		var lbls = document.getElementsByTagName('label');
		var htmlFor;
		for (var i = 0; !lbl && i < lbls.length; i++) {
			htmlFor = lbls[i].htmlFor || lbls[i].getAttribute('htmlFor') || '';
			if (htmlFor == elem.name)
				lbl = lbls[i];
		}
	}
	return lbl;
}


function required(obj) {
	var lbl = elementsLabel(obj);
	var valid = true;
	if (obj && obj.type && obj.type != 'hidden' && lbl && lbl.className.search(/(^|\s)required(Good)?(\s|$)/) != -1) {
		valid = false;
		if (obj.type == 'text' || obj.type == 'textarea' || obj.type == 'password') {
			// Hack to be sure IE doesn't try to autocomplete the field
			obj.setAttribute( "autocomplete", "off");
			valid = (obj.value.replace(/ +$/,'') != '');
			if (valid) {
				if (obj.name.search(/email/) != -1 || obj.className.search(/(^|\s)email(\s|$)/) != -1)
					valid = valid_email(obj.value);
				if (obj.name.search(/creditcard/) != -1 || obj.className.search(/(^|\s)creditcard(\s|$)/) != -1)
					valid = valid_creditcard(obj.value);
			}
		}
		if (obj.type == 'radio' || obj.type == 'checkbox') {
			var objs = obj.form.getElementsByTagName('input');
			for (var g = 0;g<objs.length;g++)
				if (objs[g].name == obj.name)
					valid |= objs[g].checked;
		}
		if (obj.type == 'select' || obj.type == 'select-one' || obj.type == 'select-multi')
			valid = (obj.options[obj.selectedIndex].value != '');
		lbl.className = lbl.className.replace(/(^|\s)required(Good)?(\s|$)/,valid ? '$1requiredGood$3' : '$1required$3');
	}
	return valid;
}

function getElementText(node) {
	var t = '';
	node = node.childNodes || node;
	for (var c = 0; c < node.length; c++)
		t += (node[c].nodeType != 1
				? node[c].nodeValue
				: getElementText(node[c].childNodes)
			);
	return t;
}

// Yes, this is mispelled
var requiredAllLastFeild = false;

function requiredAll( theForm) {
	if ( typeof theForm == 'string')
		theForm = document.getElementById( theForm);
	if (typeof theForm == 'undefined' || theForm.tagName != 'FORM')
		theForm = document.forms[0];
	requiredAllLastFeild = false;
	var valid = true;
	for (var e = 0; valid && e < theForm.elements.length; e++) {
		valid &= required(theForm.elements[e]);
		if (!valid) {
			requiredAllLastFeild = getElementText(elementsLabel(theForm.elements[e])).replace(/:$/,'');
		}
	}
	return valid;
}

function requiredBind( theContainer) {
	if ( typeof theContainer == 'string')
		theContainer = document.getElementById( theContainer);
	if ( theContainer) {
		var elem;
		var elements = [];
		var inputs = theContainer.getElementsByTagName( 'input');
		for ( var i = 0; i < inputs.length; i++)
			elements[ elements.length] = inputs[ i];
		var selects = theContainer.getElementsByTagName( 'select');
		for ( var s = 0; s < selects.length; s++)
			elements[ elements.length] = selects[ s];
		
		var textareas = theContainer.getElementsByTagName( 'textarea');
		for ( var t = 0; t < textareas.length; t++)
			elements[ elements.length] = textareas[ t];
		
		for (var e = 0; e < elements.length; e++) {
			elem = elements[ e];
			required( elem);
			
			if (elem.type == null)
				continue;
	
			switch ( elem.type) {
			case 'text':
			case 'password':
			case 'textarea':
	//				if (typeof elem.onchange != 'undefined' )
	//					continue;
	//				elem.onchange = function(e) {
					// Hack to be sure IE doesn't try to autocomplete the field
					elem.setAttribute( "autocomplete", "off");
					
					addEvent( elem, 'change', function(e) {
							e = e || window.event;
							var obj = e.target || e.srcElement;
							if (obj.type && obj.type.search(/(text|password|textarea)/) != -1) {
								var classes = obj.className.split(' ');
								for (var c = 0; c < classes.length; c++) {
									switch (classes[c]) {
									case 'currency':	field_currency(obj);	break;
									case 'money':		field_currency(obj);		break;
									case 'decimal':		field_decimal(obj);	break;
									case 'number':		field_number(obj);		break;
									case 'phone':		field_phone(obj);		break;
									case 'date':		field_date(obj);		break;
									case 'time':		field_time(obj);		break;
									case 'datetime':	field_datetime(obj);	break;
									case 'email':		field_email(obj);		break;
									case 'url':			field_url(obj);		break;
									case 'creditcard':	field_creditcard(obj);	break;
									default:
											var m = classes[c].match(/(currency|decimal)([0-9])/);
											if (m) {
												if (m[1] == 'decimal')
													field_decimal( obj, m[2]);
												else
													field_currency( obj, m[2]);
											}
											else
												field_text( obj);
										break;
									}
								}
							}
							required( obj);
						});
	//					};
				break;
			case 'select':
			case 'select-one':
			case 'select-multi':
					addEvent( elem, 'change', function(e) {
							e = e || window.event;
							var obj = e.target || e.srcElement;
							required( obj);
						});
				break;
			case 'radio':
			case 'checkbox':
	//				if (typeof elem.onclick != 'undefined')
	//					continue;
	//				elem.onchange = function(e) {
	//						required( this);
	//					};
					addEvent( elem, 'change', function(e) {
							e = e || window.event;
							var obj = e.target || e.srcElement;
							required( obj);
						});
				break;
			}
		}
	}
}


/*****************************/

function getElement(theForm,elementName) {
	var result = false;
	for (var i = 0;!result && i<theForm.elements.length;i++)
		if (theForm.elements[i].name == elementName)
			result = theForm.elements[i];
	return result;
}



function addEvent( obj, eventType, func) { 
	var result = false;
	if (obj.addEventListener != null) { 
		obj.addEventListener( eventType, func, false); 
		result = true; 
	}
	else {
		if (obj.attachEvent) 
			result = obj.attachEvent( "on" + eventType, func); 
	}
	return result;
}


