var frmVals    = '';
var formErr    = new Array();
var ignoreVal  = '--Select--';
var reqdFailBdr = '#993333';
var reqdFailBG  = '#FFD0CD';
var reqdPassBG  = 'white';
var reqdPassBdr = '#7F9DB9';

function submitForm(fn,btn,blnSubmit){
	if(blnSubmit == '' || blnSubmit == null){
		blnSubmit = 1; // submit the form on validate;
	}
	frm = $(fn);
	formErr = new Array();
	validateForm(frm);
	if(formErr.length <= 0){
		frmAction = frm.action;
		frmMethod = frm.method;
		parseForm(fn);

		if(typeof(btn) == 'object'){
			disableBtn(btn);
		}

		if(blnSubmit){
			// the form would be submitted if it's all good
			frm.submit();
		} else {
			return true;
		}

	} else {
		errMsg = 'There was an error submitting the form:\n';
		for(fe = 0; fe < formErr.length; fe++){
			errMsg += (fe+1) + '. ' + formErr[fe] + '\n';
		}
		if(!blnSubmit){
			return false;
		}
		alert(errMsg);
	}
}

function validateForm(frm){
	tmpErr = new Array();
	for(ec = 0; ec < frm.elements.length; ec++){
		valRule = frm.elements[ec].getAttribute('reqd');
		if(valRule != null){
			//el = $(frm.elements[ec].id);
			el = frm.elements[ec];
			validateFld(el,valRule);
		}
	}
}

function parseForm(fn){
	frm = $(fn);
	frmVals = '';
	for(ec = 0; ec < frm.elements.length; ec++){
		frmVals += getElId(frm.elements[ec]);
		frmVals += '=' + escape(getElValue(frm.elements[ec],ignoreVal));
		if(ec < frm.elements.length - 1){
			frmVals += '&';
		}
	}
}

function validateFld(el,rule){

	// Field Validation:
	// rule setup:
	// Rule Type|Field Name|(Min Lengh)|(Max Length)
	// Min/Max length are optional

	// Available Rules:
	// 	RegEx - format is: RegEx@@[^a-zA-Z]@@true|Name
	//		field is @@ delimited:
	//		field 0 "RegEx"
	//		field 1 regular expression
	//		field 2 true/false (the regular expression must = the boolean to validate)
	//	AlphaOnly     (a-z, A-Z, space)
	//	AlphaNumeric  (a-z, A-Z, 0-9, space, dash, period)
	//	NumericOnly   (0-9)
	//	Number        (0-9, dash, period)
	//	Phone         (xxx-xxx-xxxx, (xxx) xxx-xxxx, xxxxxxxxxx)
	// 	Email         (abc@abc.com)
	//	DateMM/DD/*YY (xx/xx/xxxx or xx/xx/xx)
	//	CreditCard    performs Luhn Mod10 validation

	elVal       = getElValue(el,ignoreVal);
	fieldRules  = rule.split('|');
	valType     = fieldRules[0];
	fldName     = fieldRules[1];
	fldMin      = fieldRules[2];
	fldMax      = fieldRules[3];
	fldRegEx    = '';
	fldRegExBln = false;
	fldIsValid  = true;

	fldMin = (Number(fldMin))? fldMin : 1;
	fldMax = (Number(fldMax))? fldMax : (100000000)^10;

	// check requird fields for minimum/maximum length
	if(elVal.length < fldMin && fldMin == 1){
		fldIsValid = false;
		formErr.push(fldName + ' cannot be empty');
	} else if(elVal.length < fldMin){
		fldIsValid = false;
		formErr.push(fldName + ' must be at least ' + fldMin + ' characters long');
	} else if(elVal.length > fldMax){
		fldIsValid = false;
		formErr.push(fldName + ' can be no longer than ' + fldMax + ' characters long');
	} else {

		// check for a RegEx rule, parse it.
		if(valType.indexOf('RegEx') != -1){
			regexA      = valType.split('@@');
			valType     = 'RegEx';
			fldRegEx    = regexA[1];
			fldRegExBln = Boolean(regexA[2]);
		}

		switch (valType){
		case 'RegEx':
			tmpReg = new RegExp(fldRegEx);
			if(tmpReg.test(elVal) == fldRegExBln){
				fldIsValid = false;
				formErr.push(fldName + ' is the incorrect format');
			}
			break

		case 'AlphaOnly':
			tmpReg = new RegExp(/[^a-zA-Z\s]/);
			if(tmpReg.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' can only be A-Z');
			}
			break

		case 'AlphaNumeric':
			tmpReg = new RegExp(/[^a-zA-Z0-9\s-.]/);
			if(tmpReg.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' can only be A-Z or 0-9');
			}
			break

		case 'NumericOnly':
			tmpReg = new RegExp(/[^0-9]/);
			if(tmpReg.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' can only be 0-9');
			}
			break

		case 'Number':
			tmpReg = new RegExp(/[^0-9.-]/);
			if(tmpReg.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' can only be a number');
			}
			break
		case 'Phone':
			phReg1 = new RegExp(/\(\d{3}\)\s\d{3}-\d{4}/);
			phReg2 = new RegExp(/\d{3}-\d{3}-\d{4}/);
			phReg3 = new RegExp(/\d{10}/);
			if(!phReg1.test(elVal) && !phReg2.test(elVal) && !phReg3.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' is an invalid format');
			}
			break

		case 'Zip':
			zipReg1 = new RegExp(/\d{5}/);
			zipReg2 = new RegExp(/\d{5}-\d{4}/);
			if(!zipReg1.test(elVal) && !zipReg2.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' is an invalid format');
			}
			break

		case 'Money':
			//numeric, comma, decimal, $ sign
			tmpReg = new RegExp(/[^0-9.$,]/);
			if(tmpReg.test(elVal)){
				fldIsValid = false;
				formErr.push(fldName + ' is an invalid format');
			}
			break

		case 'Email':

			tmpReg = new RegExp(/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/);
			fldIsValid = tmpReg.test(elVal);
			if(!fldIsValid){
				formErr.push(fldName + ' is an invalid email format');
			}
			break

		case 'DateMM/DD/*YY':
			if(elVal.indexOf('/') != -1){
				dateA = elVal.split('/');
				if(dateA.length == 3){
					if(Number(dateA[0]) && dateA[0] <= 12 && dateA[0] > 0){
						if(Number(dateA[1]) && dateA[1] <= 31 && dateA[1] > 0){
							if(Number(dateA[2]) && (dateA[2].length == 2 || dateA[2].length == 4)){
							} else {
								fldIsValid = false;
							}
						} else {
							fldIsValid = false;
						}
					} else {
						fldIsValid = false;
					}
				} else {
					fldIsValid = false;
				}
			} else {
				fldIsValid = false;
			}
			if(!fldIsValid){
				formErr.push(fldName + ' is an invalid date format');
			}
			break

		case 'CreditCard':
			//numeric only, 14-16 characters, passes MOD10
			tmpReg = new RegExp(/[^0-9]/);
			if(tmpReg.test(elVal) || !mod10(elVal) || elVal.length < 14 || elVal.length > 16){
				fldIsValid = false;
				formErr.push(fldName + ' is an invalid card format');
			}
			break
		}
	}
	if(!fldIsValid){
		el.style.backgroundColor = reqdFailBG;
		el.style.borderColor = reqdFailBdr;
	} else {
		el.style.backgroundColor = reqdPassBG;
		el.style.borderColor = reqdPassBdr;
	}
	return fldIsValid;
}

function showHideDiv(d,s){
	tmpDiv = $(d);
	if(s){
		tmpDiv.style.display = 'block';
	} else {
		tmpDiv.style.display = 'none';
	}
}

function showHideFC(d,s){
	for(z = 0; z < 4; z++){
		divName = 'divFC' + String(d) + String(z)
		showHideDiv(divName,s);
	}
}

function disableBtn(btn){
	tmpBtn = $(btn);
	tmpBtn.disabled = true;
}

function $(el){
	return document.getElementById(el);
}

function getElId(el){
	return (el.id)? el.id : el.name;
}

function getElValue(el,ignoreTxt){
	var elVal = '';
	if(ignoreTxt == null){
		ignoreTxt = '';
	}

	// we got passed a direct radio reference
	// it gets messed up like this, so we fix it
	// so we can get radio.length and find the checked button
	if(el.type == 'radio' && String(el.length) == 'undefined'){
		rdoName = getElId(el);
		rdoForm = el.form;
		el = rdoForm.elements[rdoName];
	}

	// special radio case (groups)
	// radio buttons in a group greater than one
	// have the type "undefined" for some reason
	// this sniffs out a radio array
	if(typeof(el) == 'object' && String(el.type) == 'undefined'){
		for(rc = 0; rc < el.length; rc ++){
			if(el[rc].checked){
				elVal = el[rc].value;
			}
		}
		return elVal;
	}

	// standard form inputs
	// all otehr inputs act nice.
	switch (el.type){
	case 'text':
		return el.value;
		break
	case 'hidden':
		return el.value;
		break
	case 'textarea':
		return el.value;
		break
	case 'checkbox':
		if(el.checked){
			return el.value;
		}
		break
	case 'radio':
		if(el.checked){
			return el.value;
			break;
		}
		break
	case 'select-one':
		elVal = el.options[el.selectedIndex].value;
		if(elVal == '' || elVal == ignoreTxt){
			elVal = el.options[el.selectedIndex].text;
			if(elVal == ignoreTxt){
				elVal = '';
			}
		}
		return elVal;
		break
	case 'select-multiple':
		for(sc = 0; sc < el.length; sc ++){
			if(el.options[sc].selected){
				currVal = el[sc].value;
				if(currVal == '' || currVal == ignoreTxt){
					currVal = el[sc].text;
					if(currVal == ignoreTxt){
						currVal = '';
					}
				}
				if(elVal == ''){
					elVal = currVal;
				} else {
					elVal = elVal + ',' + currVal;
				}
			}
		}
		return elVal;
		break
	}
	return elVal;
}

function mod10(ccnum){
	digits   = new Array();
	finalNum = 0;

	ccnum = ccnum.toString();

	// strip spaces - the only cleanup performed.
	ccnum = ccnum.replace(/^\s+|\s+$/g,'');

	// length under 14 or over 16
	if(ccnum.length < 14 || ccnum.length > 16){ return false; }

	// number must be 0-9 only
	ccReg = new RegExp(/[^0-9]/);
	if(ccReg.test(ccnum)){ return false; }

	// double alternating digits right to left.
	// if the digit > 9, then add the two digits together
	for(cc = ccnum.length-1; cc > -1; cc--){
		if(cc % 2 == 0){
			digits[cc] = 2 * parseInt(ccnum.charAt(cc));
			if(digits[cc] > 9){
				num = String(digits[cc]);
				digits[cc] = parseInt(num.charAt(0)) + parseInt(num.charAt(1));
			}
		} else {
			digits[cc] = parseInt(ccnum.charAt(cc));
		}
	}

	// add all the results
	for(dc = 0; dc < digits.length; dc++){
		finalNum += digits[dc];
	}

	// check the modulus
	if(finalNum % 10 == 0){
		return true;
	} else {
		return false;
	}
}