//------------------------------------------------------------------------------------
// function: isWhiteSpace
//           Function to check whether the given argument consists of charactes other
//           than a space and \t
//------------------------------------------------------------------------------------
function isWhiteSpace(argWhiteSpace) {
	argWs = argWhiteSpace.toString()
	
	for (var intI=0; intI < argWs.length; intI++)
		if (argWs.charAt(intI) != ' ' && argWs.charAt(intI) != '\t')
			return false
	
	return true
}

//------------------------------------------------------------------------------------
// function: isLeapYear
//           Function to tell, whether the given year is leap year or not
//------------------------------------------------------------------------------------
function isLeapYear(argYear) {
	return ((argYear % 4 == 0) && (argYear % 100 != 0)) || (argYear % 400 == 0) 
}

//------------------------------------------------------------------------------------
// function: daysInMonth
//           Function to return the maximum number of days in a given month of a
//           given year
//------------------------------------------------------------------------------------
function daysInMonth(argMonth, argYear) {
	switch (Number(argMonth)) {
		case 1:		// Jan
		case 3:		// Mar
		case 5:		// May
		case 7:		// Jul
		case 8:		// Aug
		case 10:		// Oct
		case 12:		// Dec
			return 31;
			break;
		
		case 4:		// Apr
		case 6:		// Jun
		case 9:		// Sep
		case 11:		// Nov
			return 30;
			break;
		
		case 2:		// Feb
			if (isLeapYear(argYear))
				return 29
			else
				return 28
			break;
		
		default:
			return 0;
	}
}

//------------------------------------------------------------------------------------
// function: getDateSeparator
//           Function to return the date separator
//           This function expects date in the format of mm/dd/yyyy or mm/dd/yy
//           or mm-dd-yyyy or mm-dd-yy
//------------------------------------------------------------------------------------
function getDateSeparator(argDate) {
	// Are there invalid separators?
	if ((argDate.indexOf('-') > 0) && (argDate.indexOf('/') > 0))
		return ' '

	if (argDate.indexOf('-') > 0)
		return '-'
	else
		if (argDate.indexOf('/') > 0)
			return '/'
		else
			return ' '
}

//------------------------------------------------------------------------------------
// function: getYear
//           Function to return the year part of the given date.
//           This function expects date in the format of mm/dd/yyyy or mm/dd/yy
//           or mm-dd-yyyy or mm-dd-yy
//------------------------------------------------------------------------------------
function getYear(argDate) {
	var dateSep = getDateSeparator(argDate)
	
	if (dateSep == ' ')
		return 0

	if(argDate.split(dateSep).length == 3)
		return argDate.split(dateSep)[2]
	else
		return 0
}

//------------------------------------------------------------------------------------
// function: getMonth
//           Function to return the month part of the given date.
//           This function expects date in the format of mm/dd/yyyy or mm/dd/yy
//           or mm-dd-yyyy or mm-dd-yy
//------------------------------------------------------------------------------------
function getMonth(argDate) {
	var dateSep = getDateSeparator(argDate)
	
	if (dateSep == ' ')
		return 0

	if(argDate.split(dateSep).length == 3)
		return argDate.split(dateSep)[0]
	else
		return 0
}

//------------------------------------------------------------------------------------
// function: getDay
//           Function to return the day part of the given date.
//           This function expects date in the format of mm/dd/yyyy or mm/dd/yy
//           or mm-dd-yyyy or mm-dd-yy
//------------------------------------------------------------------------------------
function getDay(argDate) {
	var dateSep = getDateSeparator(argDate)
	
	if (dateSep == ' ')
		return 0

	if(argDate.split(dateSep).length == 3)
		return argDate.split(dateSep)[1]
	else
		return 0
}

//------------------------------------------------------------------------------------
// function: isProperDay
//           Function to tell whether the given day of the given month is valid
//------------------------------------------------------------------------------------
function isProperDay(argDay, argMonth, argYear) {
	if ((isWhiteSpace(argDay)) || (argDay == 0))
		return false

	if ((argDay > 0) && (argDay < daysInMonth(argMonth, argYear) + 1))
		return true
	else 
		return false
}

//------------------------------------------------------------------------------------
// function: isProperMonth
//           Function to tell whether the given month is a valid one
//------------------------------------------------------------------------------------
function isProperMonth(argMonth) {
	if ((isWhiteSpace(argMonth)) || (argMonth == 0))
		return false
	
	if ((argMonth > 0) && (argMonth < 13))
		return true
	else
		return false
}

//------------------------------------------------------------------------------------
// function: isProperYear
//           Function to tell whether the given Year is a valid one
//------------------------------------------------------------------------------------
function isProperYear(argYear) {
	if ((isWhiteSpace(argYear)) || (argYear.toString().length > 4) || (argYear.toString().length == 3))
		return false
	
	switch (argYear.toString().length) {
		case 1:
			if (argYear >=0 && argYear < 10)
				return true
			else
				return false
			
		case 2:
			if (argYear >=0 && argYear < 100)
				return true
			else
				return false
			
		case 4:
			if (((argYear >=1900) || (argYear >=2000)) && ((argYear < 3000) || (argYear < 2000)))
				return true
			else
				return false
		
		default:
			return false
	}
}

//------------------------------------------------------------------------------------
// function: isProperDate
//           Function to tell whether the given date is valid or not
//           This function expects date in the format of mm/dd/yyyy or mm/dd/yy
//           or mm-dd-yyyy or mm-dd-yy
//------------------------------------------------------------------------------------
function isProperDate(argDate) {
	var tmpDay = getDay(argDate)
	var tmpMon = getMonth(argDate)
	var tmpYear = getYear(argDate)

	return isProperDay(tmpDay, tmpMon, tmpYear) && isProperMonth(tmpMon) && isProperYear(tmpYear)
}

//------------------------------------------------------------------------------------
// function: charOccurences
//           Function to return the number of times a given character is occuring in
//           the given string
//------------------------------------------------------------------------------------
function charOccurences(argString, argChar) {
	var intCt = 0

	for(var intI=0; intI < argString.length; intI++)
		if (argString.charAt(intI) == argChar)
			intCt++
	
	return intCt
}

//------------------------------------------------------------------------------------
// function: isProperEmail
//           Function to tell whether the given email is valid or not
//------------------------------------------------------------------------------------
function isProperEmail(argEmail) {
//	if (charOccurences(argEmail, '@') != 1 && charOccurences(argEmail, '.') > 2)
   if (charOccurences(argEmail, '@')!=1)
		return false      

//   if (charOccurences(argEmail, '.')!=1 && charOccurences(argEmail, '.')!=2 && charOccurences(argEmail, '.')!=3) {
//		return false      
//   }

	if (charOccurences(argEmail, '.')!=1 && charOccurences(argEmail, '.')!=2 && charOccurences(argEmail, '.')!=3 && charOccurences(argEmail, '.')!=4) {
		return false
	}	
      
	var atPos = argEmail.indexOf('@')
	var dotPos = argEmail.indexOf('.')

	if((atPos == 0) || (atPos == (argEmail.length - 1)))
		return false

	if((dotPos == 0) || (dotPos == (argEmail.length - 1)))
		return false
	
//	if((atPos > dotPos) || (atPos == (dotPos - 1)))
//		return false
	
	return true
}

//------------------------------------------------------------------------------------
// function: isProperNumber
//           Function to tell whether the given string is a proper number
//------------------------------------------------------------------------------------
function isProperNumber(argNumber) {
	var numberValue = Number(argNumber)
	
	if (isNaN(numberValue)) 
		return false
	else
		return !isWhiteSpace(argNumber)
}

//------------------------------------------------------------------------------------
// function: isProperAlphabetic
//           Function to tell whether the given string is a proper alphabetic string
//------------------------------------------------------------------------------------
function isProperAlphabetic(argString) {
	var alphabets = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"

	for(var intI=0; intI<argString.length; intI++)
		if (alphabets.indexOf(argString.charAt(intI)) == -1)
			return false
	
	return true
}

//------------------------------------------------------------------------------------
// function: objectValue
//           Function to return the value of the form element
//------------------------------------------------------------------------------------
function objectValue(argFrm, argElem) {
	var intI
	var objElem = null

	for (intI=0; intI<argFrm.length; intI++)
		if (argFrm[intI].name == argElem) 
			objElem = argFrm[intI]

	switch (objElem.type) {
		case 'text':
		case 'hidden':
		case 'password':
			return objElem.value
			break;
		
		case 'select-one':
			if (objElem.length == 0)
				return ''
			else 
				return objElem.options[objElem.selectedIndex].value
			break;
		
		case 'radio':
			for (intI=0; intI<argFrm.length; intI++)
				if (argFrm[intI].name == argElem) 
					if (argFrm[intI].checked)
						return argFrm[intI].value

			return ''
			break;
	}
}

//------------------------------------------------------------------------------------
// function: isProperZip
//           Function to validate a Zip code
//------------------------------------------------------------------------------------
function isProperZip(argZip) {
	if ((argZip.length == 5) || (argZip.length == 9))
		return isProperNumber(argZip)
	
	if (argZip.length == 10)
		return (isProperNumber(argZip.substr(0, 5)) && isProperNumber(argZip.substr(6, 4)) & (argZip.charAt(5) == '-'))
}

//------------------------------------------------------------------------------------
// function: isProperUSPhone
//           Function to validate a us phone number
//           Allowed formats 123-456-7890 or (123)456-7890
//------------------------------------------------------------------------------------
function isProperUSPhone(argPhone) {
	if (argPhone.length != 12 && argPhone.length != 14) return false
	if (argPhone.length == 12)
		return ((isProperNumber(argPhone.substr(0, 3)) && 
					(isProperNumber(argPhone.substr(4, 3)) || 
					 isProperAlphabetic(argPhone.substr(4, 3))) && 
					(isProperNumber(argPhone.substr(8, 4)) || 
					 isProperAlphabetic(argPhone.substr(8, 4)))))
	else                 
		return ((isProperNumber(argPhone.substr(1, 3)) && 
					(isProperNumber(argPhone.substr(6, 3)) || 
					 isProperAlphabetic(argPhone.substr(6, 3))) && 
					(isProperNumber(argPhone.substr(10, 4)) || 
					 isProperAlphabetic(argPhone.substr(10, 4)))))
}

//------------------------------------------------------------------------------------
// function: isProperUSSSN
//           Function to validate a us ssn
//------------------------------------------------------------------------------------
function isProperUSSSN(argSSN) {
	if (argSSN.length == 9)
   	return  (isProperNumber(argSSN.substr(0, 9)))


	if (argSSN.length != 11)
		return false

	return  (isProperNumber(argSSN.substr(0, 3)) && isProperNumber(argSSN.substr(4, 2)) &&
			 isProperNumber(argSSN.substr(7, 4)) && (argSSN.charAt(3) == '-') && (argSSN.charAt(6) == '-'))
}

//------------------------------------------------------------------------------------
// function: actionFields
//           Function to parse the action arguments
//------------------------------------------------------------------------------------
function actionFields(argActions) {
	this.email			= (argActions.indexOf('[email]') > -1)
	this.required		= (argActions.indexOf('[req]') > -1)
	this.checkDate		= (argActions.indexOf('[date]') > -1)
	this.checkZip		= (argActions.indexOf('[zip]') > -1)
	this.checkNumber	= (argActions.indexOf('[number]') > -1)
	this.checkAlphabetic= (argActions.indexOf('[alpha]') > -1)
	this.checkUSPhone	= (argActions.indexOf('[usphone]') > -1)
	this.checkUSSSN		= (argActions.indexOf('[usssn]') > -1)

	if (argActions.indexOf('[len=') > -1) {
		this.checkLength = true

		var lenToCheck = ''
		var bolCont = true

		for (var intI=(argActions.indexOf('[len=') +  5);((intI < argActions.length) && bolCont); intI++)
			if (argActions.charAt(intI) != ']')
				lenToCheck += argActions.charAt(intI)
			else
				bolCont = false
		this.lengthToCheck = lenToCheck
	}
	else
		this.checkLength = false

	if (argActions.indexOf('[blankalert=') > -1) {
		this.blankAlert = true

		var alertString = ''
		var bolCont = true

		for (var intI=(argActions.indexOf('[blankalert=') +  12);((intI < argActions.length) && bolCont); intI++)
			if (argActions.charAt(intI) != ']')
				alertString += argActions.charAt(intI)
			else
				bolCont = false
		this.blankAlertMessage = alertString
	}
	else
		this.blankAlert = false
	
	if (argActions.indexOf('[invalidalert=') > -1) {
		this.invalidAlert = true

		var alertString = ''
		var bolCont = true

		for (var intI=(argActions.indexOf('[invalidalert=') +  14);((intI < argActions.length) && bolCont); intI++)
			if (argActions.charAt(intI) != ']')
				alertString += argActions.charAt(intI)
			else
				bolCont = false
		this.invalidAlertMessage = alertString
	}
	else
		this.invalidAlert = false

	if (argActions.indexOf('[equals=') > -1) {
		this.shouldEqual = true

		var equalsString = ''
		var bolCont = true

		for (var intI=(argActions.indexOf('[equals=') +  8);((intI < argActions.length) && bolCont); intI++)
			if (argActions.charAt(intI) != ']')
				equalsString += argActions.charAt(intI)
			else
				bolCont = false
		this.shouldEqualString = equalsString
	}
	else
		this.shouldEqual = false

}

//------------------------------------------------------------------------------------
// function: validateForm
//           Function to validate a HTML form
//------------------------------------------------------------------------------------
function validateForm(argForm) {
	var frmElements = argForm.elements
	var elemName
	var elemObj

	for (var intI=0; intI < frmElements.length; intI++) {// *
		elemObj = frmElements[intI]
		elemName = elemObj.name

		if ((elemObj.type == 'hidden') && (elemName.length > 5))
			if (elemName.substr(elemName.length - 5).toLowerCase() == '_vldt') {// **
				var objAction = new actionFields(objectValue(frmElements, elemName))
				var actElem = elemName.substr(0, elemName.length - 5)
            var actTitle = argForm[actElem].title
				
				// Is it a required field?
				if (objAction.required) {
					if (isWhiteSpace(objectValue(frmElements, actElem))) {// ***
						alert (objAction.blankAlert?objAction.blankAlertMessage:actTitle + ' is a required field. Please enter it now.')
                  if (argForm[actElem].enabled) argForm[actElem].focus()
						return false
					} // ***
				}
				
				// Check the type validations
				if ((objectValue(frmElements, actElem) > '') && (!isWhiteSpace(objectValue(frmElements, actElem)))){// ***
					// Date
					if (objAction.checkDate)
						if (!isProperDate(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' contains an invalid date. Please correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Number
					if (objAction.checkNumber)
						if (!isProperNumber(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' contains an invalid number. Please correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Zip
					if (objAction.checkZip)
						if (!isProperZip(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' contains an invalid US Zip code. Please correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Alphabetic
					if (objAction.checkAlphabetic)
						if (!isProperAlphabetic(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' cannot have invalid Alphabets')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Check US phone
					if (objAction.checkUSPhone)
						if (!isProperUSPhone(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' contains an invalid US Phone Number. Please use the format (999) 999-9999 and correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Check US SSN
					if (objAction.checkUSSSN)
						if (!isProperUSSSN(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' is incorrect. Please fix it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Check email
					if (objAction.email)
						if (!isProperEmail(objectValue(frmElements, actElem))) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' contains an invalid email address. Please correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****

					// Check for length
					if (objAction.checkLength)
						if (objectValue(frmElements, actElem).length < objAction.lengthToCheck) {// ****
							alert (objAction.invalidAlert?objAction.invalidAlertMessage:actTitle + ' must be at least ' + objAction.lengthToCheck + ' characters long. Please correct it now.')
                     if (argForm[actElem].enabled) argForm[actElem].focus()
							return false
						} // ****
				} // ***
			} // **
	} // *
		
	return true
}
