// JAVASCRIPT FILE FOR VALIDATING WEB REGISTRATIONS

// Calls all the routines to validate the contact details & demographics
// - formats the address, then validates the contact details, followed by demographics
function validateform(frm) {
   addformat(frm);
	if (!validateform2(frm)) {
		return false
	}
	if (!validatedemogs(frm)) {
		return false
	}
	return true
}



// This loops through the form and validates every field that has a
// validtype property set (normally specified in JS code at the end of the form document)

function validateform2(frm) {
	var x, lSuccess
	for (var i=0; i<frm.elements.length; i++) {
		x=frm.elements[i]
		if (validatefield(frm.elements[i])==false) {
			return false
		}
	}
	return true
}

// This validates the field to make sure it has been completed correctly.

function validatefield(field) {
	var temp
	switch (field.validtype) {
		case "text":
				temp=ltrim(trim(field.value))
				if (temp.length==0) {
					alert(field.errormsg)
					field.focus()
					return false
				}
				break;
		case "listitem":
				temp=ltrim(trim(field.options[field.selectedIndex].value))
				if (temp.length==0) {
					alert(field.errormsg)
					field.focus()
					return false
				}
				break;
		case "multilist":
				var gotone=0
				for (var i=0; i < field.options.length; i++) {
					if (field.options[i].selected==true) {
						gotone=1
						i=field.options.length
					}
				}
				if (gotone==0) {
					alert(field.errormsg)
					field.focus()
					return false
				}
				break;
		case "email":
				if (!emailCheck(field.value)) {
					alert(field.errormsg)
					field.focus()
					return false
				}
				break;
		case "ccno":
				if (!validateccno(trim(field.value))) {
					alert(field.errormsg)
					field.focus()
					return false
				}
				break;
		case "radio":
				var RetVal=false
				for (var j=0; j<field.length; j++) {
					if (field[j].checked==true) {
						RetVal=true
					}
				}
				return RetVal
				break;			
		default:
	}
}


// This function checks any of the demographics to ensure they have
// been completed. It only checks them if they are included in the
// checkdems array


function validatedemogs(frm) {
  for (var e = 0; e < checkdems.length; e++) {

    var el
	for (var f = 0; f < frm.elements.length; f++) {
		if (frm.elements[f].name == checkdems[e]) {
			el=frm.elements[f]
			f=frm.elements.length
		}
	}
	
    if (el.type == 'text' || el.type == 'textarea' ||
        el.type == 'password' || el.type == 'file' || el.type == 'select-one' ) { 
      if (el.value == '') {
        alert(demdescr[e]);
        el.focus();
        return false;
      }
    }
    else if (el.type.indexOf('select') != -1) {
      if (el.selectedIndex == -1) {
        alert(demdescr[e]);
        el.focus();
        return false;
      }
    }
    else if (el.type == 'radio') {
      var group = frm[el.name];
      var checked = false;
      if (!group.length)
        checked = el.checked;
      else
        for (var r = 0; r < group.length; r++)
          if ((checked = group[r].checked))
            break;
      if (!checked) {
        alert(demdescr[e]);
        el.focus();
        return false;
      }
    }
    else if (el.type == 'checkbox') {
      var group = frm[el.name];
      if (group.length) {
        var checked = false;
        for (var r = 0; r < group.length; r++)
          if ((checked = group[r].checked))
            break;
        if (!checked) {
          alert(demdescr[e]);
          el.focus();
          return false;
        }
      } else {
      	// if there is a field with the same name plus _TC set to Y, check that this is ticked.
	    var eltc="";
	    var elname="";
		for (var f1 = 0; f1 < frm.elements.length; f1++) {
			var elname=frm.elements[f1].name;
			var elname2=el.name
			elname=elname.toUpperCase();
			elname2=elname2.toUpperCase();
			if (elname == elname2+"_TC") {
				eltc=frm.elements[f1]
				f1=frm.elements.length
			}
		}
		if (eltc.value=="Y") {
			if (!el.checked) {
				alert(demdescr[e]);
				el.focus();
				return false;
			}
		}
	}
    }
  }
  return true;
}


// routine to check email integrity

function validateemail(s) {
	s=ltrim(trim(s))
	s=s.toLowerCase()
	if (s.indexOf("@") < 1) {
		return false
	}
	var cAfterAt=s.substr(s.indexOf("@")+1)
	
	if (s.indexOf(" ") >= 0) {
		return false
	} else if (s.indexOf(",") >= 0) {
		return false
	} else if (s.indexOf("/") >= 0) {
		return false
	} else if (s.indexOf("\\") >= 0) {
		return false
	} else if (s.indexOf(";") >= 0) {
		return false
	} else if (s.indexOf("<") >= 0) {
		return false
	} else if (s.indexOf(">") >= 0) {
		return false
	} else if (s.indexOf("(") >= 0) {
		return false
	} else if (s.indexOf(")") >= 0) {
		return false
	} else if (cAfterAt.indexOf("@") >= 0) {
		return false
	} else if (cAfterAt.indexOf(".") <1) {
		return false
	} else if (cAfterAt.indexOf("..") >=0) {
		return false
	}
	
	var cReverse=reversestring(cAfterAt)
	if (cReverse.indexOf(".")<2 || cReverse.indexOf(".")>4) {
		return false
	}
	return true
} 


function validateccno(st) {
  // Encoding only works on cards with less than 19 digits
  if (st.length == 0 )
    return (false);
  if (st.length > 19)
    return (false);

  sum = 0; mul = 1; l = st.length;
  for (i = 0; i < l; i++) {
    digit = st.substring(l-i-1,l-i);
    tproduct = parseInt(digit ,10)*mul;
    if (tproduct >= 10)
      sum += (tproduct % 10) + 1;
    else
      sum += tproduct;
    if (mul == 1)
      mul++;
    else
      mul--;
  }

  if ((sum % 10) == 0)
    return (true);
  else
    return (false);
}



// check postcode is valid

function validpcode(s) {
	s=s.toUpperCase()
	var temp1=chrtran(chrtran(s,".","")," ","")
	var temp2=""
	if (temp1.substr((temp1.length)-3,1)=="O") {
		temp1=temp1.substr(0,(temp1.length)-3)+"0"+temp1.substr((temp1.length)-2,2)
	}
	for (var i=0; i<temp1.length; i++) {
		if (isAlpha(temp1.substr(i,1))) {
			temp2=temp2+"X"
		} else if (isDigit(temp1.substr(i,1))) {
			temp2=temp2+"9"
		} else {
			temp2=temp2+"?"
		}
	}
	switch (temp2) {
		case "XX99XX":
		case "X9X9XX":
		case "X999XX":
		case "XX999XX":
		case "XX9X9XX":
		case "X99XX":
		case "XX9":
		case "X9X":
		case "X99":
		case "XX9":
		case "XX9":
		case "X9":
			return true
			break;
		default:
			return false
			break;
	}
	return false
}
// Check that a Expiry Data on Credit Card 

function checkccdate(frm) {
if (checkcard(frm))
{
d=new Date()
dMonth=d.getMonth()
dMonth+=1
dYear=d.getYear()
dYear-=2000
var exmonth=Number(frm.ccexp1.options[frm.ccexp1.selectedIndex].value)
var exyear=Number(frm.ccexp2.options[frm.ccexp2.selectedIndex].value)
if (exyear<dYear) {
        alert('Credit Card has Expired Year')
        frm.ccexp2.focus()
        return false
        }

if (exyear == dYear && exmonth<dMonth) {
        alert('Credit Card has Expired Month')
        frm.ccexp1.focus()
        return false
        }

}
else
{
return false
}
return true
}
// Check that a Credit card is a Valid Number

function checkcard(frm) {
        var cc1=0
        var cc2=""
        var cc3=0
        var ccsum=0
        var add=0
        var ctr=0
        cc=ltrim(trim(frm.ccno.value))
        if (cc.length==0) {
        alert('Please Enter a Card Number')
        frm.ccno.focus()
        return false
        }
        cc1=cc.length
        cc1=cc1-1
        while (cc1>=0) {
        if (cc.substr(cc1,1)>="0" && cc.substr(cc1,1)<="9") {
        cc2=cc2+cc.substr(cc1,1)
        }
        cc1=cc1-1
        }
        cc1=0
        while (cc1<cc2.length) {
                                if (cc3==1) {
                                             if (cc2.substr(cc1,1)>="5")
                                                 {
                                                  add = Number(cc2.substr(cc1,1))*2 -9;
                                                  }
                                              else
                                                  {
                                                  add = Number(cc2.substr(cc1,1)) *2;
                                                  }
                                              }
                                              else
                                              {
                                                  add = Number(cc2.substr(cc1,1));
                                              }
                ccsum=ccsum+add;
                if (cc3==1) {
                cc3=0;
                } else {
                cc3=1;
                }

                cc1=cc1+1;
                }
        while (ccsum>0)
        {
        ccsum=ccsum-10
        }
        if (ccsum<0)
        {
        alert ('Your Card number is invalid')
        frm.ccno.focus()
        return false
        }

        cc=ltrim(trim(frm.ccno.value))
        cc1=cc.length
        ctr=0;
        cc2=""
        while (ctr<=cc1) {
        if (cc.substr(ctr,1)>="0" && cc.substr(ctr,1)<="9") {
        cc2=cc2+cc.substr(ctr,1)
        }
        ctr=ctr+1
        }
        frm.ccno.value=cc2
        cc=ltrim(trim(frm.ccno.value))


        if (cc.length>16) {
         if (checkcardtype(frm,"SWIT")) {
         frm.cctype.options.value="SWIT"
         return true
         }
        else {
        alert ('We do not accept Switch Cards \nPlease use another type of Credit Card')
        frm.ccno.focus()
        return false
         }
         }

        if (cc.length==15) {
         if (checkcardtype(frm,"AMEX")) {
         frm.cctype.options.value="AMEX"
         return true
         }
        else {
        alert ('We do not accept American Express \nPlease use another type of Credit Card')
        frm.ccno.focus()
        return false
         }
         }
         if (cc.substr(0,1)=="4") {
         if (checkcardtype(frm,"VISA")) {
         frm.cctype.options.value="VISA"
         return true
         }
        else {
        alert ('We do not accept VISA Cards \nPlease use another type of Credit Card')
        frm.ccno.focus()
        return false
         }
         }

         if (cc.substr(0,1)=="5") {
         if (checkcardtype(frm,"MAST")) {
         frm.cctype.options.value="MAST"
         return true
         }
        else {
        alert ('We do not accept MasterCard \nPlease use another type of Credit Card')
        frm.ccno.focus()
        return false
         }
         }

return true
}
//alert(frm.cctype.options.length)
         //alert(frm.cctype.options[0].value)
         //alert(frm.cctype.options[1].value)
         //alert(frm.cctype.options[2].value)
         //alert(frm.cctype.options[3].value)

function checkcardtype(frm,req) {
        var y
        for (var j=0; j<frm.cctype.options.length; j++) {
                y=frm.cctype.options[j]
                if (y.value==req) {
                return true
                        }
        }
      return false
}




function emailCheck (emailStr) {

/* 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|xxx|jobs|mobi|travel)$/;

/* 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. */

//alert("Email address seems incorrect (check @ and .'s)");
return false;
}
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) {
//alert("Ths username contains invalid characters.");
return false;
   }
}
for (i=0; i<domain.length; i++) {
if (domain.charCodeAt(i)>127) {
//alert("Ths domain name contains invalid characters.");
return false;
   }
}

// See if "user" is valid 

if (user.match(userPat)==null) {

// user is not valid

//alert("The username doesn't seem to be valid.");
return false;
}

/* 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) {
//alert("Destination IP address is invalid!");
return false;
   }
}
return true;
}

// 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) {
//alert("The domain name does not seem to be valid.");
return false;
   }
}

/* 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) {
//alert("The address must end in a well-known domain or two letter " + "country.");
return false;
}

// Make sure there's a host name preceding the domain.

if (len<2) {
//alert("This address is missing a hostname!");
return false;
}

// If we've gotten this far, everything's valid!
return true;
}

