/*
History
~~~~~~~~~~~~
Editor: Neil Salmond
Date: 16th June 2004
Purpose: Generic form check.  checkdisableandsubmit() is the main function: call it with the following line in the opening <form> tag

onsubmit="javascript: return checkdisableandsubmit(this);"

In the document itself, you give any form fields you like class="required" and title="Please enter a value for this field".  These are valid xhtml attributes, which is nice - the title attribute even pops up to help on all good browsers.  You should also do class="required" for the associated label, so that you can style the label text.

Note that your submit button must be called "submitbutton" for the disabled bit to work.

The most complicated bit of all this for me was getting the "return false" and "return true" bits in the right place

Note also that I had to use recursion because the form I originally designed this on had a hidden div with form elements inside it that were only hidden because the div was hidden.  Had I used form.elements[] it would have picked them up too, which is not what we want.  It's not the user's fault if they don't fill in a hidden or disabled field.

+++++++
Modifications
+++++++
Editor:	Michael Chen
DD-MMM-YY: Late August 2004
Watcha did:	All the variables preparing for js encoding.  Recursively collect all the form variable values to encrypt.	
~~~~~~~~~~~~~

Editor: 
Date: 
Modifications: 

OK: M&G May 26, 2006

*/
var allmsg = "";

bs="\\";
cs=' !"#$%&';
cs+="'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS"
+"TUVWXYZ^[_]`abcdefghijklmnopqrstuvwxyz{|}~\t\r\n"+bs;
cm=0;
cm1=0;
cflg="0";

/* Although this example has been prepared using
   a four-bit paradigm, you may elect to alter it
   to a 2-bit, 3-bit, 5-bit, etc. paradigm. For
   example, a 2 bit paradigm would look like this:
   four="00 01 10 11 ";
   fourletter="a  b  c  d "
   and the code in the encryption and decryption
   routines below would need to be altered to
   reflect the change in bit paradigm. We've
   put comments at the appropriate places. */
sixteen="0000 0001 0010 0011 0100 0101 0110 0111 "
       +"1000 1001 1010 1011 1100 1101 1110 1111 ";
/* Caution: don't use a space as a printing character
   in your construction of the variable "sixletter".
   Some alternates are included here for your own
   construction consideration.
   sixletter="A    B    C    D    E    F    G    H    "
            +"I    J    K    L    M    N    O    P    ";
   sixletter=".    ,    /    '    |    _    `    ~    "
            +"!    @    ^    *    -    :    ;    ?    "; */
sixletter=";    .    *    ,    x    `    i    :    "
         +"_    -    ^    <    >    '    ~    =    ";
		 
function samp(x){
 // First, we grab the two strings
 ls="";
 ls1="";
 kwd = document.ccform1.headword.value;
 kwdpd=kwd;
 msg=x;
 // Pad key to be long enough for message
 if (cflg==0){
  sl=msg.length;
  }
 else{
  sl=msg.length/2;
  }
 while (kwd.length<sl){
  kwd+=kwdpd;
  }
 //document.ex1.ps.value="I am now converting key and message strings...";
 if (cflg!=1){
  samp2();
  //setTimeout("samp2()",1000);
  }
 else{
  setTimeout("decryp()",1000);
  }
 }
 
 function samp2(){
 // Next, convert the 2 strings to binary
 for (var i=0;i<msg.length;i++){
  chk=kwd.charAt(i);
  cmk=cs.indexOf(chk)+32;
  chm=msg.charAt(i);
  cmm=cs.indexOf(chm)+32;
  for (var j=7;j>-1;j--){
   c=Math.pow(2,j);
   if (cmk>=c){
    cmk=cmk-c;
    ls+="1";
    }
   else{
    ls+="0"
    }
   if (cmm>=c){
    cmm=cmm-c;
    ls1+="1";
    }
   else{
    ls1+="0"
    }
   }
  }
 //document.ex1.ps.value="I am now encrypting message string...";
 samp3();
 //setTimeout("samp3()",1000);
 }
 
 function samp3(){
 // Next, convert the bits using key string
 ls2="";
 ls4="";
 for (var i=0;i<ls1.length;i++){
  ch=ls.charAt(i);
  ch1=ls1.charAt(i);
  if (ch=="0"){
   if (ch1=="0"){
    ch1="1";
    }
   else{
    ch1="0";
    } 
   }
  ls2+=ch1;
  }
 /* If a different bit paradigm is
    used, alter the loop below
    accordingly. */
 for (var i=0;i<ls2.length;i=i+4){
  ls3=ls2.substring(i,i+4);
  y=sixteen.indexOf(ls3);
  ls4+=sixletter.charAt(y);
  }
 ls4="Cut and paste the message below into the decryption page\n\n"+ls4; 
 document.ccform1.encoded.value = ls4;
 }

 
// recursively collect all the form variable values to encrypt 
function dorecursivecollection(mymode){
	if(mymode.name){
		 if (mymode.type !='hidden' && mymode.type !='submit' && mymode.name !='ccpaymenttype'){
		     if (mymode.type == "text") 
		        allmsg = allmsg + mymode.name.toUpperCase() + ": " + mymode.value +"\n";
			 else if (mymode.type == "select-one") 
			  allmsg = allmsg + mymode.name.toUpperCase() + ": " + mymode.options[mymode.selectedIndex].value + "\n";
			 else if (mymode.type == "radio") {
				if(mymode.checked)
				 allmsg = allmsg + mymode.name.toUpperCase() + ": " + mymode.value + "\n";}
		 }
	}
	else{
	var temp = mymode.childNodes;
	for (var i=0;i<temp.length;i++){
		//recurse thru them again
		dorecursivecollection(temp[i]);
	}
	}
}

function checkdisableandsubmit(myform){
	//get all the child nodes of the form
	var kids = myform.childNodes;
	for (var i=0;i<kids.length;i++){
		//recurse thru them, and if just one of you give us false
		if(dorecursivething(kids[i]) == false)
			return false;
	} 
	//credit card special treatment
	if (myform.name =='ccform1'){
		//for (var i=0;i<kids.length;i++){
			//recurse thru them, and if just one of you give us false
			//dorecursivecollection(kids[i]);
		//}
    //samp(allmsg);
	myform.submit();
	myform.submitbutton.disabled = true;
	return true;
	}
	else{
	//if we make it this far without returning false, then we're good to go
	myform.submit();
	myform.submitbutton.disabled = true;
	return true;
	}
}


function dorecursivething(mydomnode){
	
	//if the element is invisible, then it's not the user's fault it has no value
	//see morefields.js for why we have invisible required fields in the first place
	if (mydomnode.style){
		//two-stage 'if' to avoid throwing a "style doesn't have a display property" error
		if (mydomnode.style.display == "none"){
			//don't bother checking it's kids
			return true;
		}
	}
	
	//also if it's disabled then it's not their fault they didn't fill it in
	if (mydomnode.disabled){
		return true;
	}
	
	//if the element is required and we have a message in the title tag
	if (mydomnode.className=='required' && mydomnode.title){
		return dorequiredthing(mydomnode);
	}
	else {
		//check each of the kids of *this* one
		var kids = mydomnode.childNodes;
		for (var i=0; i<kids.length;i++){
			if(dorecursivething(kids[i]) == false)
				return false;
		}
		return true;
	}
}

function dorequiredthing(thisfield){
	//this field is required
	
	if (thisfield.value.length < 1){
		//show an alert with the text in the 'title' attribute
		alert(thisfield.title);
		//focus on the field to really make it easy for the user
		thisfield.focus();
		//don't submit the form
		return false;
	}
	
	//if the field's name has "amount" somewhere in it, then we assume it's a cash amount
	if (thisfield.name.indexOf("amount") > -1){
		//valid cash amounts are floating point numbers
		if (thisfield.value != parseInt(thisfield.value)){
			alert(thisfield.title);
			thisfield.focus();
			return false;
		}
		if (thisfield.value < 5){
			alert("Please enter a donation amount larger than $5");
			thisfield.focus();
			return false;
		}
	}
	
	//if the field's name has "mail" somewhere, then assume it's an email
	if (thisfield.name.indexOf("mail") > -1){
		var validemail = /^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/;
		if (!validemail.test(thisfield.value))
		{
			alert(thisfield.title);
			thisfield.focus();
			return false;
		}
	}
	
	//if the field's name has "card" somewhere in it, then we assume it's a credit card number
	if (thisfield.name.indexOf("card") > -1){
		//valid card numbers are only numbers and are four digits long
		var onlynumbers = /^\d+$/;
		if (
		(thisfield.value.length != 4)
		||
		(!onlynumbers.test(thisfield.value))
		){
			alert(thisfield.title);
			thisfield.focus();		
			return false;		
		}
	}
	
	//if the field's name has "description" somewhere in it, then we assume it's a big text field
	if (thisfield.name.indexOf("description") > -1){
		//we want to limit those to 4000 bytes
		if (thisfield.value.length > 3999)
		{
			alert(thisfield.title);
			thisfield.focus();		
			return false;		
		}
	}
	
	//if the field's name has "url" somewhere in it, then we assume it's a url
	if (thisfield.name.indexOf("url") > -1){
		//note that '/' is escaped to '\/'.  This was a pain in the ass to work out.
		var validurl = /(http|ftp):\/\/(www\.|(([a-zA-Z0-9]+)\.))?([a-zA-Z0-9\-]+)\.([a-z]{2,4})*(\.([a-z]{2})){0,1}/;
		if (!validurl.test(thisfield.value))
		{
			alert(thisfield.title);
			thisfield.focus();		
			return false;		
		}
	}
	
	
}

function resetforms() {
   for (i=0; i < document.forms.length; i++) {
     document.forms[i].reset();
   }
}