
function isEmpty(s){   
	return ((s == null) || (s.length == 0))
}

function isWhitespace (s){
	var whitespace = " \t\n\r";
    var i;
    if (isEmpty(s)) return true;
		for (i = 0; i < s.length; i++){   
		    var c = s.charAt(i);
		    if (whitespace.indexOf(c) == -1) return false;
		}
    return true;
}

function stripCharsInBag (s, bag){
    var i;
    var returnString = "";
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }

    return returnString;
}

function stripCharsNotInBag (s, bag){
    var i;
    var returnString = "";

    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) != -1) returnString += c;
    }

    return returnString;
}


function isDigit (c){
   return ((c >= "0") && (c <= "9"))}
function isLetter (c){   
	return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )}
function isLetterOrDigit (c){
    return (isLetter(c) || isDigit(c))}

function reformatZIPCode (ZIPString){
    if (ZIPString.length == 5) return ZIPString;
    else return (reformat (ZIPString, "", 5, "-", 4));}
function reformatUSPhone (USPhone){
    return (reformat (USPhone, "(", 3, ") ", 3, "-", 4))}
function reformatSSN (SSN){   
	return (reformat (SSN, "", 3, "-", 2, "-", 4))}
function reformatCCNum (CCNum){   
	return (reformat (CCNum, "", 4, "-", 4, "-", 4, "-", 4))}

function reformat (s)
{   var arg;
    var sPos = 0;
    var resultString = "";
    for (var i = 1; i < reformat.arguments.length; i++) {
       arg = reformat.arguments[i];
       if (i % 2 == 1) resultString += arg;
       else {
           resultString += s.substring(sPos, sPos + arg);
           sPos += arg;
       }
    }
    return resultString;
}

//Top Level Functions 
function isRequired(arrFields){
	var RetString = '';
	if (arrFields.length > 0)	{
		for (var i = 0; i < arrFields.length; i++){
			if (isWhitespace(arrFields[i].value)){
			RetString += arrFields[i].title + ' is required.' + '\n';}
		}	
	}
	return (RetString);
}

//Top Level Functions 
function isRequiredSpecial(arrFields){
	var RetString = '';
	if (arrFields.length > 0)	{
		for (var i = 0; i < arrFields.length; i++){
			if (isWhitespace(arrFields[i].value)){
			RetString += arrFields[i].title + ' is required if an optional sort field is selected.' + '\n';}
		}	
	}
	return (RetString);
}

function isStrictlyAlpha(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			for (var j=0; j < CurrString.length; j++){
				if (!(isLetter(CurrString.charAt(j)))){
				RetString += arrFields[i].title + ' may contain only letters.' + '\n';
				break;
				}
			}
		}	
	}
	return (RetString);
}

function isStrictlyAlphaNumeric(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			for (var j=0; j < CurrString.length; j++){
				if (!(isLetter(CurrString.charAt(j)) || isDigit(CurrString.charAt(j))))	{
				RetString += arrFields[i].title + ' may contain only letters or numbers.' + '\n';
				break;
				}
			}					
		}	
	}
	return (RetString);
}

function isAlpha(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				for (var j=0; j < CurrString.length; j++){
					if ((CurrString.charCodeAt(j)< 32) ||((CurrString.charCodeAt(j)> 47)&& (CurrString.charCodeAt(j)< 58)) ||(CurrString.charCodeAt(j)> 126)){
					RetString += arrFields[i].title + ' may contain only non-numeric characters.' + '\n';
					break;
					}
				}					
			}
		}	
	}
	return (RetString);
}


function isAlphaNumeric(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				for (var j=0; j < CurrString.length; j++){
					if ((CurrString.charCodeAt(j)< 32) ||(CurrString.charCodeAt(j)> 126)){
					RetString += arrFields[i].title + ' may contain only letters, numbers or spaces.' + '\n';
					break;
					}
				}					
			}
		}	
	}
	return (RetString);
}

function isStrictlyNumeric(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			for (var j=0; j < CurrString.length; j++){
				if (!(isDigit(CurrString.charAt(j)))){
				RetString += arrFields[i].title + ' may only contain numbers.' + '\n';
				break;
				}
			}
		}	
	}
	return (RetString);
}

function isPosNumeric(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				if (isNaN(Number(CurrString))){
					RetString += arrFields[i].title + ' may only be a positive number.' + '\n';
				}
				else {
					if (Number(CurrString) < 0){
						RetString += arrFields[i].title + ' may only be a positive number.' + '\n';
					}
				}			
			}
		}	
	}
	return (RetString);
}

function isInteger(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				if ((parseInt(CurrString) != CurrString)){
					RetString += arrFields[i].title + ' may only be a whole number.' + '\n';
				}
			}
		}	
	}
	return (RetString);
}

function isDecimal(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				if  ((isNaN(Number(CurrString))) || (CurrString.indexOf('.')== -1) ){
					RetString += arrFields[i].title + ' must be a decimal number.' + '\n';
				}
			}
		}	
	}
	return (RetString);
}

function isPosDecimal(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				if  ( (isNaN(Number(CurrString))) || (CurrString.indexOf('.')== -1) || (Number(CurrString) < 0) ){
					RetString += arrFields[i].title + ' must be a positive decimal number.' + '\n';
				}
			}
		}	
	}
	return (RetString);
}

function isGreaterThan(arrFields, arrLBounds){
	var RetString = '';
	var sCurrNumber = '';
	var CurrNumber = 0;
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrNumber = Number(arrFields[i].value);
			
			switch (typeof arrLBounds[i]){
			case "string" :
				sCurrNumber = String(arrLBounds[i]);
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(Number(arrLBounds[i]))) || (CurrNumber <= Number(arrLBounds[i])) ){
					RetString += arrFields[i].title + ' must be a number greater than ' + sCurrNumber + '.\n';
				}
				break;
			case "object" :
				sCurrNumber = arrLBounds[i].title;	
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(parseFloat(arrLBounds[i].value))) || (CurrNumber <= arrLBounds[i].value) ){
					RetString += arrFields[i].title + ' must be a number greater than ' + sCurrNumber + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isLessThan(arrFields, arrUBounds){
	var RetString = '';
	var sCurrNumber = '';
	var CurrNumber = 0;
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrNumber = Number(arrFields[i].value);
			
			switch (typeof arrUBounds[i]){
			case "string" :
				sCurrNumber = String(arrUBounds[i]);
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(Number(arrUBounds[i]))) || (CurrNumber >= Number(arrUBounds[i])) ){
					RetString += arrFields[i].title + ' must be a number less than ' + sCurrNumber + '.\n';
				}
				break;
			case "object" :
				sCurrNumber = arrUBounds[i].title;	
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(parseFloat(arrUBounds[i].value))) || (CurrNumber >= arrUBounds[i].value) ){
					RetString += arrFields[i].title + ' must be a number less than ' + sCurrNumber + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isBetween(arrFields, arrLBounds, arrUBounds){
	var RetString = '';
	var sUNumber = '';
	var sLNumber = '';
	var CurrNumber = 0;
	var LNumber = 0;
	var UNumber = 0;
	
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrNumber = parseFloat(Number(arrFields[i].value));
			
			switch (typeof arrUBounds[i]){
			case "string" :
				sUNumber = String(arrUBounds[i]);
				UNumber = parseFloat(Number(arrUBounds[i]));
				
				switch (typeof arrLBounds[i]){
				case "string" :
					LNumber = parseFloat(Number(arrLBounds[i]));
					sLNumber = String(arrLBounds[i]);
				break;
				case "object" :
					LNumber = parseFloat(arrLBounds[i].value);
					sLNumber = arrLBounds[i].title;
				break;
				}
			break;	
				
			case "object" :
				sUNumber = arrUBounds[i].title;
				UNumber = parseFloat(arrUBounds[i].value);
				
				switch (typeof arrLBounds[i]){
				case "string" :
					LNumber = parseFloat(Number(arrLBounds[i]));
					sLNumber = String(arrLBounds[i]);
				break;
				case "object" :
					LNumber = parseFloat(arrLBounds[i].value);
					sLNumber = arrLBounds[i].title;
				break;
				}
			break;	
			}
			
			if ((isNaN(CurrNumber)) || 
				(isNaN(LNumber)) || 
				(isNaN(UNumber)) || 
				(!((CurrNumber > LNumber) && (CurrNumber < UNumber ))) 
				){		
				RetString += arrFields[i].title + ' must be a number between ' + sLNumber + ' and ' + sUNumber + '.\n';
			}

		}
	}
	return (RetString);
}

function isEqual(arrFields1, arrFields2){
	var RetString = '';
	var sCurrNumber = '';
	var CurrNumber = 0;
	if (arrFields1.length > 0){
		for (var i = 0; i < arrFields1.length; i++){
			CurrNumber = Number(arrFields1[i].value);
			
			switch (typeof arrFields2[i]){
			case "string" :
				sCurrNumber = String(arrFields2[i]);
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(Number(arrFields2[i]))) || (CurrNumber != Number(arrFields2[i])) ){
					RetString += arrFields1[i].title + ' must be a number equal to ' + sCurrNumber + '.\n';
				}
				break;
			case "object" :
				sCurrNumber = arrFields2[i].title;	
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(parseFloat(arrFields2[i].value))) || (CurrNumber != arrFields2[i].value) ){
					RetString += arrFields1[i].title + ' must be a number equal to ' + sCurrNumber + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isNotEqual(arrFields1, arrFields2){
	var RetString = '';
	var sCurrNumber = '';
	var CurrNumber = 0;
	if (arrFields1.length > 0){
		for (var i = 0; i < arrFields1.length; i++){
			CurrNumber = Number(arrFields1[i].value);
			
			switch (typeof arrFields2[i]){
			case "string" :
				sCurrNumber = String(arrFields2[i]);
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(Number(arrFields2[i]))) || (CurrNumber == Number(arrFields2[i])) ){
					RetString += arrFields1[i].title + ' cannot be a number equal to ' + sCurrNumber + '.\n';
				}
				break;
			case "object" :
				sCurrNumber = arrFields2[i].title;	
				if ( (isNaN(parseFloat(CurrNumber))) || (isNaN(parseFloat(arrFields2[i].value))) || (CurrNumber == arrFields2[i].value) ){
					RetString += arrFields1[i].title + ' cannot be a number equal to ' + sCurrNumber + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isEqualString(arrFields1, arrFields2){
	var RetString = '';
	var CurrTitle = '';
	var CurrString = '';
	if (arrFields1.length > 0){
		for (var i = 0; i < arrFields1.length; i++){
			CurrString = arrFields1[i].value;
			
			switch (typeof arrFields2[i]){
			case "string" :
				CurrTitle = arrFields2[i];
				if (CurrString != arrFields2[i]){
					RetString += arrFields1[i].title + ' must equal ' + CurrTitle + '.\n';
				}
				break;
			case "object" :
				CurrTitle = arrFields2[i].title;	
				if (CurrString != arrFields2[i].value){
					RetString += arrFields1[i].title + ' must equal ' + CurrTitle + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isNotEqualString(arrFields1, arrFields2){
	var RetString = '';
	var CurrTitle = '';
	var CurrString = '';
	if (arrFields1.length > 0){
		for (var i = 0; i < arrFields1.length; i++){
			CurrString = arrFields1[i].value;
			
			switch (typeof arrFields2[i]){
			case "string" :
				CurrTitle = arrFields2[i];
				if (CurrString == arrFields2[i]){
					RetString += arrFields1[i].title + ' cannot be equal to ' + CurrTitle + '.\n';
				}
				break;
			case "object" :
				CurrTitle = arrFields2[i].title;	
				if (CurrString == arrFields2[i].value){
					RetString += arrFields1[i].title + ' cannot be equal to ' + CurrTitle + '.\n';
				}
				break;
			}
			
		}
	}
	return (RetString);
}

function isMinLength(arrFields, arrLBounds){
	var RetString = '';
	var CurrString = '';
	var CurrLBound = 0;
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			CurrLBound = Number(arrLBounds[i]);
			if (CurrString.length > 0){
				if (CurrString.length < CurrLBound){
					RetString += arrFields[i].title + ' must have at least ' + String(CurrLBound) + ' characters.\n';
				}
			}	
		}
	}
	return (RetString);
}

//isEmail
// must be at least one character before the @
// must be at least one character before and after the .
// characters @ and . are both required
// no spaces in the address are allowed

function isEmail(arrFields){

	var RetString = '';
	var CurrString = '';
	var errEmail = false;
	if ((arrFields.length) != 0){
		for (var j = 0; j < arrFields.length; j++){
			CurrString = arrFields[j].value;

			if (!(isWhitespace(CurrString))){
				var i = 1;
				var sLength = CurrString.length;
				
				// there must be >= 1 character before @, so we
				// start looking at character position 1 
				// look for @, sets i = to char position of '@'
				while ((i < sLength) && (CurrString.charAt(i) != "@")){
				 i++
				}
				
				// if i=sLength - there are no characters after the '@'
				// or if there is no '@'
				if ((i >= sLength) || (CurrString.charAt(i) != "@")) errEmail = true;
				else i += 2;
			
				// look for '.' after the '@'
				while ((i < sLength) && (CurrString.charAt(i) != "."))
				{ i++
				}
				// there must be at least one character after the '.'
				if ((i >= sLength - 1) || (CurrString.charAt(i) != ".")) errEmail = true;
				
				// there may be no spaces in the address
				if (CurrString.indexOf(' ') != -1) errEmail = true;
			
				if (errEmail){
					RetString += arrFields[j].title + ' is not a valid email address format' +  '.\n';
					errEmail = false;
				}
			}	
		}
	}
	return (RetString);
}


    

function isUSPhone(arrFields){
	var RetString = '';
	var CurrString = '';
	if ((arrFields.length) != 0){
		for (var i = 0; i < arrFields.length; i++){
		CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				CurrString = stripCharsNotInBag(CurrString,'0987654321');
				if (!(CurrString.length == 10)){
					RetString += arrFields[i].title + ' must have Area Code & Phone Number, ex.(800) 555-1212' +  '.\n';
				}
				else arrFields[i].value = reformatUSPhone(CurrString)
			}		
		}
	}
	return (RetString);
}

function isSSN(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length != 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				CurrString = stripCharsNotInBag(CurrString,'0987654321');
				if (CurrString.length != 9){
					RetString += arrFields[i].title + ' is not a valid Social Security Number format.' +  '.\n';
				}
				else arrFields[i].value = reformatSSN(CurrString);
			}		
		}
	}
	return (RetString);
}

function isCCNum(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length != 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				CurrString = stripCharsNotInBag(CurrString,'0987654321');
				if (CurrString.length != 16){
					RetString += arrFields[i].title + ' is not a valid Credit Card Number format.' +  '.\n';
				}
				else arrFields[i].value = reformatCCNum(CurrString);
			}		
		}
	}
	return (RetString);
}

function isCreditCard(arrFields) {
	var RetString = '';
	var CurrString = '';
	if (arrFields.length != 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			CurrString = stripCharsNotInBag(CurrString,'0987654321');
			if ( (isWhitespace(CurrString))||(CurrString.length != 16) ) {
				break;
			}
			
			var sum = 0; var mul = 1; l = CurrString.length;
			for (j = 0; j < l; j++) {
			  var digit = CurrString.substring(l-j-1,l-j);
			  var tproduct = parseInt(digit ,10)*mul;
			  if (tproduct >= 10)
			    sum += (tproduct % 10) + 1;
			  else
			    sum += tproduct;
			  if (mul == 1)
			    mul++;
			  else
			    mul--;
			}
			
			if (!((sum % 10) == 0)){
			  RetString += arrFields[i].title + ' is not a valid Credit Card Number.' +  '.\n';
			}
		}
	}
	return (RetString);		
} 


function isCCExpDate(arrMonth, arrYear){
	var RetString = '';
	var dToday = new Date()
	var CurrMonth = 0;
	var CurrYear = 0;
	if (arrMonth.length != 0){
		for (var i = 0; i < arrMonth.length; i++){
			CurrMonth = Number(arrMonth[i].value);
			CurrYear = Number(arrYear[i].value);
			if ( (isNaN(CurrMonth)) || (isNaN(CurrYear)) ){
				RetString += 'Please Select Credit Card Exp. Month/Year' +  '.\n';	
			}
			if ( (CurrYear < dToday.getFullYear()) || ((CurrYear == dToday.getFullYear()) && (CurrMonth < dToday.getMonth())) ){
				RetString += 'Credit Card Exp. Month/Year has already passed' +  '.\n';
			}
		}
	}
	return (RetString);
}

function isZipCode(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length != 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (!(isWhitespace(CurrString))){
				if ((CurrString.length != 5) && (CurrString.length != 9)){
					RetString += arrFields[i].title + ' is not a valid Zip Code format.' +  '.\n';
				}
				else arrFields[i].value = reformatZIPCode(CurrString);
			}		
		}
	}
	return (RetString);
}

function isDollar(arrFields){
	var RetString = '';
	var CurrString = '';
	var nDecimalPos = 0;
	var sLength = 0;
	var j = 0;
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			CurrString = stripCharsNotInBag(CurrString,'.0987654321');
			sLength = CurrString.length
			if (!(isWhitespace(CurrString))){
			
			while ((j < sLength) && (CurrString.charAt(j) != "."))
				{ j++
				}
			
				if  ( (isNaN(Number(CurrString))) || (CurrString.indexOf('.')== -1) || (Number(CurrString) < 0) || ((sLength - j) != 3 )){
					RetString += arrFields[i].title + ' must be in dollar format (ex. 21.00).' + '\n';
				}
				else arrFields[i].value = CurrString
			}
		}	
	}
	return (RetString);
}

function isChecked(arrFields){
	var RetString = '';
	var CurrCheck = '';
	var cnt = 0;
	var sTitle = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			if (arrFields[i] != null){
				var max = arrFields[i].length - 1;
				CurrCheck = arrFields[i];
				if (arrFields[i].length != null){
					for(j=0; j<=max; j++){
						if (CurrCheck[j].checked){
						    cnt++;
						}
					}
				}else{
					if (CurrCheck.checked){
					   cnt++;
					}
				}
				if (cnt < 1){
					if (CurrCheck.title != null){
						RetString += CurrCheck.title + ' must have at least one selection.' + '\n';
					}else{
						RetString += CurrCheck[max].title + ' must have at least one selection.' + '\n';
					}
					break;
				}
			}
		}
	}
	return (RetString);
}

function isSelected(arrFields){
	var RetString = '';
	var CurrTitle = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			CurrString = arrFields[i].value;
			if (CurrString == '0'){
				RetString += arrFields[i].title + ' must be selected.\n';
			}
		}
	}
	return (RetString);
}

function isSearchString(arrFields){
	var RetString = '';
	var CurrString = '';
	if (arrFields.length > 0){
		for (var i = 0; i < arrFields.length; i++){
			var count = 0;
			CurrString = arrFields[i].value;
			if (CurrString.length > 0) {
				for (var j=1; j < CurrString.length-2; j++){
					if (!(isLetter(CurrString.charAt(j)))){
						count = 1;
						break;
					}
				}
				if (!(isLetter(CurrString.charAt(0)))){
					if(CurrString.charAt(0) != "*"){
						count = 1;
					}
				}
				if (!(isLetter(CurrString.charAt(CurrString.length-1)))){
					if(CurrString.charAt(CurrString.length-1) != "*"){
						count = 1;
					}
				}
			}
			if (count > 0){
				RetString += arrFields[i].title + ' is not a valid entry.' + '\n';
			}
		}	
	}
	return (RetString);
}