/* Validation script by Arthur Abon */

function ufTrim(asStr)
// Function to trim all leading and trailing spaces.
{
	return asStr.replace(/^\s+/,'').replace(/\s+$/,'');
}

function ufGetParam(asStr,asFlag)
// Function to get the parameters associated with the flag. Used by ufValidate()
{
	var liStartPos, liEndPos;
	var lsValue;
	
	liStartPos = asStr.indexOf(asFlag);
	liStartPos = asStr.indexOf('(',liStartPos)+1;
	liEndPos   = asStr.indexOf(')',liStartPos);
	return ufTrim(asStr.substring(liStartPos,liEndPos));
}

function ufLuhnCheck(asCardNum)
// Function for verifying Credit Card numbers
{
	var liNumOfDigit = asCardNum.length;
	var lbOddEven = liNumOfDigit & 1;
	var liSum = 0;

	for(var liCtr=0; liCtr<liNumOfDigit; liCtr++){
		var liDigit = parseInt(asCardNum.charAt(liCtr));
		if(!((liCtr&1)^lbOddEven)){
			liDigit *= 2;
			if(liDigit>9) liDigit -= 9;
		}
		liSum += liDigit;
	}
	if(liSum % 10 == 0) return true;
	else return false;
}

function ufValidate(asForm)
// Function to validate a form; focuses on first erroneous field found if field is visible
// SYNTAX: ufValidate(asFormName, asFieldName, asFormatFlags, asDisplayName)
{
	var lsField= '', lsDisplay= '', lsFormat= '', lsType= '', lsValue= '', lsTest= '';
	var ldtTest;
	var liStartPos, liEndPos, liTest;
	var lsError = '', lsTemp = '';
	var liMonth = 0, liDay = 0, liYear = 0;
	var objField;

	for(var liCtr=1; liCtr<arguments.length; liCtr = liCtr + 3)
	{
		lsField   = arguments[liCtr];
		lsFormat  = arguments[liCtr + 1];
		lsDisplay = arguments[liCtr + 2];
		
		//Changed eval to new standard in assignment 
		
		//eval('lsValue = '+ asForm +'.'+ lsField +'.value;');
		//eval('lsType  = '+ asForm +'.' + lsField +'.type;');
		
		lsValue = document.getElementById(lsField).value;
		lsType = document.getElementById(lsField).type;
		
				
		// Added less than length checking
		if(lsFormat.indexOf('X')>=0)
		{
			if(lsType.indexOf('select')>=0)
			{
				if(lsValue<=0) 
					lsError = 'Error in ufValidate: ' + lsDisplay + ' cannot have a length.';
			}
			else
			{
				liTest = parseInt(ufGetParam(lsFormat,'X'));
				if((lsValue.length>0)&&(lsValue.length>=liTest)) // do not test 0 length, let R catch that 
					lsError = lsDisplay + ' is required to be less than ' + liTest + ' characters long.';
			}
		}
		if(lsError.length>0) break;
		
		// Added greater than length checking
		if(lsFormat.indexOf('Y')>=0)
		{
			if(lsType.indexOf('select')>=0)
			{
				if(lsValue<=0) 
					lsError = 'Error in ufValidate: ' + lsDisplay + ' cannot have a length.';
			}
			else
			{
				liTest = parseInt(ufGetParam(lsFormat,'Y'));
				if((lsValue.length>0)&&(lsValue.length<=liTest)) // do not test 0 length, let R catch that
					//lsError = lsDisplay + ' is required to have more than ' + liTest + ' characters.';
					lsError = lsDisplay + ' must be at least ' + eval(liTest+1) + ' characters long.';
			}
		}
		if(lsError.length>0) break;
		
		lsValue   = ufTrim(lsValue);
		
		if(lsType.indexOf('select')>=0) 
			//eval('lsValue = '+ asForm +'.'+ lsField +'.selectedIndex;');
			lsValue = document.getElementById(lsField).selectedIndex;
		
		// Check if blank
		if(lsFormat.indexOf('R')>=0)
		{
			if(lsType.indexOf('select')>=0)
			{
				if(lsValue<=0) 
					lsError = lsDisplay + ' is required.';
			}
			else
			{
				if(lsValue.length<=0) 
					lsError = lsDisplay + ' is required.';
			}
		}
		if(lsError.length>0) break;
		
		// Check if date format
		if((lsValue.length>0)&&((lsFormat.indexOf('D')>=0)||(lsFormat.indexOf('B')>=0)||(lsFormat.indexOf('A')>=0)))
		{	
			if(	
				!((lsValue.length==10)||(lsValue.length==8))||
				(lsValue.split('/').length!=3)||
				(lsValue.indexOf('/',0)!=2)||
				(lsValue.indexOf('/',3)!=5)||
				(lsValue.indexOf('/',6)!=(-1))||
				(isNaN(lsValue.split('/')[0]-1))||
				(isNaN(lsValue.split('/')[1]-1))||
				(isNaN(lsValue.split('/')[2]-1))
			  )
				lsError = lsDisplay + ' should be a valid date in the \"mm/dd/yyyy\" format.\n\nExample: 09/27/1997';

			ldtTest = new Date(lsValue);
			if(parseFloat(lsValue.split('/')[0])!=(ldtTest.getMonth()+1)){
				lsError = lsDisplay + ' should be a valid date in the \"mm/dd/yyyy\" format.\n\nExample: 09/27/1997';
			}
			if(isNaN(ldtTest)) {
				lsError = lsDisplay + ' should be a valid date in the \"mm/dd/yyyy\" format.\n\nExample: 09/27/1997';
			}
		}
		if(lsError.length>0) break;
		
		// Check if numeric
		if((lsValue.length>0)&&((lsFormat.indexOf('N')>=0)||(lsFormat.indexOf('P')>=0)||(lsFormat.indexOf('I')>=0)||(lsFormat.indexOf('G')>=0)||(lsFormat.indexOf('C')>=0)||(lsFormat.indexOf('L')>=0)))
		{
			lsTest = lsValue.replace(/[a-zA-Z]/g,'**').replace(/[^\-\d\.]/g,'**');
			if(isNaN(parseFloat(lsValue))||(lsTest.indexOf('**')>=0))
				lsError = lsDisplay + ' should be numeric.';
		}
		if(lsError.length>0) break;
		
		//Check if integer
		if((lsValue.length>0)&&(lsFormat.indexOf('I')>=0))
		{
			lsTest = lsValue.replace(/[a-zA-Z]/g,'**').replace(/[^\-\d]/g,'**');
			if(isNaN(parseFloat(lsValue))||(lsTest.indexOf('**')>=0))
				lsError = lsDisplay + ' should be an integer.';
		}

		// Check if valid credit card
		if((lsValue.length>0)&&(lsFormat.indexOf('C')>=0))
		{
			if(!ufLuhnCheck(lsValue))
				lsError = lsDisplay + ' should be a valid credit card number.';
			if((lsValue.length<13)||(lsValue.length>16))
				lsError = lsDisplay + ' should be a valid credit card number.';
		}
		
		// Check if email
		if((lsValue.length>0)&&(lsFormat.indexOf('E')>=0))
		{
			// Replaced with better regular expression
			if(lsValue.match(/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/)==null) 
			//if(lsValue.match(/.+[@].+[\.].{3,}/)==null) 
				lsError = lsDisplay + ' should be a valid e-mail address.';
				//alert(lsValue);
				//alert(lsField);
		}
		if(lsError.length>0) break;
		
		// Check if phone number
		if((lsValue.length>0)&&(lsFormat.indexOf('P')>=0))
		{
			// Replaced with better regular expression
			if(lsValue.match(/(^\(\+?\d+\)\s?\d{3}\-?\d{4}$)|(^\+?\d*\-?\d{3}\-?\d{4}$)/)==null)
				lsError = lsDisplay + ' should be a valid phone number.\n\nEx. \n\n   9999999999\n';
				
		}
		if(lsError.length>0) break;
		
		// Check if greater than
		if((lsValue.length>0)&&(lsFormat.indexOf('G')>=0))
		{
			liTest = parseFloat(ufGetParam(lsFormat,'G'));
			if(isNaN(liTest)) 
				lsError = 'Error in function ufValidate parameter G.';
			else
			{
				if((parseFloat(lsValue)<=liTest)&&((lsValue.length>0)&&(lsFormat.indexOf('L')>=0)))
					lsError = lsDisplay + ' should be between the numbers ' + (liTest) + ' and ' + (parseFloat(ufGetParam(lsFormat,'L'))) +'.';
				else if(parseFloat(lsValue)<=liTest)
					lsError = lsDisplay + ' should be greater than ' + liTest + '.';
			}
		}
		if(lsError.length>0) break;
		
		// Check if less than
		if((lsValue.length>0)&&(lsFormat.indexOf('L')>=0))
		{
			liTest = parseFloat(ufGetParam(lsFormat,'L'));
			if(isNaN(liTest)) 
				lsError = 'Error in function ufValidate parameter L.';
			else
			{
				if((parseFloat(lsValue)>=liTest)&&((lsValue.length>0)&&(lsFormat.indexOf('G')>=0)))
					lsError = lsDisplay + ' should be between the numbers ' + (parseFloat(ufGetParam(lsFormat,'G'))) + ' and ' + (liTest) +'.';
				else if(parseFloat(lsValue)>=liTest)
					lsError = lsDisplay + ' should be less than ' + liTest + '.';
			}
		}
		if(lsError.length>0) break;
		
		// Check if before
		if((lsValue.length>0)&&(lsFormat.indexOf('B')>=0))
		{
			ldtTest = ufGetParam(lsFormat,'B')
			ldtTest = new Date(ldtTest);
			if(isNaN(ldtTest)) 
				lsError = 'Error in function ufValidate parameter B.';
			else
			{
				lsTemp = lsValue;
				lsValue = new Date(lsValue);
				if((lsValue.valueOf() >= ldtTest.valueOf())&&(lsFormat.indexOf('A')>=0))
					lsError = lsDisplay + ' should be a date between ' + ufGetParam(lsFormat,'A') + ' and ' + ufGetParam(lsFormat,'B') + '.';
				else if(lsValue.valueOf() >= ldtTest.valueOf())
					lsError = lsDisplay + ' should be a date before ' + ufGetParam(lsFormat,'B') + '.';
			}
			lsValue = lsTemp
		}
		if(lsError.length>0) break;
		
		// Check if later
		if((lsValue.length>0)&&(lsFormat.indexOf('A')>=0))
		{
			ldtTest = new Date(ufGetParam(lsFormat,'A'));
			if(isNaN(ldtTest)) 
				lsError = 'Error in function ufValidate parameter A.';
			else
			{
				lsValue = new Date(lsValue);
				if((lsValue.valueOf() <= ldtTest.valueOf())&&(lsFormat.indexOf('B')>=0))
					lsError = lsDisplay + ' should be a date between ' + ufGetParam(lsFormat,'A') + ' and ' + ufGetParam(lsFormat,'B') + '.';
				else if(lsValue.valueOf() <= ldtTest.valueOf())
					lsError = lsDisplay + ' should be a date after ' + ufGetParam(lsFormat,'A') + '.';
			}
		}
		if(lsError.length>0) break;
	}// end for

	if(lsError.length>0)
	{
		alert(lsError);
		if(lsType != 'hidden')
			//eval(asForm + '.' + lsField + '.focus();');
			document.getElementById(lsField).focus();
		return false;
	}
	else
	{
		for(liCtr=0; liCtr<document.getElementById(lsField).length;liCtr = liCtr + 1)
		{
			objField = eval(asForm+'.elements['+liCtr+']');
		}
		return true;
	}
}
