/*************************************************************************************
** FormValidate.js - Validates and checks for required fields.  Only supports
** INPUT and SELECT form elements.  Also only supports Date in format MM/DD/YYYY
**
** To use call the "Field" function once per form element you need to validate
** or make required.  Then pass the variables into an array.  And lastly call the
** validate(this) function from the onSubmit event of your form.
*************************************************************************************/


/*************************************************************************************
** var formEltName = new Field(realname, formEltName, validationType, required);
**
** 1) realName is simply a meaningful description of the form element for use in
**    reporting. For example, if the user forgets to fill in this field, the alert
**    will say, "Please enter your last name."
**
** 2) formEltName is very important. Note that its value is the same as the name of the
**    corresponding element in the HTML form, and the same as the object name itself.
**    These names must be identical.
**
** 3) validationType is the form of validation you wish to apply.  Valid values are
**    'date', 'numeric', 'code', 'alphanumeric', and 'select'
**
** 4) required is a boolean indicating if this is a required field
**
**
** Example:
**
** var txtDate = new Field('Due Date', 'txtDate', 'date', true);
*************************************************************************************/
//var txtDate = new Field('Due Date', 'txtDate', 'date', true);
//var txtOrderNumber = new Field('Order Number', 'txtOrderNumber', 'alphanumeric', true);
//var txtCategory = new Field('Category', 'txtCategory', 'select', true);
//var txtCode = new Field('Commodity Code', 'txtCode', 'code', true);


/***************************************************************
** Define the fields array:
** Add a new item to the array for each object you create above
** Make sure the value of the array element is the same as
** the name of the object, and that the array elements are listed
** in the same order the corresponding objects appear in the form
** (it's more clear to the user that way)
***************************************************************/
//var fields = new Array(txtDate, txtOrderNumber, txtCategory, txtCode);


function validate(form)
{
	var formPassed = true;

	for (i=0; i<fields.length; i++)
	{
		formEltName = fields[i].formEltName;
		//alert(formEltName);

		formObj = eval("form." + formEltName);

		if ((fields[i].validationType != "select") && (fields[i].validationType != "radio") && (fields[i].fieldLength != -1))
		{
		    if (formObj.value.length > fields[i].fieldLength)
	    		{
	        		window.alert("The maximum length for " + fields[i].realName + " is " + fields[i].fieldLength + ".");
				formPassed = false;
		    	}
		}


		if (formPassed == true)
		{

			if (formObj.value != "")
			{

			switch (fields[i].validationType)
				{
					case "freeform":
						break;


					case "date":

						if (!isDate(formObj.value))
						{
							window.alert("The value of '" + formObj.value +  "' for " + fields[i].realName + " is invalid.  You must use a date format of 'MM/DD/YYYY'.");
							formPassed = false;
						}
						break;


					case "time":

						if (!isTime(formObj.value))
						{
							window.alert("The value of '" + formObj.value +  "' for " + fields[i].realName + " is invalid.  You must use a 24HR time format of 'HH:MM'.");
							formPassed = false;
						}
						break;


					case "alphanumeric":
						if (!isAlphanumeric(formObj.value))
						{
							window.alert(fields[i].realName + " may only contain Alphanumeric characters.");
							formPassed = false;
						}
						break;

					case "alphanumericnospace":
						if (!isAlphanumericNoSpace(formObj.value))
						{
							window.alert(fields[i].realName + " may only contain Alphanumeric characters.");
							formPassed = false;
						}
						break;

					case "code":

						if (!isCode(formObj.value))
						{
							window.alert("The " + fields[i].realName + " may only contain valid characters.");
							formPassed = false;
						}
						break;

					case "partNumber":

						if (!isPartNumber(formObj.value))
						{
							window.alert("The " + fields[i].realName + " may only contain digits and dashed.");
							formPassed = false;
						}
						break;

					case "serialNumber":

						if (!isSerialNumber(formObj.value))
						{
							window.alert("The " + fields[i].realName + " must contain a letter followed by 6 digits.");
							formPassed = false;
						}
						break;


					case "numeric":

						if (!isNumeric(formObj.value))
						{
							window.alert(fields[i].realName + " must be a numeric value.");
							formPassed = false;
						}
						break;


					case "float":
						if(!checkFloat(formObj.value, fields[i].fieldLength, fields[i].decimalPlaces))
						{
							var maxdigits = fields[i].fieldLength - fields[i].decimalPlaces - 1;
							window.alert(fields[i].realName + " must be a numeric value with a maximum of " + maxdigits + " digits and a maximum of " + fields[i].decimalPlaces + " decimal places.");
							formPassed = false;
						}
						break;


					case "noquotes":
						if(!noQuotes(formObj.value))
						{
							window.alert(fields[i].realName + " cannot contain double quotes.");
							formPassed = false;
						}
						break;

					case "nonzeronumeric":
                    	if (!isNonZeroNumeric(formObj.value))
                        {
                             window.alert(fields[i].realName + " must be a numeric and greater than zero.");
                             formPassed = false;
                        }
                        break;
					case "nonzerofloat":

                    	if (!isNonZeroFloat(formObj.value, fields[i].fieldLength, fields[i].decimalPlaces))
                        {
							var maxdigits = fields[i].fieldLength - fields[i].decimalPlaces - 1;
							 window.alert(fields[i].realName + " must be a numeric value that is greater than zero with a maximum of " + maxdigits + " digits and a maximum of " + fields[i].decimalPlaces + " decimal places.");
                             formPassed = false;
                        }
                        break;
					case "zipcode":
                    	if (!isZIPCode(formObj.value))
                        {
							 window.alert(fields[i].realName + " must be a valid zip code.");
                             formPassed = false;
                        }
                        break;
					case "email":
						if (!isEmail(formObj.value))
						{
							window.alert(fields[i].realName + " must be a valid email address.");
							formPassed = false;
						}
						break;

				}

			}
		}


		if (!formPassed)
		{

			formObj.select();
			//formObj.focus();
			return false;
		}

	}

	return checkRequired(form);
	//return true;

}



//Field object definition
function Field(realName, formEltName, validationType, required)
{
	this.realName = realName;
	this.formEltName = formEltName;
	this.validationType = validationType;
	this.required = required;
	this.fieldLength = -1;
}

function Field(realName, formEltName, validationType, required, length)
{
	this.realName = realName;
	this.formEltName = formEltName;
	this.validationType = validationType;
	this.required = required;
	this.fieldLength = length;
}

function Field(realName, formEltName, validationType, required, length, decimalPlaces)
{
	this.realName = realName;
	this.formEltName = formEltName;
	this.validationType = validationType;
	this.required = required;
	this.fieldLength = length;
	this.decimalPlaces = decimalPlaces;
}


function checkRequired(form)
{

	var formPassed = true;

	for (i=0; i<fields.length; i++) {

		formEltName = fields[i].formEltName;
		formObj = eval("form." + formEltName);

		switch (fields[i].validationType)
		{
			case "select":

				if (fields[i].required && formObj.selectedIndex == 0)
				{
					formPassed = false;
				}
				break;

			case "radio":

				if (fields[i].required)
				{
					formPassed = isRadio(formObj);
				}
				break;

			default:

				if ((fields[i].required) && (formObj.value == ""))
				{
					formPassed = false;
					break;
				}
		}

		if (!formPassed)
			break;

	}

	if (!formPassed)
	{
		window.alert("The " + fields[i].realName + " field is required.");
		if (formObj.focus) formObj.focus();
	}

	return formPassed;

}

function oneRequired(form, field1, field2)
{
	if (form(field1.formEltName).value == "" && form(field2.formEltName).value == "")
	{
		alert("Either " + field1.realName + " or " + field2.realName + " must be entered.");
		return false;
	}

	return true;
}


function isDate(str) {
  if (str.length != 10) { return false }

  for (j=0; j<str.length; j++) {
    if ((j == 2) || (j == 5)) {
      if (str.charAt(j) != "/") { return false }
    } else {
      if ((str.charAt(j) < "0") || (str.charAt(j) > "9")) { return false }
    }
  }

  var month = str.charAt(0) == "0" ? parseInt(str.substring(1,2)) : parseInt(str.substring(0,2));
  var day = str.charAt(3) == "0" ? parseInt(str.substring(4,5)) : parseInt(str.substring(3,5));
  var begin = str.charAt(6) == "0" ? (str.charAt(7) == "0" ? (str.charAt(8) == "0" ? 9 : 8) : 7) : 6;
  var year = parseInt(str.substring(begin, 10));

  if (day == 0) { return false }
  if (month == 0 || month > 12) { return false }
  if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
    if (day > 31) { return false }
  } else {
    if (month == 4 || month == 6 || month == 9 || month == 11) {
      if (day > 30) { return false }
    } else {
      if (year%4 != 0) {
        if (day > 28) { return false }
      } else {
        if (day > 29) { return false }
      }
    }
  }
  return true;
}


function isTime(str) {
  var l = str.length;
  if (l != 5) { return false }
  for (j=0; j<l; j++) {
    if ((l == 5) && (j == 2)) {
      if (str.charAt(j) != ":") { return false }
    } else {
      if ((str.charAt(j) < "0") || (str.charAt(j) > "9")) { return false }
    }
  }

  var hour = str.charAt(0) == "0" ? parseInt(str.substring(1,2)) : parseInt(str.substring(0,2));
  var minute = str.charAt(3) == "0" ? parseInt(str.substring(4,5)) : parseInt(str.substring(3,5));

  if (hour < 0 || hour > 23) { return false }
  if (minute < 0 || minute > 59) { return false }

  return true;
}


function isSelected(formObj)
{
  return (formObj.selectedIndex != 0);
}


function isRadio(formObj) {
  for (j=0; j<formObj.length; j++) {
    if (formObj[j].checked) {
      return true;
    }
  }
  return false;
}



// Returns true if all characters in string s are numbers.
function isNumeric(s)
{
    var i;
    for ( i = 0; i < s.length; i++ )
    {
        var c = s.charAt(i);
        if ( ! isDigit(c) ) return false;
    }
    return true;
}

// Returns true if all characters in string s are numbers.
function isPartNumber(s)
{
    var i;
    for ( i = 0; i < s.length; i++ )
    {
        var c = s.charAt(i);
        if ( ! isDigit(c) && c != '-') return false;
    }
    return true;
}

function isSerialNumber(s)
{
	if(s.length != 7)
		return false;

	var c = s.charAt(0);
	if(!isLetter(c))
		return false;

    var i;
    for ( i = 1; i < s.length; i++ )
    {
        var c = s.charAt(i);
        if ( ! isDigit(c))
			return false;
    }
    return true;
}



// Returns true if string s is English letters
// (A .. Z, a..z) and numbers only.
function isAlphanumeric (s)
{
   var i;

    // Search through string's characters one by one
    // until we find a non-alphanumeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is number or letter.
        var c = s.charAt(i);

        if (! (isLetter(c) || isDigit(c) || isSpace(c)) )
        return false;
    }

    // All characters are numbers or letters.
    return true;
}

// Returns true if string s is English letters
// (A .. Z, a..z) and numbers only.
function isAlphanumericNoSpace (s)
{
   var i;

    // Search through string's characters one by one
    // until we find a non-alphanumeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is number or letter.
        var c = s.charAt(i);

        if (! (isLetter(c) || isDigit(c)) )
        return false;
    }

    // All characters are numbers or letters.
    return true;
}


// Returns true if string s represents a valid code
function isCode (s)
{
   var i;

    // Search through string's characters one by one
    // until we find an invalid character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is number or letter.
        var c = s.charAt(i);

        if (! (isLetter(c) || isDigit(c) || c=="#" || c=="$" || c=="&" ||
			c=="*" || c=="(" || c=="" || c==")" || c=="_" ||
			c=="+" || c=="-" || c=="=" || c==":" || c==";" ||
			c=="?" || c=="/" || c=="." || c=="`") )
        return false;
    }

    // All characters are numbers or letters.
    return true;
}

// Returns true if character c is an English letter
// (A .. Z, a..z).
function isLetter (c)
{
	return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

function isSpace (c)
{
	return c==" ";
}



// Returns true if character c is a digit
// (0 .. 9).
function isDigit (c)
{
	return ((c >= "0") && (c <= "9"))
}


// Email address must be of form a@b.c -- in other words:
// * there must be at least one character before the @
// * there must be at least one character before and after the .
// * the characters @ and . are both required
function isEmail (s)
{
	// if we find .. then the email address is invalid
	if (s.indexOf("..") != -1) return false;

	if (s.indexOf(";") != -1) return false;

	if (s.indexOf(";") != -1) return false;
	if (s.indexOf(":") != -1) return false;
	if (s.indexOf("/") != -1) return false;
	if (s.indexOf("\\") != -1) return false;
	if (s.indexOf("(") != -1) return false;
	if (s.indexOf(")") != -1) return false;
	if (s.indexOf("[") != -1) return false;
	if (s.indexOf("]") != -1) return false;
	if (s.indexOf("?") != -1) return false;
	if (s.indexOf("!") != -1) return false;
	if (s.indexOf("@@") != -1) return false;
	if (s.indexOf(" ") != -1) return false;

	// there must be >= 1 character before @, so we
    // start looking at character position 1
    // (i.e. second character)
    var i = 1;
    var sLength = s.length;

    // look for @
    while ((i < sLength) && (s.charAt(i) != "@"))
    { i++
    }

    if ((i >= sLength) || (s.charAt(i) != "@")) return false;
    else i += 2;

    // look for .
    while ((i < sLength) && (s.charAt(i) != "."))
    { i++
    }

    // there must be at least one character after the .
    if ((i >= sLength - 1) || (s.charAt(i) != ".")) return false;
    else if(s=="default.email@heart.org") return false;
    else return true;
}


function noQuotes(s)
{
    var i;

    // Search through string's characters one by one
    // until we find a quote.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is number or letter.
        var c = s.charAt(i);

        if (isQuote(c))
            return false;
    }

    // All characters are numbers or letters.
    return true;
}

function isQuote(c)
{
    return (c == '\"');
}



function checkFloat(nbr,maxlen,decplcs)
{


   if (nbr.length > 0)
    {
        if (nbr.indexOf(".") == 0)
            nbr = "0" + nbr;
        if (!verifyFloat(nbr))
        {
            return false;
        }
        else
        {
            if (!maxFloat(nbr,maxlen,decplcs))
            {
                return false;
            }
        }
    }
    return true;
}

function verifyFloat(nbr)
{
  if (nbr.length == 0) return true;
	    fPttn = /^\d+\.?\d*$/
	return (fPttn.test(nbr));
}

function maxFloat(nbr,maxlen,decplcs)
{
	maxdigits = maxlen - decplcs - 1;

	var digits, dec;

	var dotIndex = nbr.indexOf(".");
	if(dotIndex != -1)
	{
		digits = nbr.substring(0,dotIndex);
		dec = nbr.substring(dotIndex+1,nbr.length);
	}
	else
	{
		digits = nbr;
		dec = "";
	}

	if(digits.length > maxdigits || dec.length > decplcs)
		return false;

	return true;


/*  var nbrlen = -1;
	var dotIndex = nbr.indexOf(".");
	if (dotIndex > maxlen - decplcs)
	{
	    return false;
	}
	if (dotIndex == -1)
	{
	    maxlen = maxlen - decplcs - 1;
	    nbrlen = nbr.length;
	}
	else
	{
	    nbrlen = nbr.length - 1;
	    if ((nbrlen - dotIndex) > decplcs)
	        return false;
	}
	if (nbrlen > maxlen)
	{
	    return false;
	}
	return true;*/
}

function checkDecPt(nbr)
{
  if ( (nbr.indexOf(".") == 0) && (!isNaN(nbr)) )
      return true;
}

function isNonZeroNumeric(s)
{
     if (!isNumeric(s)) return false;

     if (s <= 0) return false;

     return true;
}

function isNonZeroFloat(s,maxlen,decplcs)
{
     if (!checkFloat(s,maxlen,decplcs)) return false;

     if (s <= 0) return false;

     return true;
}

// non-digit characters which are allowed in ZIP Codes
var ZIPCodeDelimiters = "-";

// U.S. ZIP codes have 5 or 9 digits.
// They are formatted as 12345 or 12345-6789.
var digitsInZIPCode1 = 5
var digitsInZIPCode2 = 9


function isZIPCode (s)
{
	var normalizedZIP = stripCharsInBag(s, ZIPCodeDelimiters)
    return checkZIPCode(normalizedZIP);
}

function checkZIPCode (s)
{
   return (isNumeric(s) &&
            ((s.length == digitsInZIPCode1) ||
             (s.length == digitsInZIPCode2)))
}

// Removes all characters which appear in string bag from string s.
function stripCharsInBag (s, bag)

{   var i;
    var returnString = "";

    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++)
    {
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

// Checks to ensure a textarea does not exceed the number of lines & linesize limits
function checkLineSize(str, lineNum, lineSize, numLines)
{
    if (str != null && str.length > 0)
    {
        if (lineNum > numLines)
            return false;

        carriageReturn = str.indexOf("\n");
        if (carriageReturn > (lineSize * lineNum + 1))
            return false;
        else if (carriageReturn == -1)
        {
            if (str.length > lineSize)
                return false;
            else
                return true;
        }
        return checkLineSize(str.substring(carriageReturn+1), lineNum+1, lineSize, numLines);
    }
    else
        return true;
}

//Checks to ensure a String is either null or greater
//than a specified minimum size
function checkMinimumSize(str, minSize, allowNull)
{
    if ((!allowNull && str.length == 0) || (str.length > 0 && str.length < minSize))
        return false;
    else
        return true;
}





