/*	ValidateForm.js - Validates form fields on CLient Side
* Author: Greg Brunet - www.SemperSoft.com, April 2000
* Copyright (c) 2000 Semper Software, Inc. All Rights Reserved.
* This script is a work-in-progress.
* It is released for testing purposes only, and not
* recommended for general use.
* Contact Tools@SemperSoft.com with feedback.
*/

function ValidateForm(objForm, sVOkay, sVOkayRC, sVError) {	// as boolean
// USAGE:
//	- add REQUIRED to any form elements to require them to be entered
//		(for 'selects' it will require an item > element 0 to be selected)
// - ALL OTHER items only apply of REQUIRED is TRUE (*** change this later!?)
//	- add ErrMsg="message" to display a message for all validation failures
//	- add MATCH="fieldname" to force entry to match another field's entry
//		(good to force passwords to match)
//	- add RANGE="lo,hi" to check for a text entry within a range
//	- add FORMAT="item" to check format of the text entry (** not implemented yet)

	// Sources include:
	//	http://www.fellowship.net/JerryNixon/vbscript/demos-script/demo_formRequiredFields.htm (JerryNixon@fellowship.net)
	//	http://developer.netscape.com/docs/examples/javascript/regexp/overview.html

	var ret = true;			// AS boolean;
	var bHiLite = true;		// AS boolean;
	var nRadioLen;			// AS integer;	// can't get true length from elements array!
//	var sVOkay = "white";	// AS string;
//	var sVOkayRC = "#FFCC33";	// AS string; - radio or checkbox background 
//	var sVError = "gold";		// AS string;	"red" "#FF6666"
	var bChecked;			// AS boolean;
	var nElement;			// AS integer;
	var sErrText = "";		// AS string;

//	alert("Got here 1 - Elements:" + objForm.elements.length);
	for (nElement=0; nElement <= objForm.elements.length-1; nElement++) {
		obj = objForm.elements[nElement];
//		alert("Processing " + obj.name + " [" + obj.type + "]: " + obj.length + " getAttr(Required): " + obj.getAttribute("Required"));
		if (obj.getAttribute("Required") != null) { 
//	alert(obj.name + " - Required: |" + obj.getAttribute("Required") + "|");
			switch (obj.type.toLowerCase()) {		// needed cause NN uses mixed case, IE uses lower
			case "radio":
			case "checkbox":
				eval("nRadioLen=objForm." + obj.name + ".length");
//				alert(obj.name + " RADIO-Length: [" + obj.length + "," + nRadioLen + "] Checked: " + obj.checked);
				if (nRadioLen > 1) {
//					alert("RL>1");
					okay = false;
			        for (i=0; i < nRadioLen; i++) {
						eval("bChecked=objForm." + obj.name + "[" + i + "].checked");
						if (bChecked) { okay = true; break; }
					}
					if (okay) 
						for (i=0; i < nRadioLen; i++) {eval("objForm." + obj.name + "[" + i + "].style.background= sVOkayRC"); }
					else {
						ret = false; 
						if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is not selected.\n"; 
						if (bHiLite) {for (i=0; i < nRadioLen; i++) {eval("objForm." + obj.name + "[" + i + "].style.background= sVError;");};}};
				} else {
//					alert("RL ! >1");
					if (! obj.checked ) {
						ret = false;  
						if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is not selected.\n";
						if (bHiLite) obj.style.background= sVError;
					} else obj.style.background= sVOkayRC;
				}
				break;
			case "text":
			case "password":
			case "textarea":
			case "":					// needed cuz NN doesn't set Type for default INPUT's (to TEXT)
//				alert("TEXT-" + obj.name + " Range: [" + obj.getAttribute("Range") + "]");
				if (obj.value == "") {
					ret = false;
					if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is required.\n";
					if (bHiLite) obj.style.background = sVError;
				} else obj.style.background= sVOkay;
// all other checks MUST HAVE "REQUIRED" defined to also be checked!
// Check for Range limits
				if (obj.getAttribute("Range") != null) {
					aRange = obj.getAttribute("Range").split(",");
					alert("Value:" + parseFloat(0+obj.value) + (parseFloat(0+obj.value) < aRange[0]) + (parseFloat(0+obj.value) > aRange[1]));
					if (parseFloat(0+obj.value) < aRange[0]) {
						ret = false;  
						if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is less than the minimum allowed value (" + aRange[0] + ").\n"; 
						if (bHiLite) obj.style.background = sVError;
					} else if (parseFloat(0+obj.value) > aRange[1]) {
						ret = false;  
						if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is greater than the maximum allowed value (" + aRange[1] + ").\n"; 
						if (bHiLite) obj.style.background = sVError;
					}
				};
// Check for Match requirements
				if (obj.getAttribute("Match") != null) {
					sMatch = obj.getAttribute("Match");
					if (obj.value != objForm.elements[sMatch].value) {
						ret = false;  
						sErrText += obj.getAttribute("ErrMsg") + " must match " + objForm.elements[sMatch].ErrMsg + "\n";
						if (bHiLite) obj.style.background = sVError;
					}					
				};
// Check for EMail address
				if (obj.getAttribute("EMail") != null) {
//	alert(obj.name + " - EMAIL ErrMsg: |" + obj.getAttribute("ErrMsg") + "|");
					var i = 1;
					var s = obj.value;
					var sLength = s.length;
					var emailRet = true;
				
					// look for @ 
					while ((i < sLength) && (s.charAt(i) != "@")) { i++ }
					if ((i >= sLength) || (s.charAt(i) != "@")) emailRet = false;
					else i += 2;
					// look for .
					if (emailRet) {
						while ((i < sLength) && (s.charAt(i) != ".")) { i++ }
						// there must be at least one character after the .
						if ((i >= sLength - 1) || (s.charAt(i) != ".")) emailRet = false;
					}
					// if not valid - tell them
					if (! emailRet) {
						ret = false;
						if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " must be an email address.\n";
						if (bHiLite) obj.style.background = sVError;
					}
				};
				break;

			case "select-one":
			case "select-multiple":
//				alert("SELECT-Length: [" + obj.length + "] SI: " + obj.selectedIndex);
				if (obj.selectedIndex < 1) {
					ret = false;  
					if (obj.getAttribute("ErrMsg") != null) sErrText += obj.getAttribute("ErrMsg") + " is not selected.\n"; 
					if (bHiLite) obj.style.background= sVError;
				} else obj.style.background= sVOkay;
				break;
			case "button":
			case "submit":
			case "reset":
				break;
			}
		}
	}

	if (! ret) alert(sErrText);	
	return ret;
}

function isEmail (s)
{   if (isEmpty(s)) 
       if (isEmail.arguments.length == 1) return defaultEmptyOK;
       else return (isEmail.arguments[1] == true);
   
    // is s whitespace?
    if (isWhitespace(s)) 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 return true;
}
