/*
Author........John Winger
Description...Various functions for validating form elements & questionnaire question types
Last Updated..10/23/2008
*/
function isEmpty(f,e,type,label) {
	var d      = eval("document." + f + "." + e);
	var notify = (label.length > 0 ? true : false);
	var empty  = false;
	var verb   = "select";

	if (type == "text") {
		d.value = trim(d.value);
		if (d.value.length == 0) empty = true;
		verb = "enter";
	}

	if (type == "radio")
		if (getRadioVal(d).length == 0)
			empty = true;

	if (type == "check" || type == "checkbox")
		if (d.checked == 0)
			empty = true;

	if (type == "select") {
		if (d.selectedIndex < 0)
			empty = true;
		else if (d.options[d.selectedIndex].value.length == 0)
			empty = true;
	}

	if (empty && notify) {
		alert("Please " + verb + " a response for " + label + ".");

		if (type == "radio" && d.length > 1)
			eval("document." + f + "." + e + "[0].focus()");
		else
			eval("document." + f + "." + e + ".focus()");
	}

	return empty;
}


function isLength(ckLen,f,e,label) {
	var d      = eval("document." + f + "." + e);
	var notify = (label.length > 0 ? true : false);
	var lenOK  = false;

	if (d.value.length >= ckLen) lenOK = true;

	if (!lenOK && notify) {
		alert("Please enter a valid response for " + label + ".\nThe value must be at least " + ckLen + " characters.");
		eval("document." + f + "." + e + ".focus()");
	}

	return lenOK;
}


function isValidDobYr(y) {
	if (y.length < 4) return false;
	if (!allValidChars(y,"0123456789")) return false;

	var today = new Date();
	var thisYr = today.getYear();
	if (thisYr < 1900) thisYr += 1900;
	var firstValidYr = thisYr - 100;

	y = parseInt(y, 10);
	if (y < firstValidYr || thisYr < y) return false;

	return true;
}


function isEmail(eMailAddr) {
	var strLen = eMailAddr.length;

	if (strLen < 6 || 65 < strLen)
		return false;
	else if (!allValidChars(eMailAddr,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.@'))
		return false;
	else if (eMailAddr.indexOf("@") <= 0)
		return false;
	else if (eMailAddr.charAt(strLen - 1) == "@")
		return false;
	else if (eMailAddr.indexOf("@", (eMailAddr.indexOf("@") + 1)) > -1 )
		return false;
	else if (eMailAddr.indexOf(".") < 0)
		return false;
	else if (eMailAddr.indexOf(".", (eMailAddr.indexOf("@") + 2)) < 0)
		return false;
	else if (eMailAddr.charAt(eMailAddr.indexOf("@") + 1) == ".")
		return false;
	else if (eMailAddr.charAt(strLen - 1) == ".")
		return false;

	return true;
}


function isPhoneNumber(number,force_area_code) {
	// matches common US phone numbers.
	// (123) 456-7890, (123)456-7890, 123-4567
	var pattern;

	if (force_area_code)
		pattern = /^\(\d{3}\)\s*\d{3}\-\d{4}\s*$/;
	else
		pattern = /^((\(\d{3}\))?\s*)?\d{3}\-\d{4}\s*$/;

	if ( ! pattern.test(number) )
		return false;
	else
		return true;
}


function selItemCount(f,e,highPos,lowPos) {
	if (! lowPos) lowPos = 0;
	var d = "document." + f + "." + e;
	var selItemCount = 0;

	for (var i = lowPos; i <= highPos; i++) {
		if (eval(d + i))
			if (eval(d + i + ".checked"))
				selItemCount++;
	}

	return selItemCount;
}


function digitCount(str) {
	var cnt = 0;
	for (var i = 0; i < str.length; i++) {
		var c = str.charAt(i);
		if (isDigit(c))
			cnt++;
	}
	return cnt;
}


function isDigit(c) {
	if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
		return true;
	else
		return false;
}


function formatPhNum(str) {
	var cnt = 0;
	var ph  = '';

	for (var i = 0; i < str.length; i++) {
		var c = str.charAt(i);

		if (isDigit(c)) {
			cnt++;

			if (cnt == 4 || cnt == 7)
				ph += '-';
			else if (cnt == 11)
				ph += ' ext. ';

			ph += c;
		}
	}

	return ph;
}


function isValidStAbbr(abbr,inclUsTerr) {
	var validAbbr = ',AK,AL,AR,AZ,CA,CO,CT,DC,DE,FL,GA,HI,IA,ID,IL,IN,KS,KY,LA,MA,MD,ME,MI,MN,MO,MS,MT,NC,ND,NE,NH,NJ,NM,NV,NY,OH,OK,OR,PA,RI,SC,SD,TN,TX,UT,VA,VT,WA,WI,WV,WY,';
	if (inclUsTerr) validAbbr += 'AS,FM,GU,MH,MP,PW,PR,VI,';

	if (validAbbr.indexOf(',' + abbr.toUpperCase() + ',') > -1)
		return true;
	else
		return false;
}


function isZipCode(zip) {
	if (zip.length != 5 && zip.length != 10) {
		return false;
	}
	else if (zip.length == 5 && !allValidChars(zip,'0123456789')) {
		return false;
	}
	else if (zip.length == 10) {
		var part1 = zip.substring(0,5);
		var part2 = zip.charAt(5);
		var part3 = zip.substring(6,10);

		if (!allValidChars(part1 + part3,'0123456789') || part2 != '-')
			return false;
	}

	return true;
}


function allValidChars(str,valChars) {
	var c;
	for (var i = 0; i < str.length; i++) {
		c = str.charAt(i);
		if (valChars.indexOf(c) < 0) {
			return false;
			break;
		}
	}

	return true;
}


function getRadioVal(radioObj) {
	var value = "";

	if (!radioObj.length) {
		if (radioObj.checked) value = radioObj.value;
	}
	else {
		for (var i = 0; i < radioObj.length; i++) {
			if (radioObj[i].checked) {
				value = radioObj[i].value;
				break;
			}
		}
	}

	return value;
}


function strReplace(origString, findString, replString) {
	var pos     = origString.indexOf(findString);
	var len     = origString.length;
	var findLen = findString.length;

	var preString, postString;

	while (pos != -1) {
		preString  = origString.substring(0, pos);
		postString = origString.substring(pos + findLen, len);
		origString = preString + replString + postString;
		pos        = origString.indexOf(findString);
	}

	return origString;
}


function isValidNumber(checkVal) {
	if (!allValidChars(checkVal,"-0123456789.") || checkVal.length == 0 || checkVal == "." || checkVal == "-") {
		return false;
	}
	else {
		if (checkVal.indexOf(".") > -1) {
			if (checkVal.indexOf(".",(checkVal.indexOf(".") + 1)) > -1)
				return false;
		}
		else if (checkVal.indexOf("-") > 0) {
			return false;
		}
	}

	return true;
}


function isWholeNumber(checkVal) {
	if (!allValidChars(checkVal,"-0123456789") || checkVal.length == 0 || checkVal == "-")
		return false;
	else if (checkVal.indexOf("-") > 0)
		return false;
	else
		return true;
}


function isInRange(num,min,max) {
	if (min <= num && num <= max)
		return true;
	else
		return false;
}


function strLenInRange(str,min,max) {
	var len = str.length;
	if (min <= len && len <= max)
		return true;
	else
		return false;
}


function equalsConstSum(f,e,numPrts,constSum,supressMsgs,allowBlanks,disallowZero) {
	var d           = "document." + f + "." + e;
	var strConstSum = constSum + "";
	var maxLen      = strConstSum.length;
	var checkSum    = 0;
	var num, rangeMin, rangeMax, adnlAlrtMsg;

	if (disallowZero) {
		rangeMin    = 1;
		rangeMax    = constSum - 1;
		adnlAlrtMsg = "";
	}
	else {
		rangeMin    = 0;
		rangeMax    = constSum;
		adnlAlrtMsg = " Enter a zero if none.";
	}

	for (var i = 0; i <= numPrts; i++) {
		if (eval(d + i)) {
			num = eval(d + i + ".value");

			if (strLenInRange(num, 1, maxLen) && isWholeNumber(num) && isInRange(parseFloat(num),rangeMin,rangeMax)) {
				checkSum += parseInt(num, 10);
			}
			else if (!allowBlanks || (allowBlanks && num.length > 0)) {
				if (!supressMsgs) {
					alert("Make sure you enter a whole number between " + rangeMin + " and " + rangeMax + " at each space provided." + adnlAlrtMsg);
					eval(d + i + ".focus()");
				}

				return false;
			}
		}
	}

	if (checkSum != constSum) {
		if (!supressMsgs)
			alert("Your responses add up to " + checkSum + ", but they need to add up to " + strConstSum + ".");
		return false;
	}

	return true;
}


function equalsConstSumLow(f,e,numPrts,lowVal, constSum,supressMsgs,allowBlanks) {
	var d           = "document." + f + "." + e;
	var strConstSum = constSum + "";
	var maxLen      = strConstSum.length;
	var checkSum    = 0;
	var num;

	for (var i = 0; i <= numPrts; i++) {
		if (eval(d + i)) {
			num = eval(d + i + ".value");

			if (strLenInRange(num, 1, maxLen) && isWholeNumber(num) && isInRange(parseFloat(num),lowVal,constSum)) {
				checkSum += parseInt(num, 10);
			}
			else if (!allowBlanks || (allowBlanks && num.length > 0)) {
				if (!supressMsgs) {
					alert("Make sure you enter a whole number between " + lowVal + " and " + constSum + " at each space provided.");
					eval(d + i + ".focus()");
				}

				return false;
			}
		}
	}

	if (checkSum != constSum) {
		if (!supressMsgs)
			alert("Your responses add up to " + checkSum + ", but they need to add up to " + strConstSum + ".");
		return false;
	}

	return true;
}


function checkRank(f,e,numPrts,maxRank,rankUsed,supressMsgs,qMsg) {
	var d          = "document." + f + "." + e;
	var strMaxRank = maxRank + "";
	var maxLen     = strMaxRank.length;
	var minRank    = 1;
	var qDesc      = "";
	if (qMsg && qMsg.length > 0) qDesc = " at " + qMsg;
	var tmp;

	for (var i = 0; i <= numPrts; i++) {
		if (eval(d + i)) {
			tmp = eval(d + i + ".value");

			if (strLenInRange(tmp, 1, maxLen) && isWholeNumber(tmp) && isInRange(parseInt(tmp, 10), minRank, maxRank)) {
				rankUsed[ parseInt(tmp, 10) ]++;
			}
			else if (tmp.length > 0) {
				// allow empty spaces, just not invalid responses
				if (!supressMsgs) {
					alert("Make sure you only use whole numbers between " + minRank + " and " + maxRank + qDesc);
					eval(d + i + ".focus()");
				}

				return false;
			}
		}
	}

	for (var i = 1; i < rankUsed.length; i++) {
		if (rankUsed[i] > 1) {
			if (!supressMsgs) alert('You used "' + i + '" more than once' + qDesc);
			return false;
		}
		else if (rankUsed[i] == 0) {
			if (!supressMsgs) alert('You did not use "' + i + '"' + qDesc);
			return false;
		}
	}

	return true;
}


function checkGrid(formName,qnumStart,qnumEnd,label,rowOrCol,rowLabel) {
	/*
	formName...name of the form (usually "form1")
	qnumStart..question number of the first row in the grid (the lowest qnum)
	qnumEnd....question number of the last row in the grid (the highest qnum)
	label......addition text to add to the alert (only if you're not passing
	           in a rowLabel array)
	rowOrCol...for the alert message, if selection is made by column set as
	           'column' ('row' is the default if this value is not set)
	rowLabel...an array of the row (or column) labels for specifying in the
	           alert message (optional)
	*/
	if (label.length > 0) label = label + " ";
	if (!rowOrCol) rowOrCol = 'row';
	if (!rowLabel) rowLabel = new Array();
	var labelsExist = ((!rowLabel || rowLabel.length > 0) ? true : false);

	for (var i = qnumStart; i <= qnumEnd; i++) {
		var rowIdx = i - qnumStart;

		if (eval("document." + formName + ".q" + i + "_0")) {
			var labelTmp = (labelsExist ? '"' + rowLabel[rowIdx] + '"' : "each " + rowOrCol + " in the " + label + "grid");

			if (isEmpty(formName, "q" + i + "_0", "radio", labelTmp))
				return false;
		}
	}

	return true;
}


function checkMultiSelGrid(f,qnumStart,qnumEnd,highPos,mainLabel,otherPos,otherSpecQnum,otherLabel,exclPos,exclLabel,rowOrCol,rowLabel) {
	if (mainLabel.length > 0) mainLabel = mainLabel + " ";
	if (!rowOrCol) rowOrCol = 'row';
	if (!rowLabel) rowLabel = new Array();
	var labelsExist = ((!rowLabel || rowLabel.length > 0) ? true : false);
	var d = "document." + f;

	for (var q = qnumStart; q <= qnumEnd; q++) {
		var inputsExist = false;
		var e = 'q' + q + '_';

		for (var i = 0; i <= highPos; i++) {
			if (eval(d + "." + e + i)) {
				inputsExist = true;
				break;
			}
		}

		if (inputsExist) {
			var rowIdx   = q - qnumStart;
			var labelTmp = (labelsExist ? '"' + rowLabel[rowIdx] + '"' : "each " + rowOrCol + " in the " + mainLabel + "grid");

			if (!valCheckbox(f,e,highPos,labelTmp,otherPos,otherSpecQnum,otherLabel,exclPos,exclLabel))
				return false;
		}
	}

	return true;
}


function valCheckboxAlt(f,e,highPos,dkPos,nonePos,otherPos,otherSpecQnum,label) {
	// DEPRICATED
	// Using these arguments to call the new "valCheckbox()" function...
	var newHighPos = highPos;
	if (dkPos    > newHighPos) newHighPos = dkPos;
	if (nonePos  > newHighPos) newHighPos = nonePos;
	if (otherPos > newHighPos) newHighPos = nootherPos;

	var _otherPos      = new Array();
	var _otherSpecQnum = new Array();
	var otherLabel     = new Array();
	var exclPos        = new Array();
	var exclLabel      = new Array();

	if (otherPos) {
		_otherPos[0]      = otherPos;
		_otherSpecQnum[0] = otherSpecQnum;
		otherLabel[0]     = "Other";
	}

	var subscr = 0;
	if (dkPos) {
		exclPos[subscr]   = dkPos;
		exclLabel[subscr] = "Don't know";
		subscr++;
	}

	if (nonePos) {
		exclPos[subscr]   = nonePos;
		exclLabel[subscr] = "None";
	}

	return valCheckbox(f,e,newHighPos,label,_otherPos,_otherSpecQnum,otherLabel,exclPos,exclLabel);
}


function valCheckbox(f,e,highPos,mainLabel,otherPos,otherSpecQnum,otherLabel,exclPos,exclLabel) {
	/*
	f..............form name (usually "form1")
	e..............checkbox name minus the "subscript" ending (eg "q1_")
	highPos........highest "subscript"/position (including "none's", "other's", etc)
	mainLabel......a label that refers to the question for the error message (eg "the question" if it's the only one on the screen)
	otherPos.......array of "subscripts" where the "other" checkboxes are located
	otherSpecQnum..array of "other" question numbers
	otherLabel.....array of "other" input labels for error messages
	exclPos........array of "subscripts" where exclusive responses are located
	exclLabel......array of input labels of exclusive responses for error messages
	*/
	var d                  = "document." + f + "." + e;
	var nonExclItemChecked = new Array(exclPos.length);
	var atLeastOneChecked  = false;
	var firstFormEleSub    = -1;

	// first, see if any checkboxes are checked
	for (var i = 0; i <= highPos; i++) {
		if (eval(d + i)) {
			if (firstFormEleSub < 0) firstFormEleSub = i;
			if (eval(d + i + ".checked") == true) {
				atLeastOneChecked = true;

				for (var j = 0; j < exclPos.length; j++) {
					if (i != exclPos[j]) nonExclItemChecked[j] = true;
				}
			}
		}
	}

	if (!atLeastOneChecked) {
		alert("Please select a response for " + mainLabel + ".");
		eval(d + firstFormEleSub + ".focus()");
		return false;
	}

	// check "other specify's"
	if (otherPos.length) {
		var otherChecked, otherSpecValue;

		for (var i = 0; i < otherPos.length; i++) {
			if (eval(d + otherPos[i]))
				otherChecked = eval(d + otherPos[i] + ".checked");
			else
				otherChecked = false;

			if (eval("document." + f + ".q" + otherSpecQnum[i] + "_0"))
				otherSpecValue = eval("document." + f + ".q" + otherSpecQnum[i] + "_0.value");
			else
				otherSpecValue = "";

			if (otherChecked && otherSpecValue.length == 0) {
				alert('You selected "' + otherLabel[i] + '" but did not specify for ' + mainLabel + '. Please enter your response in the space provided.');
				eval("document." + f + ".q" + otherSpecQnum[i] + "_0.focus()");
				return false;
			}
			else if (!otherChecked && otherSpecValue.length > 0) {
				alert('You entered a response for "' + otherLabel[i] + '" but did not select that option for ' + mainLabel + '. Please clarify.');
				eval(d + otherPos[i] + ".focus()");
				return false;
			}
		}
	}

	// check exclusive responses (e.g. none, don't know, etc)
	if (exclPos.length) {
		for (var i = 0; i < exclPos.length; i++) {
			if (eval(d + exclPos[i]) && eval(d + exclPos[i] + ".checked") && nonExclItemChecked[i] == true) {
				alert('You cannot select "' + exclLabel[i] + '" along with other responses for ' + mainLabel + '.');
				eval(d + exclPos[i] + ".focus()");
				return false;
			}
		}
	}

	return true;
}


function openNewWin(url,winName,features) {
	if (!winName)
		winName  = 'Untitled';
	if (!features)
		features = 'scrollbars=yes,resizable=yes,status=no,width=400,height=400';

	var nWin = window.open(url,winName,features);
	nWin.focus();

	return nWin;
}


function trim(trimStr) {
	var trimedStr = rtrim(ltrim(trimStr));
	return trimedStr;
}


function ltrim(trimStr) {
	var trimStrLen = trimStr.length;

	for (var i = 0; i < trimStrLen; i++) {
		var aCharCode = trimStr.charCodeAt(i);
		if (isWhiteSpace(aCharCode) == false)
			break;
	}

	return trimStr.substring(i, trimStrLen);
}


function rtrim(trimStr) {
	var trimStrLen = trimStr.length - 1;

	for (var i = trimStrLen; i > 0; i--) {
		var aCharCode = trimStr.charCodeAt(i);
		if (isWhiteSpace(aCharCode) == false)
			break;
	}

	return trimStr.substring(0, i + 1);
}


function isWhiteSpace(testChar) {
	// White space chars: 9=TAB, 10=LF, 12=FF, 13=CR, 32=Space
	var trimChars = new Array(9,10,12,13,32);
	var wsFound   = false;

	for (var i = 0; i < trimChars.length; i++) {
		if (testChar == trimChars[i]) {
			wsFound = true;
			break;
		}
	}

	return wsFound;
}


function chRowClass(rowId,newClass) {
	var theRow;

	if (document.getElementById)
		theRow = document.getElementById(rowId);

	if (!theRow || typeof(theRow.className) == 'undefined')
		return false;

	theRow.className = newClass;

	return true;
}


function getCkboxValuesStr(f,e,highPos) {
	var d = "document." + f + "." + e;
	var value = "";

	for (var i = 0; i <= highPos; i++) {
		if (eval(d + i) && eval(d + i + ".checked") == true)
			value = value + eval(d + i + ".value");
	}

	return value;
}
