//Javascript functions for form validation
function MM_findObj(n, d) 
{ //v4.01
  var p,i,x;  
  if(!d) d=document; 
  if((p=n.indexOf("?"))>0&&parent.frames.length) 
  {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);
  }
  if(!(x=d[n])&&d.all) x=d.all[n]; 
  for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); 
  return x;
}
 
function YY_checkform() { //v4.66
//copyright (c)1998,2002 Yaromat.com, modified by DRS for GSMR
  var args = YY_checkform.arguments;  //Collection of parameters passed to function
  var myDot=true; 
  var myV=''; 
  var myErr='';
  var addErr=false;
  var myReq;
  var addInfo = '';  //provides additional error info (primarily used by email validation)
  var accum=0 //Accumulator; represents the number of check boxes checked before encountering the last in the group (method of ensuring at least one box is checked in grouping)

  for (var i=1; i<args.length; i=i+4) //Process arguments in groups of 4 starting at the second argument
  {
    if (args[i+1].charAt(0)=='#')
	{
     myReq=true; 
     args[i+1]=args[i+1].substring(1); //strips the # sign from the second parameter (not sure why?)
	}
	else
	{
	 myReq=false
	}

    var myObj = MM_findObj(args[i].replace(/\[\d+\]/ig,""));  //Gathers info on the specified object in the form
    myV=myObj.value;  //assigns value of selection for text/text area type fields

	//DRS: debugger
	//alert("Field name: " + args[i] + ", ObjType: " + myObj.type + ", ObjValue: " + myV + " len: " + myV.length)

    if (myObj.type=='text'||myObj.type=='password'||myObj.type=='hidden') //for text type fields...
	{
      if (myReq&&myObj.value.length==0){addErr=true}  //text fields must not be blank, or else error...

      if ((myV.length>0)&&(args[i+2]==1))  //validates text field content based on from / to number range (range must be specified in 2nd parameter)
	  { //fromto
        var myMa=args[i+1].split('_');
		if(isNaN(myV)||myV<myMa[0]/1||myV > myMa[1]/1){addErr=true}  //if not numvalue or value is outside of range, error.
      } 
	  else if ((myV.length>0)&&(args[i+2]==2))  //validates text field content for email format (simple version)
	  {
        var rx=new RegExp("^[\\w\.=-]+@[\\w\\.-]+\\.[a-z]{2,4}$");
		if(!rx.test(myV))addErr=true;
      } else if ((myV.length>0)&&(args[i+2]==3))  //validates text field content for date format
	  { // date
        var myMa=args[i+1].split("#"); 
		var myAt=myV.match(myMa[0]);
        if(myAt)
		{
          var myD=(myAt[myMa[1]])?myAt[myMa[1]]:1; 
		  var myM=myAt[myMa[2]]-1; 
		  var myY=myAt[myMa[3]];
          var myDate=new Date(myY,myM,myD);
          if(myDate.getFullYear()!=myY||myDate.getDate()!=myD||myDate.getMonth()!=myM){addErr=true};
        }
		else
		{
	     addErr=true
		}
      } else if ((myV.length>0)&&(args[i+2]==4))  //validates text field content for time format
	  { // time
        var myMa=args[i+1].split("#"); 
		var myAt=myV.match(myMa[0]);
		if(!myAt){addErr=true}
      } else if (myV.length>0&&args[i+2]==5)  //validates text field content - unsure of purpose
	  { // check this 2
        var myObj1 = MM_findObj(args[i+1].replace(/\[\d+\]/ig,""));
        if(myObj1.length)myObj1=myObj1[args[i+1].replace(/(.*\[)|(\].*)/ig,"")];
        if(!myObj1.checked){addErr=true}
      } else if (myV.length>0&&args[i+2]==6)  //validates text field content - validates password length
	  { // the same
        var myObj1 = MM_findObj(args[i+1]);
        if(myV!=myObj1.value){addErr=true}
	  } else if ((myV.length>0)&&(args[i+2]==7))  //DRS: added 12/20/05 to validate email type fields in more robust manner
	  {
		if((addInfo=emailCheck(myV))!='')  //email check function defined below. addInfo assigned non blank value if validation fails.
		{
			addErr=true;
			addInfo=addInfo + ' - check: ' + args[i+3]; //Pass along message as appended data - changed 01/20/09 DRS
		}
	  } else if ((myV.length>0)&&(args[i+2]==8))  //DRS: added 12/20/05 to validate zipcode type fields
	  {
		if((addInfo=zipCheck(myV))!=''){addErr=true}  //email check function defined below. addInfo assigned non blank value if validation fails.
	  }
    } else
    if (!myObj.type&&myObj.length>0&&myObj[0].type=='radio')  //for radio button type fields...
	{
      var myTest = args[i].match(/(.*)\[(\d+)\].*/i);
	  if (args[i+2]==1){var myObj1=(myObj.length>1)?myObj[myTest[2]]:myObj} //Modified DRS - doesn't appear to function properly in native form
      if (args[i+2]==1&&myObj1&&myObj1.checked&&MM_findObj(args[i+1]).value.length/1==0){addErr=true}
      if (args[i+2]==2){ //Test for at least one of the radio items being checked
      var myDot=false;
      for(var j=0;j<myObj.length;j++){myDot=myDot||myObj[j].checked}
      if(!myDot){myErr+='* ' +args[i+3]+'\n'}
     }
    } else if (myObj.type=='checkbox')  //for checkbox type fields...
	{
	  if(args[i+2]==1&&myObj.checked==false){addErr=true}  //Can't be false; ie: must be checked as in "consent given" type fields
      if(args[i+2]==2&&myObj.checked&&MM_findObj(args[i+1]).value.length/1==0){addErr=true} //Special case: if box is checked, the specified text field (2nd argument) can't be blank
	  if(args[i+2]==3&&myObj.checked==true){accum++}  //Special animal; increment the check box accumulator (DRS)
	  if(args[i+2]==4)
	  {
		  if(myObj.checked&&MM_findObj(args[i+1]).value.length/1==0){addErr=true;accum=0}  //Special case: if box is checked, the specified text field (2nd argument) can't be blank
	      else if(myObj.checked==false&&accum<1){
		   addErr=true;
		   myNum = args[i+3].lastIndexOf('('); //This is very much a hack; expects args[i+3] to be in a very specific format. Essentially extracts the item number from: text text {number.subcategory.letter) format.
		   myMsg = args[i+3].substring(myNum,args[i+3].length);
		   myNum = myMsg.lastIndexOf('.');
		   myMsg = myMsg.substring(1,myNum);
		   addInfo='At least one item must be selected from this checkbox grouping. (' + myMsg + ')';
		   accum=0
		  }else{accum=0}
	  } //field is not checked, but when we encountered group termination type (catchall) field, it's time to reconcile the grouping of checkboxes
	  if(args[i+2]==5) //Handles the case where we just want at least one check box to be selected (use args[i+2]==3 for all previous checkboxes in the validation script)
	  {
		  if(myObj.checked==true){accum++};
		  if(accum==0){addErr=true;addInfo=args[i+3]};
	  }
	} else if (myObj.type=='select-one'||myObj.type=='select-multiple'){  //for select type drop down boxes
      if(args[i+2]==1&&myObj.selectedIndex/1==0){addErr=true}
    } else if (myObj.type=='textarea')  //for text area type fields...
	{
      if(myV.length<args[i+1]){addErr=true}
    } else if (!myObj.type&&myObj.length>0&&myObj[0].type=='checkbox') //Added by DRS - special case; array of checkboxes
	{
	  if(args[i+2]==1) //At least one checkbox checked, in an array of checkboxes (form elements possess same name)
	  {
		accum=0
		for(var j=0;j<myObj.length;j++)
		{
			if(myObj[j].checked) accum++;
		}
		if(accum==0){addErr=true};
	  }
	}
	if (addErr)  //If error is true for this field cycle...
	{ 
	  if(addInfo!='')  //Additional error info is present; ignore the passed generic error message and append this info.
	  {
	    myErr+='* '+addInfo+'\n'
	  } 
	  else 
	  {
	    myErr+='* '+args[i+3]+'\n';  //Just append passed message to myErr
	  }
    addErr=false;  //reset addErr flag,
	addInfo = '';  //reset additional info message
	}
  }  //end for
  
  if (myErr!=''){alert('The required information is incomplete or contains errors:\t\t\t\t\t\n\n'+myErr)}
  document.MM_returnValue = (myErr=='');  //MM_returnValue set to true if no errors in any fields checked, false otherwise.
}

//Email style validation function (modified 12/20/05 - DRS)

/*This script and many more are available free online at
The JavaScript Source!! http://javascript.internet.com

V1.1.3: Sandeep V. Tamhankar (stamhankar@hotmail.com)
Original:  Sandeep V. Tamhankar (stamhankar@hotmail.com)*/

//Begin
function emailCheck (emailStr) {

//Trim leading and trailing spaces
while (emailStr.charAt(0) == ' ')
  emailStr = emailStr.substring(1);
while (emailStr.charAt(emailStr.length - 1) == ' ')
  emailStr = emailStr.substring(0, emailStr.length - 1);

var strerr="";

emailStr = emailStr.toLowerCase()

/* The following variable tells the rest of the function whether or not
to verify that the address ends in a two-letter country or well-known
TLD.  1 means check it, 0 means don't. */

var checkTLD=1;

/* The following is the list of known TLDs that an e-mail address must end with. */

var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;

/* The following pattern is used to check if the entered e-mail address
fits the user@domain format.  It also is used to separate the username
from the domain. */

var emailPat=/^(.+)@(.+)$/;

/* The following string represents the pattern for matching all special
characters.  We don't want to allow special characters in the address.
These characters include ( ) < > @ , ; : \ " . [ ] */

var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";

/* The following string represents the range of characters allowed in a
username or domainname.  It really states which chars aren't allowed.*/

var validChars="\[^\\s" + specialChars + "\]";

/* The following pattern applies if the "user" is a quoted string (in
which case, there are no rules about which characters are allowed
and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
is a legal e-mail address. */

var quotedUser="(\"[^\"]*\")";

/* The following pattern applies for domains that are IP addresses,
rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
e-mail address. NOTE: The square brackets are required. */

var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;

/* The following string represents an atom (basically a series of non-special characters.) */

var atom=validChars + '+';

/* The following string represents one word in the typical username.
For example, in john.doe@somewhere.com, john and doe are words.
Basically, a word is either an atom or quoted string. */

var word="(" + atom + "|" + quotedUser + ")";

// The following pattern describes the structure of the user

var userPat=new RegExp("^" + word + "(\\." + word + ")*$");

/* The following pattern describes the structure of a normal symbolic
domain, as opposed to ipDomainPat, shown above. */

var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");

/* Finally, let's start trying to figure out if the supplied address is valid. */

/* Begin with the coarse pattern to simply break up user@domain into
different pieces that are easy to analyze. */

var matchArray=emailStr.match(emailPat);

if (matchArray==null) {

/* Too many/few @'s or something; basically, this address doesn't
even fit the general mould of a valid e-mail address. */

strerr = "Email address seems incorrect (check @ and .'s)";
return strerr;
}

var user=matchArray[1];
var domain=matchArray[2];

// Start by checking that only basic ASCII characters are in the strings (0-127).

for (i=0; i<user.length; i++) {
if (user.charCodeAt(i)>127) {
strerr = "Email address contains invalid characters.";
return strerr;
   }
}
for (i=0; i<domain.length; i++) {
if (domain.charCodeAt(i)>127) {
strerr = "Email domain name contains invalid characters.";
return strerr;
   }
}

// See if "user" is valid

if (user.match(userPat)==null) {

// user is not valid

strerr = "Email address part doesn't seem to be valid.";
return strerr;
}

/* if the e-mail address is at an IP address (as opposed to a symbolic
host name) make sure the IP address is valid. */

var IPArray=domain.match(ipDomainPat);
if (IPArray!=null) {

// this is an IP address

for (var i=1;i<=4;i++) {
if (IPArray[i]>255) {
strerr = "Email address destination IP address is invalid!";
return strerr;
   }
}
return strerr;
}

// Domain is symbolic name.  Check if it's valid.

var atomPat=new RegExp("^" + atom + "$");
var domArr=domain.split(".");
var len=domArr.length;
for (i=0;i<len;i++) {
if (domArr[i].search(atomPat)==-1) {
strerr = "Email address domain name does not seem to be valid.";
return strerr;
   }
}

/* domain name seems valid, but now make sure that it ends in a
known top-level domain (like com, edu, gov) or a two-letter word,
representing country (uk, nl), and that there's a hostname preceding
the domain or country. */

if (checkTLD && domArr[domArr.length-1].length!=2 &&
domArr[domArr.length-1].search(knownDomsPat)==-1) {
strerr = "Email address must end in a well-known domain or two letter " + "country.";
return strerr;
}

// Make sure there's a host name preceding the domain.

if (len<2) {
strerr = "Email address is missing a hostname!";
return strerr;
}

// If we've gotten this far, everything's valid!
return strerr;
}
//End of the email validation function

//Zipcode validation function (modified 12/20/05 - DRS)
/*Original:  Brian Swalwell -->

This script and many more are available free online at
The JavaScript Source!! http://javascript.internet.com*/

function zipCheck(zipString) 
{
	var valid = "0123456789-";
	var hyphencount = 0;
    var strerr = "";

	if (zipString.length!=5 && zipString.length!=10) 
	{
	  strerr = "Zip code format: Expecting 5 digit, or 5-4 digit zip code.";
	  return strerr;
	}

    for (var i=0; i < zipString.length; i++) 
	{
		temp = "" + zipString.substring(i, i+1);
		if (temp == "-") hyphencount++;
		if (valid.indexOf(temp) == "-1") 
		{
		  strerr = "Zip code contains invalid characters.";
		  return strerr;
	    }
	    if ((hyphencount > 1) || ((zipString.length==10) && ""+zipString.charAt(5)!="-")) 
	    {
	      strerr = "Zipcode appears incorrectly hypenated: expecting 5-4 digits ex: '99999-9999'.";
	      return strerr;
	    }
	}
	return strerr;
}
//End zipcode validation function

<!-- simple counter for limiting input to TEXTAREA -->
function charcnt(len, Targetobj, Cntobj) 
{
	if (Targetobj.value.length > len)
	  Targetobj.value = Targetobj.value.substring(0, len);
	else
	  Cntobj.value = len - Targetobj.value.length;
}

