var garrErrorMessage;		// Error message array.
var gstrErrorMessage;		// Last error message.

// Error array column constant.
var errELEMENTID = 0;			
var errLABEL = 1;				
var errMESSAGE = 2;			


/******************************************************************************
	Purpose:		Common validator function to loop through all form elements
							to call the ValidateElement function. 

	Parameters: 

	Returns:		An array of error messages.

	By: KRB 21 Oct 2002: Reworked original for ALIRTS v2
******************************************************************************/

function CommonValidator() {
	var objForm; 
	var objElement;
			
			// Reset Error array
			garrErrorMessage = new Array();

 			for (var i=0; i < document.forms.length; i++) {
				objForm = document.forms(i);
				
				/*	.elements collection contains all button, input, select, and textarea elements on form
					type descriptions: button = button;textarea = textarea;select = select-one;input(submit) = submit;input(text) = text;input(password) = password
				*/
				for (var j=0; j < objForm.elements.length; j++) {
					objElement = objForm.elements(j);
					
					//alert("Debug: [" + j + "] " +  pobjElement.name + " = " + pobjElement.type);
					
					// Validate each element
					strErrorMsg = ValidateElement( objElement );
					
					if (strErrorMsg.length > 0) {
						 BuildErrorMsg(objElement, strErrorMsg);
					}
		
				}// elements on form loop
			}// forms on document loop
							
	return true;
}

/******************************************************************************
	Purpose:		Check for v_* attributes to perform client side
							input validation.

	Parameters: pobjElement = element to validate

	Returns:		String with error message.

	By: KRB 21 Oct 2002: Reworked original for ALIRTS v2
******************************************************************************/

function ValidateElement( pobjElement ) {
  var expSpaces = /^(\s*)$/;			//regular expression search for spaces
  var expCommas = /[,]/g;					//regular expression search for commas globally
  var pstrValue;

	// Check Input text elements
	if (pobjElement.type == 'text' || pobjElement.type == 'password' || pobjElement.type == 'textarea') {
							
		// Check to see if it is blank.  						
		if (pobjElement.v_isRequired == 'true')  {

			// Strip spaces.
			pstrValue = pobjElement.value;
			pstrValue = pstrValue.replace(expSpaces, '');
			
			if( pstrValue.length == 0) {
 				return 'Input entry is required.';
			}
		}
		
		// Check maximum length
		if ((pobjElement.value != '') && (pobjElement.value.length > pobjElement.v_maxLength) ) {
			return 'Input entry exceeds maximum length allowed of ' + pobjElement.v_maxLength;
		}

		// Check value is numeric
		if (pobjElement.v_isNumeric == 'true' && pobjElement.value != '' && !isNumeric(pobjElement.value, pobjElement.v_numDigits, pobjElement.v_numDecimals, pobjElement.v_numCommas)) {
			return 'Input entry requires a valid numeric value and format.';
		} 
		
		// Check max and min values once v_isNumeric has passed.
		if (pobjElement.v_isNumeric == 'true')
		{

			// Check Maximum value
			if (pobjElement.v_numMax) {
			
				// Strip commas from value
				pstrValue = pobjElement.value;
				pstrValue = pstrValue.replace(expCommas,'');
				
				if (parseFloat(pstrValue) > parseFloat(pobjElement.v_numMax)) {
					return 'Input entry requires a value less than or equal to ' + pobjElement.v_numMax + '.';
				}
			}
		
			// Check Minimum value
			if (pobjElement.v_numMin) {
			
				// Strip commas from value
				pstrValue = pobjElement.value;
				pstrValue = pstrValue.replace(expCommas,'');
				
				if (parseFloat(pstrValue)  < parseFloat(pobjElement.v_numMin)) {
					return 'Input entry requires a value greater than or equal to ' + pobjElement.v_numMin + '.'; 
				}
			}
		}
		
		// Check date
		if (pobjElement.v_isDate == 'true') {
				if (pobjElement.value != '' ){

					if ( !isDate(pobjElement.value, pobjElement.v_dtSeparator, pobjElement.v_dtMin, pobjElement.v_dtMax) ){
						return gstrErrorMessage;
					}
				}
		}

		// Check value is URL
		if (pobjElement.v_isURL == 'true' && pobjElement.value != '' && !isURL(pobjElement.value)) {
			return 'Input entry requires a valid URL address.';
		} 

		// Check value is Phone
		if (pobjElement.v_isPhone == 'true' && pobjElement.value != '' && !isPhone(pobjElement.value)) {
			return 'Input entry requires a valid phone number in the format: (999)999-9999 x9999.';
		} 
		
		// Check value is Zip
		if (pobjElement.v_isZip == 'true' && pobjElement.value != '' && !isZip(pobjElement.value)) {
			return 'Input entry requires a valid zipcode in the format: 99999-9999.';
		} 

	}//end if input element

	// Check Select element
	if (pobjElement.type == "select-one") {
		//*** Code for 'Select' string in description text
		//var sOptionText = pobjElement.options[pobjElement.selectedIndex].text;						
		//if (pobjElement.v_isRequired == 'true' &&  sOptionText.indexOf('Select') > -1  ) {
		
		if (pobjElement.v_isRequired == 'true' && pobjElement.options[pobjElement.selectedIndex].value == 0  ) {
			return 'Input entry requires a selection.';
		}
	}
	
	return '';					
					
}

/******************************************************************************
	Purpose:		Builds the common validator's error message array.

	Parameters: pobjElement - Element validated
							pstrErrorMsg - Error Message

	Returns:		true 

	By: KRB 21 Oct 2002: Reworked original for ALIRTS v2
******************************************************************************/
function BuildErrorMsg(pobjElement, pstrErrorMsg) {
	
	// Add Validation Error Message to array
	garrErrorMessage[garrErrorMessage.length] = Array(pobjElement.id, pobjElement.v_Label, pstrErrorMsg)

	return true;
}

/******************************************************************************
	Purpose:		Validates a date value with various seperators.  The
							dates must be entered with 4 digit year.  This method
							tested correctly for leap years.
							Dates are assumed to be in US format MM/DD/YYYY

	Parameters: pstrDate - String date value to check
							pstrSep - Optional. Seperator to split date parts.
							pstrMinDate - Optional. Beginning date range.
							pstrMaxDate - Optional. Ending date range.

	Returns:		True if valid, otherwise false.

	By: KRB 06 Dec 2001: Original build and test of function.
		KRB 07 Oct 2002: Modified for optional pstrSep, pstrMinDate, pstrMaxDate
		KRB 02 Mar 2005: Fixed bug if input is 09 for month by adding radix 
						 parameter = 10 on parseInt function
******************************************************************************/
function isDate(pstrDate, pstrSep, pstrMinDate, pstrMaxDate) {
	var dtMin, dtMax

	// Set optional parameter default values.	
	pstrSep = pstrSep == undefined ? '/': pstrSep; 
	
	if (pstrMinDate == undefined) {
		dtMin = new Date('01/01/1900')
	}
	else {
	  dtMin = new Date(pstrMinDate)
	}
	
	if (pstrMaxDate == undefined) {
		dtMax = new Date('12/31/2099')
	}
	else {
	  dtMax = new Date(pstrMaxDate)
	}
 
	// Split the date parts into an array.
	var arrDateParts = pstrDate.split(pstrSep);

	// Confirm there are 3 parts to the date.
	if (arrDateParts.length != 3) {
		gstrErrorMessage = 'Input entry requires a date value in the format of MM' + pstrSep + 'DD' + pstrSep + 'YYYY.';
		return false;
	}
	
	// Retrieve individual date values.
	var intDate = parseInt(arrDateParts[1],10);
	var intMonth = parseInt(arrDateParts[0],10);
	var intYear = parseInt(arrDateParts[2],10);
	
	// Create date object with passed date.
	var dtValue = new Date(pstrDate);
		
	// Compare the split values with what date object has.  The date objects month 
	// value is 0-11, so subtract 1. 
	if ( intDate != dtValue.getDate() || intMonth-1 != dtValue.getMonth() || intYear != dtValue.getFullYear() ) {
		gstrErrorMessage = 'Input entry requires a date value in the format of MM' + pstrSep + 'DD' + pstrSep + 'YYYY.';
		return false;
	}

	// Check date within date range. 
	if (dtValue < dtMin ) {
		gstrErrorMessage =  'Date must be later than or equal to ' + (dtMin.getMonth()+1) + pstrSep + dtMin.getDate() + pstrSep + dtMin.getFullYear() + '.';
		return false;
	}
	if (dtValue > dtMax) {
		gstrErrorMessage =  'Date must be earlier than or equal to ' + (dtMax.getMonth()+1) + pstrSep + dtMax.getDate() + pstrSep + dtMax.getFullYear() + '.';
		return false;
	}
	
	// Made it through isDate() validation.			
	gstrErrorMessage = '';
	return true;
}


/******************************************************************************
	Purpose:		Validates that a string contains only valid numbers, 
							commas are allowed.  Uses the regular expression object
							to validate number.  
							Examples
							1,234.56		Precision = 6, Scale = 2

	Parameters: 	
		pstrValue - String to be tested for validity
		pintPrecision - Optional. The maximum number of digits allowed
		pintScale - Optional. The maximum number of decimal places to allowed
		blnAllowCommas - Optional. Allow commas.

	Returns:		True if valid, otherwise false.

	By: KRB 12 Aug 2002:  Converted to regular expression logic and 
												test of function.
			KRB 19 Aug 2002:  Added Precision check
			KRB 29 Aug 2002:  Added Optional allow commas
			
******************************************************************************/
function  isNumeric( pstrValue , pintPrecision, pintScale, pblnAllowCommas) {
	var expNumber = /(^[-]{0,1}([.]\d{1,}){1}$)|(^[-]{0,1}\d{1,}([.]\d{0,}){0,1}$)|(^[-]{0,1}\d{1,3}([,]\d{3})*([.]\d{0,}){0,1}$)/; 
	var expCommas = /[,]/g;
	var expPeriods = /[.]/g;
	var blnResult
	var blnAllowCommas
	
	//alert( pstrValue + ", " + pintPrecision + ", " + pintScale +  ", " + pblnAllowCommas);
	
	// convert passed parameter to boolean data type.
	if (pblnAllowCommas == 'true' || pblnAllowCommas == true ) {
		blnAllowCommas = true;
	}
	else {
		blnAllowCommas = false;
	}
		
	// no scale is an integer
	if (pintScale == 0) {
		if (blnAllowCommas == true) 
			expNumber =  /(^[-]{0,1}\d{1,}[.]{0,1}$)|(^[-]{0,1}\d{1,3}([,]\d{3})*[.]{0,1}$)/; 
		else 
			expNumber =  /(^[-]{0,1}\d{1,}[.]{0,1}$)/; 
					
	} 
	// decimal places specified
	else if (pintScale > 0) {
		if (blnAllowCommas == true) 
			expNumber.compile('(^[-]{0,1}([.]\\d{1,' + pintScale + '}){1}$)|(^[-]{0,1}\\d{1,}([.]\\d{0,' + pintScale + '}){0,1}$)|(^[-]{0,1}\\d{1,3}([,]\\d{3})*([.]\\d{0,' + pintScale + '}){0,1}$)');
		else 
			expNumber.compile('(^[-]{0,1}([.]\\d{1,' + pintScale + '}){1}$)|(^[-]{0,1}\\d{1,}([.]\\d{0,' + pintScale + '}){0,1}$)');
	}
	else
	// no decimal places specified
	{
		if (blnAllowCommas == true) 
			expNumber =  /(^[-]{0,1}([.]\d{1,}){1}$)|(^[-]{0,1}\d{1,}([.]\d{0,}){0,1}$)|(^[-]{0,1}\d{1,3}([,]\d{3})*([.]\d{0,}){0,1}$)/; 
		else 
			expNumber =  /(^[-]{0,1}([.]\d{1,}){1}$)|(^[-]{0,1}\d{1,}([.]\d{0,}){0,1}$)/; 
	}

	//check for numeric characters 
	blnResult = expNumber.test(pstrValue);
			
	// Test Precision Length
	if ( blnResult == true ) {
	
		// Strip commas and periods 
		pstrValue = pstrValue.replace(expCommas,"")
		pstrValue = pstrValue.replace(expPeriods,"")
	
		// Check length
		if ( pstrValue.length > pintPrecision ) {
			blnResult = false;
		}
	}
	
	return blnResult;
}



/******************************************************************************
	Purpose:		Validates that a string contains a valid email pattern.  
							This code is based on an example from www.regxlib.com 
							example.

	Parameters: pstrValue - String to be tested for validity.

	Returns:		True if valid, otherwise false.

	By: KRB 22 Oct 2001: Original build and test of function.
******************************************************************************/
function isEmail( pstrValue) {

  //var expEmail = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/  // Ms.NET Email expresion validator
 
	var expEmail = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/  //from: www.regxlib.com

  //check for valid email
  return expEmail.test(pstrValue);
}


/******************************************************************************
	Purpose:		Validates that a string contains a valid URL address.  
							This code is based on an example from www.regxlib.com 
							example.

	Parameters: pstrValue - String to be tested for validity.

	Returns:		True if valid, otherwise false.

	Comments:   @@@ This routine still has some bugs that need to be worked 
							out.  

	By: KRB 23 Oct 2001: Original build and test of function.
******************************************************************************/
function isURL( pstrValue) {

  var expURL = new RegExp('\w+');
   
  //expURL.compile('^http://([\w-]+\.)+[\w-]+(/[\w- ./&?%=]*)$')  // Ms.NET URL expresion validator
	//var expURL = /^(http|https|ftp)\:[/][/]][a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?([a-zA-Z0-9\-\._\?\,\+\&%\$#\=~])*[^\.\,\)\(\s]$/  //from: www.regxlib.com
  expURL.compile('((http|https|ftp)://)?[a-zA-Z0-9_/\,]+[\.]{1,1}[a-zA-Z0-9\-\._\?\,\+\&%\$#\=~]*')  

  //check for valid email
  return expURL.test(pstrValue);
}


/******************************************************************************
	Purpose:		Validates that a string contains a valid US Phone number.  

	Parameters: pstrValue - String to be tested for validity.

	Returns:		True if valid, otherwise false.

	Comments:   @@@ This routine should have some optional parameters
							for format acceptance.

	By: KRB 23 Oct 2001: Original build and test of function.
******************************************************************************/
function isPhone( pstrValue) {

  var expPhone = /^((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}?[ ]*((x){0,1}([0-9]){1,5}){0,1}$/	// Ms.NET Phone expresion validator

  //check for valid email
  return expPhone.test(pstrValue);
}


/******************************************************************************
	Purpose:	Validates that a string contains a valid US Zipcode.  

	Parameters: pstrValue - String to be tested for validity.

	Returns:	True if valid, otherwise false.

	Comments:   @@@ Add Canadian option

	By: KRB 23 Oct 2001: Original build and test of function.
******************************************************************************/
function isZip( pstrValue) {

  var expZip = /^\d{5}(-\d{4})?$/	// Ms.NET Phone expresion validator

  //check for valid email
  return expZip.test(pstrValue);
}



// Pass through functions to work with .Net validator controls
function validateDate(oSrc, args){
	args.IsValid = isDate(args.Value, '/');
}
			
function validatePhone(oSrc, args){
	args.IsValid = isPhone(args.Value);
}

function validateZip(oSrc, args){
	args.IsValid = isZip(args.Value);
}

