

function validateRequiredInput(control, message)
{
    if (control)
    {
        if (control.value == '') return message;
        else return '';
    }
    else return 'RequiredInput: No such control ' + message;
}

function validateRequiredRadioGroup(radioGroup, message)
{
    if (radioGroup)
    {
        var radioChoice = false;

        for (counter = 0; counter < radioGroup.length; counter++)
        {
            if (radioGroup[counter].checked)
                radioChoice = true;
        }
        if (!radioChoice)
        {
            return message;
        }
        return '';
    }
    else return 'RequiredRadioGroup: no such control '+message;
}

function validateMaxSize(control, message, size)
{
    if (control)
    {
        if (control.value.length > size) return message + '('+(control.value.length - size)+ ' extra characters)';
        else return '';
    }
    else return 'Maxsize: No such control ' + message;
}

function validateSameValue(control1, control2,  message)
{
    if (control1)
    {
        if (control2)
        {
            if (control1.value != control2.value) return message;
            else return '';
        }
        else return 'RequiredInput: No such control (2) ' + message;
    }
    else return 'RequiredInput: No such control (1) ' + message;
}



function validateRequiredSelect(control, message, badValue)
{
    if (control)
    {
        if (control.options[control.selectedIndex].value)
        {
            if (control.options[control.selectedIndex].value == badValue) return message;
            else return '';
        }
        if (control.options[control.selectedIndex].text == badValue) return message;
        else return '';
    }
    else return 'RequiredSelect: No such control ' + message;
}

function validateDateField(control, format, formatMessage)
{
	if (control) {
		if ((control.value != '') && (!isDate(trim(control.value),trim(format))))  {
			if (formatMessage == null || formatMessage == '') {
				return "Please provide a date in the following format: " + format;
			} else {
				return formatMessage;
			}
		}
	}
	else return 'DateField: No such control ' + formatMessage;
	return '';
}

function validateEmailField(control, invalidEmailMessage)
{
	if (control) {
		if ((control.value != '') && (!isEmailAddress(trim(control.value))))  {
			if (invalidEmailMessage == null || invalidEmailMessage == '') {
				return "Please provide a valid email address.";
			} else {
				return invalidEmailMessage;
			}
		}
	}
	else return 'EmailField: No such control ' + invalidEmailMessage;
	return '';
}

function validatePhoneField(control, errorMessage) {
	if (errorMessage == null || errorMessage == '') {
		errorMessage = "Please provide a valid phone number.";
	}
	var s;
	if (control) {
		if (isPhoneNumber(trim(control.value))) {
			s = '';
		} else {
			s = errorMessage;
		}
	} else {
		s = 'PhoneField: No such control ' + errorMessage;
	}
	return s;
}

function validateNumericField(control, allowCommas, badNumericMessage, invalidCommasMessage)
{
	if (control) {
	        var value = control.value.replace(/^\s+/g, '').replace(/\s+$/g, '');
			if ((value != '') && (isNaN(value) || (parseFloat(value) != value)))  {
				var resultVal = isNaNWithCommas(value);
				if (resultVal > 0) {
					if (resultVal == 1) {
						if (badNumericMessage == null || badNumericMessage == '') {
							return "Please provide a valid number in the " + control.name + " field.";
						} else {
							return badNumericMessage;
						}
					}
					if (resultVal == 2) {
						if (invalidCommasMessage == null || invalidCommasMessage == '') {
							return "Please provide a valid commas for the number in the " + control.name + " field.";
						} else {
							return invalidCommasMessage;
						}
					}
				}
		}

	}
	else return 'NumericField: No such control ' + badNumericMessage;

	return '';

}

function validateNumericFieldWithMinimum(control, allowCommas, badNumericMessage, invalidCommasMessage, minValue, belowMinValueMessage)
{
    var result = validateNumericField(control, allowCommas, badNumericMessage, invalidCommasMessage);
    if (result != '') return result;

    // we already know it's a valid number
    if (control.value < minValue) return belowMinValueMessage;
    return '';
}


function validateIntegralField(control, allowCommas, badNumericMessage, invalidCommasMessage, notAnIntegralMessage)
{
	if (control) {
		if (control.value.indexOf('.') != -1) {
			// alert("this number has to be an integer.");
			if (notAnIntegralMessage == null || notAnIntegralMessage == '') {
				return "Please provide a whole number (no decimal points) in the " + control.name + " field.";
			} else {
				return notAnIntegralMessage;
			}

		}

		if ((control.value != '') && (isNaN(control.value) || (parseInt(control.value) != control.value)))  {
			var resultVal = isNaNWithCommas(control.value);
			if (resultVal > 0) {
				if (resultVal == 1) {
					if (badNumericMessage == null || badNumericMessage == '') {
						return "Please provide a valid number in the " + control.name + " field.";
					} else {
						return badNumericMessage;
					}
				}
				if (resultVal == 2) {
					if (invalidCommasMessage == null || invalidCommasMessage == '') {
						return "Please provide a valid commas for the number in the " + control.name + " field.";
					} else {
						return invalidCommasMessage;
					}
				}
			}
		}

	}
	else return 'IntegerField: No such control ' + badNumericMessage;

	return '';

}

function validateMinimumIntegralField(control, allowCommas, minValue, belowMinValueMessage, badNumericMessage, invalidCommasMessage, notAnIntegralMessage)
{
    var result = validateIntegralField(control, allowCommas, badNumericMessage, invalidCommasMessage, notAnIntegralMessage);
    if (result != '') return result;

    // we already know it's a valid int
    if (control.value < minValue) return belowMinValueMessage;
    return '';
}

function validateMaximumIntegralField(control, allowCommas, maxValue, aboveMaxValueMessage, badNumericMessage, invalidCommasMessage, notAnIntegralMessage)
{
    var result = validateIntegralField(control, allowCommas, badNumericMessage, invalidCommasMessage, notAnIntegralMessage);
    if (result != '') return result;

    // we already know it's a valid int
    if (control.value > maxValue) return aboveMaxValueMessage;
    return '';
}

//Helper functions for validation.  This code may be moved to a more logical location.
// ===================================================================
// Author: Matt Kruse <mkruse@netexpress.net>
// WWW: http://www.mattkruse.com/
//
// ===================================================================

var MONTH_NAMES = new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');

// ------------------------------------------------------------------
// isDate ( date_string, format_string )
//
// Returns true if date string matches format of format string and
// is a valid date. Else returns false.
//
// It is recommended that you trim whitespace around the value before
// passing it to this function, as whitespace is NOT ignored!
// ------------------------------------------------------------------
function isDate(val,format) {
	var date = getDateFromFormat(val,format);
	if (date == 0) { return false; }
	return true;
	}

// -------------------------------------------------------------------
// compareDates(date1,date1format,date2,date2format)
//   Compare two date strings to see which is greater.
//   Returns:
//   1 if date1 is greater than date2
//   0 if date2 is greater than date1 of if they are the same
//  -1 if either of the dates is in an invalid format
// -------------------------------------------------------------------
function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1 = getDateFromFormat(date1,dateformat1);
	var d2 = getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits = "1234567890";
	for (var j=0; j < val.length; j++) {
		if (digits.indexOf(val.charAt(j)) == -1) { return false; }
		}
	return true;
	}
function _getInt(str,j,minlength,maxlength) {
	for (x=maxlength; x>=minlength; x--) {
		var token = str.substring(j,j+x);
		if (token.length < minlength) {
			return null;
			}
		if (_isInteger(token)) {
			return token;
			}
		}
	return null;
	}
// ------------------------------------------------------------------
// END Utility Functions
// ------------------------------------------------------------------

// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the
// getTime() of the date. If it does not match, it returns 0.
//
// This function uses the same format strings as the
// java.text.SimpleDateFormat class, with minor exceptions.
//
// The format string consists of the following abbreviations:
//
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//
// Examples:
//  "MMM d, y" matches: January 01, 2000
//                      Dec 1, 1900
//                      Nov 20, 00
//  "m/d/yy"   matches: 01/20/00
//                      9/2/00
//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val = val+"";
	format = format+"";
	var i_val = 0;
	var i_format = 0;
	var c = "";
	var token = "";
	var token2= "";
	var x,y;
	var now   = new Date();
	var year  = now.getYear();
	var month = now.getMonth()+1;
	var date  = now.getDate();
	var hh    = now.getHours();
	var mm    = now.getMinutes();
	var ss    = now.getSeconds();
	var ampm  = "";

	while (i_format < format.length) {
		// Get next token from format string
		c = format.charAt(i_format);
		token = "";
		while ((format.charAt(i_format) == c) && (i_format < format.length)) {
			token += format.charAt(i_format);
			i_format++;
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }// 4-digit year
			if (token=="yy")   { x=2;y=2; }// 2-digit year
			if (token=="y")    { x=2;y=4; }// 2-or-4-digit year
			year = _getInt(val,i_val,x,y);
			if (year == null) { return 0; }
			i_val += year.length;
			if (year.length == 2) {
				if (year > 70) {
					year = 1900+(year-0);
					}
				else {
					year = 2000+(year-0);
					}
				}
			}
		else if (token=="MMM"){// Month name
			month = 0;
			for (var k=0; k<MONTH_NAMES.length; k++) {
				var month_name = MONTH_NAMES[k];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase() == month_name.toLowerCase()) {
					month = k+1;
					if (month>12) { month -= 12; }
					i_val += month_name.length;
					break;
					}
				}
			if (month == 0) { return 0; }
			if ((month < 1) || (month>12)) { return 0; }
			// TODO: Process Month Name
			}
		else if (token=="MM" || token=="M") {
			x=token.length; y=2;
			month = _getInt(val,i_val,x,y);
			if (month == null) { return 0; }
			if ((month < 1) || (month > 12)) { return 0; }
			i_val += month.length;
			}
		else if (token=="dd" || token=="d") {
			x=token.length; y=2;
			date = _getInt(val,i_val,x,y);
			if (date == null) { return 0; }
			if ((date < 1) || (date>31)) { return 0; }
			i_val += date.length;
			}
		else if (token=="hh" || token=="h") {
			x=token.length; y=2;
			hh = _getInt(val,i_val,x,y);
			if (hh == null) { return 0; }
			if ((hh < 1) || (hh > 12)) { return 0; }
			i_val += hh.length;
			hh--;
			}
		else if (token=="HH" || token=="H") {
			x=token.length; y=2;
			hh = _getInt(val,i_val,x,y);
			if (hh == null) { return 0; }
			if ((hh < 0) || (hh > 23)) { return 0; }
			i_val += hh.length;
			}
		else if (token=="KK" || token=="K") {
			x=token.length; y=2;
			hh = _getInt(val,i_val,x,y);
			if (hh == null) { return 0; }
			if ((hh < 0) || (hh > 11)) { return 0; }
			i_val += hh.length;
			}
		else if (token=="kk" || token=="k") {
			x=token.length; y=2;
			hh = _getInt(val,i_val,x,y);
			if (hh == null) { return 0; }
			if ((hh < 1) || (hh > 24)) { return 0; }
			i_val += hh.length;
			h--;
			}
		else if (token=="mm" || token=="m") {
			x=token.length; y=2;
			mm = _getInt(val,i_val,x,y);
			if (mm == null) { return 0; }
			if ((mm < 0) || (mm > 59)) { return 0; }
			i_val += mm.length;
			}
		else if (token=="ss" || token=="s") {
			x=token.length; y=2;
			ss = _getInt(val,i_val,x,y);
			if (ss == null) { return 0; }
			if ((ss < 0) || (ss > 59)) { return 0; }
			i_val += ss.length;
			}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase() == "am") {
				ampm = "AM";
				}
			else if (val.substring(i_val,i_val+2).toLowerCase() == "pm") {
				ampm = "PM";
				}
			else {
				return 0;
				}
			}
		else {
			if (val.substring(i_val,i_val+token.length) != token) {
				return 0;
				}
			else {
				i_val += token.length;
				}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) {
		return 0;
		}
	// Is date valid for month?
	if (month == 2) {
		// Check for leap year
		if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) { // leap year
			if (date > 29){ return false; }
			}
		else {
			if (date > 28) { return false; }
			}
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return false; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") {
		hh+=12;
		}
	else if (hh>11 && ampm=="AM") {
		hh-=12;
		}
	var newdate = new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}


//===================================
function trim(arg) {
//===================================

	var trimvalue = "";

	if (arg == null) return trimvalue;
	arglen = arg.length;
	if (arglen < 1) return trimvalue;

	z = 0;
	pos = -1;
	while (z < arglen) {
		if (arg.charCodeAt(z) != 32 && !isNaN(arg.charCodeAt(z))) {
			pos = z;
			break;
		}
		z++;
	}

	var lastpos = -1;
	z = arglen;
	while (z >= 0) {
		if (arg.charCodeAt(z) != 32 && !isNaN(arg.charCodeAt(z))) {
			lastpos = z;
			break;
		}
		z--;
	}

	trimvalue = arg.substring(pos,lastpos + 1);

	return trimvalue;

}


function isEmailAddress(value) {
      /* The following conditions are tested.
         one and only one at symbol exists and it is preceded by at least one character
         at least one period follows the at symbol
         at least one character separates the period from the at symbol
         if there are two periods, they are not adjacent
         the period is not the last character
         there are no spaces or commas
      */

      var debug = false;
      var addressOK = true;
      var atPos = value.indexOf('@');
      var atPos2 = value.lastIndexOf('@');
      var dotPos = value.substring(atPos).indexOf('.') + atPos;
      var dotPos2 = value.lastIndexOf('.');
      var eEndPos = value.length - 1;
      var spacePos = value.indexOf(' ');
      var commaPos = value.indexOf(',');

      if (atPos < 1
          || atPos != atPos2
          || dotPos < atPos + 2
          || dotPos2 - dotPos == 1
          || dotPos2 == eEndPos
          || spacePos >= 0
          || commaPos >= 0) {
         addressOK = false;
      }
      return addressOK;
}


//returns 0 if successful, 1 if this is not a valid number, 2 if the commas are messed up.
function isNaNWithCommas(str) {

	re = /^|,/g;
	var newStr = str.replace(re, "");

	if (isNaN(newStr)) {
		return 1;
	}

	//if there are no commas at all, return successfully.
	if (str.length == newStr.length) return 0;

	//then test to see if the commas are placed correctly.  first determine if a decimal place exists.
	var decIndex = str.indexOf('.');
	if (decIndex == -1) decIndex = str.length;

	var counter = 0;
	for (q = decIndex-1; q >= 0; q--) {
		if (str.charAt(q) == ',') {
			if (counter != 3) {
				return 2;
			} else {
				counter = 0;
			}
		} else counter++;
	}
	if (str.charAt(0) == '-') counter--;
	if (counter < 1 || counter > 3) return 2;

	//seems like everything is ok.
	return 0;
}

function isPhoneNumber(str) {
	//strips out the characters '()-xX ' and returns true iff the result is
	//a list of no less than 10 digits
	//so, for example, "(212) 799-2551 x209" would pass the test
	var result = true;
	var count = 0;
	for (i = 0; i < str.length; i++) {
		var c = str.charAt(i);
		if (c == '-' || c == '(' || c == ')' || c == 'x' || c == 'X' || c == ' ') {
			//ignore
	    	} else if (c >= '0' && c <= '9') {
			count++;
		} else {
			result = false;
			break;
	    	}
	}
	if (result) {
	    result = count == 0 || count >= 10;
	}
	return result;
}

