var appUrlRE = new RegExp("http:\\/\\/[^\\/]+(\\/[^\\/]+)");
appUrlRE.exec(document.location.href, "$1");
var appUrl = RegExp.$1;
/* include internationalized data validation & formatting variables */
if (!window._VALIDATION_ISLOADED) {
	document.write("<script type='text/javascript' src='" + appUrl + "/resources/new/en_US/js/properties.js'><" + "/script>");
}
/* include browser object */
if (!window.browserIsLoaded) {
	document.write("<script type='text/javascript' src='" + appUrl + "/resources/new/js/browsercheck.js'><" + "/script>");
}

/* Global default color to highlight form fields */
var yellow = "FFFF66";
/* Global object for checking at least a certain number of a field collection has been filled in */
var minNumCollection = null;

/*
** getQueryStringParameters()
** Description:		Utility function to retrieve the current query string and package its parameters/values into a "Hashmap".
 *					Checks to make sure the method is not already defined before loading, as it is included in other Cobalt js libraries.
** Syntax:			getQueryStringParameters()
** Usage (assume URL is "http://www.blah.com/asdf.html?foo=bar"):
 *					var qsparms = getQueryStringParameters();
 *					var valueOfFoo = qsparms["foo"];	// assigns "bar" to variable "valueOfFoo"
** Return Value:	"Hashmap" containing a collection of key(String)=>value(String) pairs
 */
if (!window.getQueryStringParametersIsLoaded) {
	var getQueryStringParametersIsLoaded = true;
	getQueryStringParameters = function(someDoc) {
		if (!someDoc) var someDoc = document;
        var thisqs = someDoc.location.search.substring(1, someDoc.location.search.length);
		if (thisqs.length > 0) {
			var qspairs = thisqs.split("&");
			var qsparms = new Array();
			for (var i=0; i<qspairs.length; i++) {
				var regexp = /\+/g;
				if (!qspairs[i]) continue;
				var qskey = unescape((qspairs[i].split("=")[0]).replace(regexp, " "));
				var qsval = unescape((qspairs[i].split("=")[1]).replace(regexp, " "));
				if (qsparms[qskey] && (qsparms[qskey] == qsval)) continue;
				if (!qsparms[qskey]) {
					qsparms[qskey] = qsval;
					continue;
				}
				if (typeof qsparms[qskey] == "string") qsparms[qskey] = [qsparms[qskey], qsval];
				else qsparms[qskey][qsparms[qskey].length] = qsval;
			}
			return qsparms;
		}
		return null;
	}
}

/*
** populateFromQuery()
** Description:		Takes "Hashmap" of key=>value pairs from the query string, populates form elements named 'key' with 'value'.
** Syntax:			populateFromQuery(someForm(Form), someQSParms("Hashmap"))
** Usage:			populateFromQuery(document.formName, getQueryStringParameters());
** Arguments:
 *					REQ	someForm:		HTML Form with Fields to populate
 *						someQSParms:	"Hashmap" of key=>value parameters from the query string
 */
function populateFromQuery(someForm, someQSParms) {
	if (!someForm || !someQSParms) return;
	for (var fieldname in someQSParms) {
		if (someForm[fieldname]) {
			switch(someForm[fieldname].type) {
			case "file":
				break;
			case "text": case "password": case "textarea": case "hidden":
				someForm[fieldname].value = someQSParms[fieldname];
				break;
			default:
				if (typeof someQSParms[fieldname] == "string") {
					setSelected(someForm[fieldname], someQSParms[fieldname]);
				} else {
					for (var i=0; i<someQSParms[fieldname].length; i++) setSelected(someForm[fieldname], someQSParms[fieldname][i]);
				}
				break;
			}
		}
	}
}

/*
** clearForm()
** Description:		Cycles through all Fields in a Form and resets their bgcolors to white.
 *					Optionally sets error message Layer(s) to display:none.  Optionally executes reset() method of Form.
** Syntax:			clearForm(thisForm(Form), [ errorMsgs(Array of Layers OR Layer), [ isReset(Boolean) ] ])
** Usage:			clearForm(document.formName, document.getElementById("errMsg"), true);
** Arguments:
 *					REQ	thisForm:	HTML Form with Fields to clear, also to execute reset() on if applicable
 *						errorMsgs:	array of Layers or single Layer; default is null
 *						isReset:	execute Form.reset(); default is false
 */
function clearForm(thisForm, errorMsgs, isReset){
	changeFieldColor(thisForm.elements);
	if (errorMsgs) {
		if (errorMsgs.length) {
			for (var k=0; k<errorMsgs.length; k++) errorMsgs[k].style.display = "none";
		} else if (errorMsgs.style) {
			errorMsgs.style.display = "none";
		}
	}
	if (isReset) thisForm.reset();
	return;
}

/*
** changeFieldColor()
** Description:		Takes Array of Form Fields and sets their background colors.
** Syntax:			changeFieldColor(fieldList(Array of Fields), [ color(String) ])
** Usage:			changeFieldColor([document.formName.firstName, document.formName.lastName], yellow);
** Arguments:
 *					REQ	fieldList:	Array of Form Fields to apply color change to
 *						color:		hex color String (or variable containing hex color String); default is ""
 */
function changeFieldColor(fieldList, color) {
	if (!color) var color = "";
	var currElem, currElemType;
	for (var i=0; i<fieldList.length; i++) {
		currElem = fieldList[i];
		if (!currElem) break;
		currType = currElem.type;
		// if a collection of form fields (defined by createCollection()), make recursive call with its fieldArray
		if (currType == "collection") {
			changeFieldColor(fieldList[i].fieldArray, color);
		// otherwise assume a normal form field
		} else if ((currType != "button") && (currType != "submit") && (currType != "reset") && (currType != "hidden")) {
			if (!currElem.length || currType == "select-one") {
				currElem.style.backgroundColor = color;
			} else {
				for (var j=0; j<currElem.length; j++) currElem[j].style.backgroundColor = color;
			}
		}
	}
}

/*
** createCollection()
** Description:		Creates (associative) list of collections of form inputs on the page that should be treated as an array
					(e.g. service types).
** Syntax:			createCollection(thisForm(Form), collectionName(String), fieldNameArray(Array of Strings), [ minimumNum(Number) ])
** Usage:			createCollection(document.formName, "service_type", ["oil_change", "brake_inspection"], 1);
** Arguments:
 *					REQ	thisForm:		Form that the Fields in fieldNameArray belong to
 *					REQ	collectionName:	name to refernce the collection by
 *					REQ	fieldNameArray:	Array of field names in the collection
 *						minimumNum:		at least this number in the collection must be filled in; default is 1
 */
function createCollection(thisForm, collectionName, fieldNameArray, minimumNum) {
	if (!minimumNum) var minimumNum = 1;
	if (!minNumCollection) minNumCollection = {};
	minNumCollection[collectionName] = {};
	var fieldArray = new Array;
	for (var i=0; i<fieldNameArray.length; i++) {
		if (thisForm[fieldNameArray[i]]) fieldArray[fieldArray.length] = thisForm[fieldNameArray[i]];
	}
	minNumCollection[collectionName].type = "collection";
	minNumCollection[collectionName].name = collectionName;
	minNumCollection[collectionName].num = minimumNum;
	minNumCollection[collectionName].fieldArray = fieldArray;
}

/*
** getMissingReqs()
** Description:		Takes Array or list of required Fields, returns Array of Fields found empty/unchecked/etc.
 *					Note: non-existent Fields are ignored.
** Syntax:			getMissingReqs((Array of Fields OR list of Fields))
** Usage:
 *					var missingReqs = getMissingReqs([document.formName.firstName, document.formName.lastName]);
 *				OR	var missingReqs = getMissingReqs(document.formName.firstName, document.formName.lastName);
** Arguments:		REQ	:	Array or comma-delimited list of Fields to check
** Return Value:	Array of empty/unchecked/etc required Fields
 */
function getMissingReqs() {
	requiredFields = (arguments[0].form) ? arguments : arguments[0];
	var missedFields = new Array();
	var currElem, currElemType;
    for (var i=0; i<requiredFields.length; i++) {
		currElem = requiredFields[i];
		if (!currElem) break;
		currElemType = currElem.type;
		if (!currElemType && currElem.length) {
			if (!isChecked(currElem)) missedFields[missedFields.length] = currElem;
		} else {
			switch (currElemType) {
			    case "text": case "password": case "textarea": case "file":
					if (isBlank(currElem.value)) missedFields[missedFields.length] = currElem;
			        break;
			    case "checkbox": case "radio":
					if (!isChecked(currElem)) missedFields[missedFields.length] = currElem;
			        break;
			    case "select-one":
					if (!isSelected(currElem)) missedFields[missedFields.length] = currElem;
			        break;
				case "collection":
					if (!filledMinimum(currElem.fieldArray, currElem.num)) missedFields[missedFields.length] = currElem;
					break;
			    default:
			}
		}
	}
	return missedFields;
}

/*
** filledMinimum()
** Description:		Checks to make sure at least the given number of Fields has been completed.
 *					Also takes Array of Fields to ignore.
** Syntax:			filledMinimum(fieldCollection(Array of Fields), num(Number), [ ignoreFields(Array of Fields) ])
** Usage:			if (filledMinimum(document.formName.elements, 2, [document.formName.dialogSelect]))
** Arguments:
 *					REQ	fieldCollection:	Array of Fields to check
 *					REQ	num:				minimum Number of Fields that must be completed
 *						ignoreFields:		Array of Fields that should be ignored; default is null
** Return Value:	Boolean; minimum Number of Fields has been completed
 */
function filledMinimum(fieldCollection, num, ignoreFields) {
	var fieldsToCheck = new Array();
	if (ignoreFields) {
		for (var i=0; i<ignoreFields.length; i++) {
			for (var j=0; j<fieldCollection.length; j++) {
				if (fieldCollection[j] && (ignoreFields[i].name == fieldCollection[j].name)) {
					delete fieldCollection[j];
					break;
				}
			}
		}
	}
	var filledSoFar = 0;
	for (var k=0; k<fieldCollection.length; k++) {
		var currElem = fieldCollection[k];
		if (currElem) {
			var currElemType = currElem.type;
			switch (currElemType) {
				case "text": case "password": case "textarea": case "file":
					if (!isBlank(currElem.value)) filledSoFar++;
					if (filledSoFar >= num) return true;
					break;
				case "checkbox": case "radio":
					if (isChecked(currElem)) filledSoFar++;
					if (filledSoFar >= num) return true;
					break;
				case "select-one":
					if (isSelected(currElem)) filledSoFar++;
					if (filledSoFar >= num) return true;
					break;
				default:
			}
		}
	}
	return false;
}

/*
** hasDropdownHole()
** Description:		Takes an Array of Dropdowns and checks for "holes"-- unselected Dropdowns *before* selected Dropdowns.
 *					Highlights unselected Dropdowns with default color.
** Syntax:			hasDropdownHole(selectList(Array of Dropdowns), [ defaultValue(String) ])
** Usage:			if (hasDropdownHole([document.formName.type, document.formName.make, document.formName.model], "Select One"))
** Arguments:
 *					REQ	selectList:		Array of Dropdowns to check, in order
 *						defaultValue:	option value String to count as unselected, e.g. "Select One"; default is ""
** Return Value:	Boolean; there exists a "hole"
 */
function hasDropdownHole(selectList, defaultValue) {
	if (arguments.length == 1) var defaultValue = "";
	var lastElem = null;
	var prevIsBlank = false;
	for (var i=0; i<selectList.length; i++) {
		var currElem = selectList[i];
		currElem.style.backgroundColor = "";
		if (isSelected(currElem, defaultValue) && prevIsBlank) {
			lastElem.style.backgroundColor = yellow;
			return false;
		} else if (!isSelected(currElem, defaultValue)) {
			prevIsBlank = true;
		}
		lastElem = currElem;
	}
	return true;
}

/*
** isNumeric()
** Description:		Validates ONLY numeric characters.
** Syntax:			isNumeric(str(String))
** Usage:			if (isNumeric(document.formName.quantity.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only numeric characters
 */
function isNumeric(str) {
	var numberRE = new RegExp("^[" + _VALIDATION_NUMERIC + "]*$");
	return numberRE.test(str);
}

/*
** isAlpha()
** Description:		Validates ONLY alpha characters (including internationalized alpha characters).
** Syntax:			isAlpha(str(String))
** Usage:			if (isAlpha(document.formName.alpha.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only alpha characters
 */
function isAlpha(str) {
	var alphaRE = new RegExp("^[" + _VALIDATION_ALPHA + "]*$");
	return alphaRE.test(str);
}

/*
** isAlphaNumeric()
** Description:		Validates ONLY alphanumeric characters (including internationalized alpha characters).
** Syntax:			isAlphaNumeric(str(String))
** Usage:			if (isAlphaNumeric(document.formName.alphanumeric.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only alphanumeric characters
 */
function isAlphaNumeric(str) {
	var alphanumRE = new RegExp("^[" + _VALIDATION_ALPHANUMERIC + "]*$");
	return alphanumRE.test(str);
}

/*
** hasNoQuotes()
** Description:		Validates any character except double quotes.
** Syntax:			hasNoQuotes(str(String))
** Usage:			if (hasNoQuotes(document.formName.noquotes.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains no double quotes
 */
function hasNoQuotes(str) { return hasNoCustom(str, "\""); }

/*
** hasNoHTML()
** Description:		Validates any character except HTML characters (double quotes and angle brackets).
** Syntax:			hasNoHTML(str(String))
** Usage:			if (hasNoHTML(document.formName.mastheadtext.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains no HTML characters
 */
function hasNoHTML(str) { return hasNoCustom(str, "\"<>"); }

/*
** hasNoCustom()
** Description:		Validates any character except those contained in passed String.
** Syntax:			hasNoCustom(str(String), [ customBadChars(String) ])
** Usage:			if (hasNoCustom(document.formName.noCommasOrUnderscores.value, ",_"))
** Arguments:
 *					REQ	str:			String to check
 *						customBadChars:	String containing bad characters; default is none
** Return Value:	Boolean; String contains no bad characters
 */
function hasNoCustom(str, customBadChars) {
	if (!customBadChars) return true;
	var badCharsRE = new RegExp("^[^" + customBadChars + "]*$");
	return badCharsRE.test(str);
}

/*
** isAssetName()
** Description:		Validates characters acceptable in asset names, plus asset name maxlength of 80.
** Syntax:			isAssetName(str(String))
** Usage:			if (isAssetName(document.formName.assetName.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isAssetName(str) { return _VALIDATION_ASSETNAME.test(str); }

/*
** isLibraryName()
** Description:		Validates characters acceptable in library names.
** Syntax:			isLibraryName(str(String))
** Usage:			if (isLibraryName(document.formName.libraryName.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isLibraryName(str) {
	if (BrowserObj().ns4) return true;
	return _VALIDATION_LIBRARYNAME.test(str);
}

/*
** isEmail()
** Description:		Validates characters acceptable in email addresses, plus email address format.
** Syntax:			isEmail(str(String))
** Usage:			if (isEmail(document.formName.email.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters and is correct in email address format
 */
function isEmail(str) { return _VALIDATION_EMAIL.test(str); }

/*
** isURL()
** Description:		Validates characters acceptable in URLs, plus URL format.
** Syntax:			isURL(str(String))
** Usage:			if (isURL(document.formName.vanityURL.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters and is correct in URL format
 */
function isURL(str) { return _VALIDATION_URL.test(str); }

/*
** isPhoneFax()
** Description:		Validates characters acceptable in alphanumeric phone & fax numbers, plus phone/fax format.
** Syntax:			isPhoneFax(str(String))
** Usage:			if (isPhoneFax(document.formName.phone.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters and is correct in phone/fax format
 */
function isPhoneFax(str) { return _VALIDATION_PHONEFAX.test(str); }

/*
** isNumericPhoneFax()
** Description:		Validates characters acceptable in numeric only phone & fax numbers, plus phone/fax format.
** Syntax:			isNumericPhoneFax(str(String))
** Usage:			if (isNumericPhoneFax(document.formName.phone.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters and is correct in phone/fax format
 */
function isNumericPhoneFax(str) { return _VALIDATION_NUMERIC_PHONEFAX.test(str); }

/*
** isZip()
** Description:		Validates characters acceptable in zip/postal codes, plus zip/postal code format.
** Syntax:			isZip(str(String))
** Usage:			if (isZip(document.formName.zip.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters and is in correct zip/postal code format
 */
function isZip(str) { return _VALIDATION_ZIP.test(str); }

/*
** isFreeformDate()
** Description:		Validates characters acceptable in dates, plus date validity, plus date format.
** Syntax:			isFreeformDate(str(String))
** Usage:			if (isFreeformDate(document.formName.date.value))
** Arguments:		REQ	str:	String to check containing full date (e.g. "01/01/2003")
** Return Value:	Boolean; String contains only acceptable characters, is a valid date, and is in correct date format
 */
function isFreeformDate(str) { return _VALIDATION_DATE.test(str); }

/*
** isDay()
** Description:		Validates characters acceptable in date days, plus limited day validity.
** Syntax:			isDay(str(String), [ daysInMonth(String) ])
** Usage:			if (isDay(document.formName.day.value, "28"))
** Arguments:
 *					REQ	str:			String to check
 *						daysInMonth:	Maximum number of days in month (default is 31)
** Return Value:	Boolean; String contains only acceptable characters, and is a valid day
 */
function isDay(str, daysInMonth) {
	if (arguments.length == 1) var daysInMonth = 31;
	return (isEmpty(str) || (str <= daysInMonth));
}

/*
** isMonth()
** Description:		Validates characters acceptable in months, plus month validity.
** Syntax:			isMonth(str(String))
** Usage:			if (isMonth(document.formName.month.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters, and is a valid month
 */
function isMonth(str) { return (isEmpty(str) || _VALIDATION_DATE_MAP[str]); }

/*
** isYear()
** Description:		Validates characters acceptable in years, plus year validity.
** Syntax:			isYear(str(String))
** Usage:			if (isYear(document.formName.year.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters, and is a valid year
 */
function isYear(str) {
	var _allyears = new RegExp("^" + _VALIDATION_DATE_ALLYEARS + "?$");
	return _allyears.test(str);
}

/*
** isDate()
** Description:		Validates characters acceptable in dates, plus limited date validity (does not check leap years).
** Syntax:			isDate(customDateObj(object))
** Usage:			if (isDate({
									[ "d":document.formName.day.value, ]
									[ "m":document.formName.month.value, ]
									[ "y":document.formName.year.value ]
								}))
** Arguments:		REQ	customDateObj:	object containing any combination of optional day ("d"), month ("m"), and year ("y") values
** Return Value:	Boolean; object values contain only acceptable characters, and are (probably) part of valid date
 */
function isDate(customDateObj) {
	var gotDay = (customDateObj["d"] && !isEmpty(customDateObj["d"]));
	var gotMonth = (customDateObj["m"] && !isEmpty(customDateObj["m"]));
	var gotYear = (customDateObj["y"] && !isEmpty(customDateObj["y"]));
	// munge
	if (gotDay && (customDateObj["d"].length == 1)) customDateObj["d"] = "0" + customDateObj["d"];
	if (gotMonth && (customDateObj["m"].length == 1)) customDateObj["m"] = "0" + customDateObj["m"];
	// one-off checks
	if (gotYear && !isYear(customDateObj["y"])) return false;
	if (gotMonth && !isMonth(customDateObj["m"])) return false;
	if (gotDay && !isDay(customDateObj["d"])) return false;
	// day, month, year passed
	if (gotDay && gotMonth && gotYear) {
		var thisdate = "";
		for (var i=0; i<_VALIDATION_DATE_ORDER.length; i++) thisdate += customDateObj[_VALIDATION_DATE_ORDER[i]] + _VALIDATION_DATE_DL;
		return isFreeformDate(thisdate.substring(0, (thisdate.length - _VALIDATION_DATE_DL.length)));
	}
	// only day and month passed
	if (gotDay && gotMonth && !gotYear) return isDay(customDateObj["d"], _VALIDATION_DATE_MAP[customDateObj["m"]]);
	return true;
}

/*
** isAddress()
** Description:		Validates characters acceptable in addresses.
** Syntax:			isAddress(str(String))
** Usage:			if (isAddress(document.formName.address.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isAddress(str) {
	if (BrowserObj().ns4) return true;
	return _VALIDATION_ADDRESS.test(str);
}

/*
** isMoney()
** Description:		Validates characters acceptable in monetary values.
** Syntax:			isMoney(str(String))
** Usage:			if (isMoney(document.formName.price.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isMoney(str) { return _VALIDATION_MONEY.test(str); }

/*
** isCity()
** Description:		Validates characters acceptable in city names.
** Syntax:			isCity(str(String))
** Usage:			if (isCity(document.formName.city.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isCity(str) {
	if (BrowserObj().ns4) return true;
	return _VALIDATION_CITY.test(str);
}

/*
** isOdometer()
** Description:		Validates characters acceptable in odometer readings.
** Syntax:			isOdometer(str(String))
** Usage:			if (isOdometer(document.formName.odometer.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isOdometer(str) { return _VALIDATION_ODOMETER.test(str); }

/*
** isLatLong()
** Description:		Validates characters acceptable in latitudes & longitudes.
** Syntax:			isLatLong(str(String))
** Usage:			if (isLatLong(document.formName.latitude.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isLatLong(str) { return _VALIDATION_LATLONG.test(str); }

/*
** isCCNumber()
** Description:		Validates characters acceptable in credit card numbers.
** Syntax:			isCCNumber(str(String))
** Usage:			if (isCCNumber(document.formName.ccnumber.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isCCNumber(str) { return _VALIDATION_CREDITCARDNUMBER.test(str); }

/*
** isSSNumber()
** Description:		Validates characters acceptable in social security numbers.
** Syntax:			isSSNumber(str(String))
** Usage:			if (isSSNumber(document.formName.ssnumber.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only acceptable characters
 */
function isSSNumber(str) { return _VALIDATION_SSN.test(str); }

/*
** isBlank()
** Description:		Validates Strings containing nothing but white space characters.
** Syntax:			isBlank(str(String))
** Usage:			if (isBlank(document.formName.mustBeBlank.value))
** Arguments:		REQ	str:	String to check
** Return Value:	Boolean; String contains only white space characters
 */
function isBlank(str) {
	if (str == "") return true;
	var blankRE = new RegExp("^[" + _VALIDATION_BLANKCHARS + "]*$");
	return blankRE.test(str);
}

/*
** isSelected()
** Description:		Checks to see if a Dropdown has a non-default option selected.
** Syntax:			isSelected(thisSelect(Dropdown), [ defaultValue(String) ])
** Usage:			if (isSelected(document.formName.make, "Select One"))
** Arguments:
 *					REQ	thisSelect:		Dropdown to check
 *						defaultValue:	option value String to count as unselected, e.g. "Select One"; default is ""
** Return Value:	Boolean; Dropdown has non-default option selected.
 */
function isSelected(thisSelect, defaultValue) {
	if (arguments.length == 1) var defaultValue = "";
	var currentSelection = getSelected(thisSelect);
	if (currentSelection) return (currentSelection["value"] != defaultValue);
	else return false;
}

/*
** isChecked()
** Description:		Checks to see if a Radio or Checkbox Array has an option checked.
** Syntax:			isChecked(checkObj(Radio Array OR Checkbox Array))
** Usage:			if (isChecked(document.formName.vehicleExteriorCondition))
** Arguments:		REQ	checkObj:	Radio or Checkbox Array to check
** Return Value:	Boolean; Radio or Checkbox Array has an option checked.
 */
function isChecked(checkObj) { return (getSelected(checkObj)) ? true : false; }

/*
** isMaxLength()
** Description:		Checks to see if a String is more than the max Number of characters
** Syntax:			isMaxLength(str(String), maxLength(Number))
** Usage:			if (isMaxLength(document.formName.textCellText.value, 500))
** Arguments:
 *					REQ	str:		String to check
 *						maxLength:	maximum Number of characters
** Return Value:	Boolean; String is equal to or under max Number of characters
 */
function isMaxLength(str, maxLength) {
	if (str.length <= maxLength) return true;
	else return false;
}

/*
** getSelected()
** Description:		Gets an object containing the selected "index" and "value" of a Dropdown, or Radio or Checkbox Array
** Syntax:			getSelected(thiselement(Dropdown OR Radio Array OR Checkbox Array))
** Usage:			var currentMakeName = getSelected(document.formName.make)["value"];
** Arguments:		REQ	thiselement:	Dropdown, or Radio Array, or Checkbox Array to get selection of
** Return Value:	object containing selected "index" and "value" properties OR Boolean; false if no selection
 */
function getSelected(thiselement) {
	if (thiselement.type == "select-one") {
		var ind = thiselement.selectedIndex;
		if (ind >= 0) return {"index":ind, "value":thiselement.options[ind].value}
	}
	if (thiselement.length) {
		var isCheckbox = (thiselement[0].type == "checkbox") ? true : false;
		var values = new Array();
		var indexes = new Array();
		for (var i=0; i<thiselement.length; i++) {
			if (thiselement[i].checked && !isCheckbox) return {"index":i, "value":thiselement[i].value};
			if (thiselement[i].checked && isCheckbox) {
				values[values.length] = thiselement[i].value;
				indexes[indexes.length] = i;
			}
		}
		if (isCheckbox) {
			if (indexes.length) return {"index":indexes, "value":values};
			else return {"index":null, "value":null};
		}
	} else {
		if (thiselement.checked) return {"index":0, "value":thiselement.value};
	}
	return false;
}

/*
** setSelected()
** Description:		Sets the selection of a Dropdown, or Radio or Checkbox Array
** Syntax:			setSelected(thiselement(Dropdown OR Radio Array OR Checkbox Array), selectvalue(String))
** Usage:			setSelected(document.formName.make, "Audi");
** Arguments:
 *					REQ	thiselement:	Dropdown, or Radio Array, or Checkbox Array to set selection of
 *						selectvalue:	option value String to select
 */
function setSelected(thiselement, selectvalue) {
	var thiscoll = (thiselement.type == "select-one") ? thiselement.options : thiselement;
	var checkedProperty = (thiselement.type == "select-one") ? "selected" : "checked";
	if (arguments.length == 1) {
		eval("thiselement[0]." + checkedProperty + " = true");
	} else {
		if (thiscoll.length) {
			for (var i=0; i<thiscoll.length; i++) {
				if (thiscoll[i].value == selectvalue) {
					eval("thiscoll[i]." + checkedProperty + " = true");
					break;
				}
			}
		} else {
			if (thiscoll.value == selectvalue) eval("thiscoll." + checkedProperty + " = true");
		}
	}
}
