/* usage example

<script>
	var record = <DATABASE RECORD AS RECEIVED FROM XPS>
	//var useForm = "formname";	//to process a form with a name other than form
</script>

<html>
	<head>
		<script language="javascript" src="../include/forms.js"></script>
	</head>
	<body onLoad="gw_init()" onUnload="gw_onunload()">
		<div id="errors"></div>
		<form method="post" name="form" onSubmit="return validate(this);" error="Errors in form:">
			<input type="text" name="email" required="true" valid="email" remember="cb('rememberMe')" ignoreInitialfocus="cb('rememberMe')" error="Please enter valid email" value="" size="16" maxlength="32" class="inputtext" onKeyUp="submitOnEnter(event)" >
			Name: <input type="text" name="name" required="true" error="Name is a required field" size="11" maxlength="11" /><br />
			Seats: <input type="text" name="seats" valid="number" required="true" from="10" to="15" error="Seats must contain a valid number from 10 to 15"/><br />
			Password: <input type="password" id="USER_PASSWORD" class="input" valid="string" minlength="6" required="true" error="Password must be at least 6 characters long" maxlength="20" size="20" />
			<input type="password" name="password2" class="input" valid="equals" other="password1" error="Password fields must match" maxlength="20" size="20" />
			ip: <input type="text" name="ip" valid="ip" required="true" error="Valid IP address required"/><br />
			date: <input type="text" name="date" valid="date" required="true" error="Invalid date" ID="Text1"/><br />
			<input type="checkbox" name="rememberMe" rememberForm="true" checked>
			<input type="checkbox" name="agree" id="agree" required="true" error="Please check the checkbox to indicate that agree with the terms of the program">
  			<input type="submit" value="Submit" />
		</form>
	</body>
</html>

*/

	var gwFormSubmitCanceled	= false;
	onLoad0.add(formInit);

	function getForm() {
		var form;	
		if (typeof(useForm)!="undefined") {
			form = getObject(useForm); 
		} else {
			form = getObject("form");	//default form name is form
		}
		if (typeof(form)=="undefined")  {	
			isFormInited=false;
			return null;
		}
		if (!isFormInited) {
			formInit();
		}
		return form;
	}

	var isFormInited=false;
	var firstFieldFound = false;
	function formInit() {
		if (isFormInited) return;
		isFormInited = true;

		var i;
		var form = getForm();
		if (form == null) return;
		var fields=getChildren(form);

		// look for rememberMe field
		for (i=0;i<fields.length;i++) {
			switch (getFieldType(fields[i])) {
				case "input" :
					if (getAtt(fields[i], "rememberForm") != null) {
						remember(fields[i], false);
						fields[i].onclick = reactToRememberForm;
					}
				break;
			}
		}
	
		// update checkboxes first so ignoreInitialfocus can be understood with condition
		for (i=0;i<fields.length;i++) {
			switch (getFieldType(fields[i])) {
				case "input" :
					var onclick =fields[i].onclick;
					if (onclick!=null) {
						if (onclick.toString().indexOf("linkTo(this")!=-1) fields[i].onclick();
					}
			}
		}

		// who should we focus on?
		for (i=0;i<fields.length;i++) {
			switch (getFieldType(fields[i])) {
				case "input" :
					if (!firstFieldFound) {
						if (getAtt(fields[i], "type") == "hidden") continue;
						var ignoreinitialfocus = getAtt(fields[i], "ignoreinitialfocus");
						if (typeof(ignoreinitialfocus)!="undefined") {
							if (eval(ignoreinitialfocus)) continue;
						}
						fields[i].focus();
						firstFieldFound=true;
					}
					break;
			}
		}

		// see if field need to read from cookies based on checkbox
		for (i=0;i<fields.length;i++) {
			switch (getFieldType(fields[i])) {
				case "input" :
					if (getAtt(fields[i], "remember")!=null) remember(fields[i], false);
				break;
				case "select" :
					if (getAtt(fields[i], "remember")!=null) remember(fields[i], false);
				break;
			}
		}

		// fill in information from the database automagically
		if (typeof(record)!="undefined") {
			for (i=0;i<fields.length;i++) {
				var field		= fields[i];
				var type		= getFieldType(field); 
				var newvalue	= record[field.name];
				var calculated	= field.calculated;
				if (typeof(calculated)!="undefined" && calculated!=null) {
					newvalue = eval(calculated);	//calculate the value
				}
				
				var isVisible	= field.isVisible;
				if (typeof(isVisible)!="undefined" && isVisible!=null) {
					var show = eval(isVisible);
					if (!show) {
						field.style.visibility = "hidden";
					}
				}
				
				var isEnabled	= field.isEnabled;
				if (typeof(isEnabled)!="undefined" && isEnabled!=null) {
					var enable = eval(isEnabled);
					if (!enable) {
						field.disabled = true;
					}
				}
				
				if (typeof(newvalue)=="undefined") continue;
				if (field.gw_done==true) continue;
				field.gw_done = true;
		
				switch (type) {
					case "input" :
					case "textarea" :
						var subtype = field.type;
						switch (subtype) {
							case "checkbox" :
								field.checked = (newvalue=="1");
							break;
							default :
								field.value = newvalue;
							break;
						}
					break;
					case "span" :
						field.innerHTML = newvalue;
					break;
					case "select" :
						var selected	= record[field.name];
						//newvalue == selected
						/*
						if (typeof(newvalue[0])=="undefined") {
							field.options.add(new Option(newvalue, 0), 0);
						} else {
							for (var i=0; i<newvalue.length; i++) {
								field.options.add(new Option(newvalue[i], i), 0);
							}
						}
						*/
						for (var i=0; i<field.options.length; i++) {
							if (field.options[i].value==selected) field.selectedIndex = i;
						}
					break;
				}
			}
		}	// form fill-in
		
		isFormInited=true;
	}

	function getUpdate() {
		var update = new Object();
		var fields=getChildren(form);
		for (i=0;i<fields.length;i++) {
			var field		= fields[i];
			var type		= getFieldType(field); 
			var name		= field.name;
			if (typeof(record[name])=="undefined") continue;

			switch (type) {
				case "input" :
				case "textarea" :
					var subtype = field.type;
					switch (subtype) {
						case "checkbox" :
							update[name] = (field.checked ? "1" : "0");
						break;
						default :
							update[name] = field.value;
						break;
					}
				break;
				case "select" :
					update[name] = field.options[field.selectedIndex].text;
				break;
			}
		}
		return update;
	}

	function submitOnEnter(event) {
		var code = 0;
		if (typeof(event.which)!=UNDEFINED)
			code = event.which;
		else
			code = event.keyCode;
		if (code==13) submitForm(getForm());
	}

	function getAtt(field, att) {
		try {
			return field.getAttribute(att);
		} catch(err) { return null; }
	}
	
	function getAttLC(field, att) {
		try {
			return getAtt(field, att).toLowerCase();
		} catch(err) { return null; }
	}
	
	function getName(field) {
		var temp = getAtt(field, "name");
		if (typeof(temp)=="undefined") temp = getAtt(field, "id");
		return temp;
	}
	
	var firstComplain=null;
	var lastComplain=null;
	var errorMsg="", errMsgAlert="";
	function initComplain() {
		firstComplain=null;
		lastComplain=null;
		errorMsg="";
		errMsgAlert="";
	}
	
	function complain(field) {
		if (lastComplain==field) return;
		lastComplain=field;
		if (firstComplain==null) firstComplain=field;
		var error = getAtt(field, "error");
		if (error==null) error="Error with field: "+field.name;
		errorMsg+="<li>"+error+"</li>\r\n";
		errMsgAlert+="- "+error+"\r\n";
	}
	
	function summarizeComplain(form) {
		if (firstComplain!=null) {
			firstComplain.focus();
		}
		
		if (errorMsg!="") {
			var error = getAtt(form, "error");
			var prefix = "<font size=\"+1\" color=\"red\"><b>"+error+"</b></font>\r\n<font color=\"red\">\r\n";
			var postfix = "</font>\r\n";
			try {
				getObject("errors").innerHTML=prefix+errorMsg+postfix;
			} catch(err) {}
			alert(error+"\r\n"+errMsgAlert);
			return true;
		} else {
			return false;
		}
	}
	
	function field(name) {
		return getObject(name).value;
	}
	
	function cb(name) {
		return getObject(name).checked;
	}
	
	//
	function submitForm(form) {
		if (validate(form)) form.submit();
	}
	
	//			for (g in f[i])	if (g.toLowerCase()=="required") alert(f[i][g]);
	function validate(form, callback)	{
		if (gwFormSubmitCanceled) return true;
		reactToRememberFormNow();
		if (!isFormInited) {
			alert("Browser not supported.  Please use IE 5.0 or higher");
			return false;
		}
		initComplain();
		var i;
	//	var fields=getChildren(form);
		var fields=form;
		for (i=0;i<fields.length;i++) {
			var value = oGetField(fields[i]);
			var required = false;
			
			// alert('Element type is "'+ getFieldType(fields[i])+'"\nValue is: "'+value+'"');
			
			var ftype	= getFieldType(fields[i]);
			if ((ftype=="input" || ftype=="select" || ftype=="textarea"))  {
				try {
					required = eval(getAttLC(fields[i], "required"))
				} catch(err) {}
				if (required && value=="") {
					complain(fields[i]);
					continue;
				}
				
				var regExp		= getAttLC(fields[i], "regexp");
				var checkValid	= getAttLC(fields[i], "valid");
				switch (checkValid) {
					case "number"		: 
						regExp = "(^\\d+$)";
						if (!valid(regExp, value)) {
							complain(fields[i]);
						} else {
							var from = getInt(getAtt(fields[i], "from"));
							var to = getInt(getAtt(fields[i], "to"));
							var val = getInt(value);
							//alert(val+":"+from+":"+to);
							if (val!=null && ((from!=null && val<from) || (to!=null && val>to))) complain(fields[i]);
						}
						var min = getInt(getAtt(fields[i], "minlength"));
						var val = getInt(min);
						if (required) {
							if (value.length<val) complain(fields[i]);
						} else {
							if (value.length>0 && value.length<val) complain(fields[i]);
						}
						continue;
					break;
					case "string"		: 
						var min = getInt(getAtt(fields[i], "minlength"));
						var val = getInt(min);
						if (required) {
							if (value.length<val) complain(fields[i]);
						} else {
							if (value.length>0 && value.length<val) complain(fields[i]);
						}
						continue;
					break;
					case "date"			:
						if (!checkdate(fields[i])) {
							if (required || value!='')
							{
								complain(fields[i]);
							}
						}
					break;
					case "creditcard"	:
						if (LuhnCheck(value)==false) complain(fields[i]);
					break;
					case "equals"	:
						var other = getAtt(fields[i], "other");
						if (getField(other) != oGetField(fields[i])) complain(fields[i]);
					break;
					case "ip"			:
						regExp = "(^[1,2]?\\d{1,2}\\.[1,2]?\\d{1,2}\\.[1,2]?\\d{1,2}\\.[1,2]?\\d{1,2}$)"
					break;
					case "email"		:
						regExp = "^[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$";
					break;
				}
				if (!valid(regExp, value)) complain(fields[i]);
			}
		}
	
		var response = !summarizeComplain(form);
		if (response) {
			if (typeof(callback)!="undefined") return callback();
		}
		return response;
	}
	
	function valid(regExp, value) {
		if (value!=""&&regExp!=null&regExp!="") {
			var re=new RegExp(regExp);
			return re.test(value);
		}
		return true;
	}
	
	function getInt(string) {
		try {
			if (string!=null&&string!="") return parseInt(string);
		} catch(err) {}
		return null;
	}
	
	function reactToRememberForm() {
		setTimeout("reactToRememberFormNow()",1);
	}
	function reactToRememberFormNow() {
		var i;
		var form = getForm();
		if (form == null) return;
		var fields=getChildren(form);
		for (i=0;i<fields.length;i++) {
			switch (getFieldType(fields[i])) {
				case "input" :
					if (getAtt(fields[i], "remember")!=null || getAtt(fields[i], "rememberForm")!=null) {
						remember(fields[i], true);
					}
				break;
			}
		}
	}
	
	var cookiePrefix	= "gatherworks_cookie_";
	function remember(obj, update) {
		var ob				= obj;
		if (typeof(ob)==UNDEFINED || (typeof(ob.name)==UNDEFINED && typeof(ob.id)==UNDEFINED)) {
			ob 		= this;
			update	= true;
		} else {
			//at isFormInited as there is a param passed
			ob.onChange = remember; //callback will not contain a param
			ob.onblur = remember; //callback will not contain a param
		}

		var type			= getFieldType(ob).toLowerCase();
		var condition		= getAtt(ob, "remember");
		var defaultValue	= oGetField(ob);
		var name			= ob.id;
		if (typeof(name)==UNDEFINED) name = ob.name;

		if (condition==null || condition=="on") condition="true";
		condition = eval(condition);
		if (condition==false) {
			removeVar(cookiePrefix+name);
			return;
		}

		switch (type) {
			case "input" :
				if (update) {
					setVar(cookiePrefix+name, defaultValue);
				} else {
					//get value from cookie and put into field
					var cookie = getVar(cookiePrefix+name, defaultValue);
					oSetField(ob, cookie);
				}
			break;
			case "select" :
				if (update) {
					setVar(cookiePrefix+name, defaultValue);
				} else {
					//get value from cookie and put into field
					var cookie = getVar(cookiePrefix+name, defaultValue);
					if (cookie!="") oSetField(ob, cookie);
				}
			break;
		}
	}
	
	/////////////////////////////////// BEGIN: DATE Functions
	function checkdate(objName) {
		var datefield = objName;
		if (chkdate(objName) == false) {
			datefield.select();
			datefield.focus();
			return false;
		}
		return true;
	}
	
	function chkdate(objName) {
		var strDate = objName.value;
		
		if (!strDate.match("^[0-9]{4}-([1-9]|0[1-9]|1[012])-([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])$", "g")) {
			return false;
		}
		
		return true;
	}
	
	function LeapYear(intYear) {
		if (intYear % 100 == 0) {
			if (intYear % 400 == 0) { return true; }
		} else {
			if ((intYear % 4) == 0) { return true; }
		}
		return false;
	}
	
	function dateRange(from, to) {
		if (Date.parse(from.value) <= Date.parse(to.value)) {
			return true; //alert("The dates are valid.");
		} else {
			return false;
			//if (from.value == "" || to.value == "") 
			//alert("Both dates must be entered.");
			//else 
			//alert("To date must occur after the from date.");
		}
	}
	
	/////////////////////////////////// END: DATE Functions
	
	
	/////////////////////////////////// BEGIN: Credit Card Validation
	// Form Field Validation Functions:
	//
	// isValidExpDate(formField,fieldLabel,required)
	//   -- checks for date in the format MM/YY or MM/YYYY against the current date
	// isValidCreditCardNumber(formField,ccType,fieldLabel,required)
	//   -- checks for valid credit card format using the Luhn check and known digits about various cards
	//
	
	function validRequired(formField,fieldLabel) {
		var result = true;
		
		if (formField.value == "") {
			alert('Please enter a value for the "' + fieldLabel +'" field.');
			formField.focus();
			result = false;
		}
		
		return result;
	}
	
	
	function allDigits(str) {
		return inValidCharSet(str,"0123456789");
	}
	
	function inValidCharSet(str,charset) {
		var result = true;
		
		for (var i=0;i<str.length;i++)
			if (charset.indexOf(str.substr(i,1))<0)
			{
				result = false;
				break;
			}
		
		return result;
	}
	
	function isValidExpDate(formField,fieldLabel,required) {
		var result = true;
		var formValue = formField.value;
	
		if (required && !validRequired(formField,fieldLabel))
			result = false;
	  
		if (result && (formField.value.length>0)) {
			var elems = formValue.split("/");
			
			result = (elems.length == 2); // should be two components
			var expired = false;
			
			if (result) {
				var month = parseInt(elems[0],10);
				var year = parseInt(elems[1],10);
				
				if (elems[1].length == 2) {
					year += 2000;
				}
				
				var now = new Date();
				
				var nowMonth = now.getMonth() + 1;
				var nowYear = now.getFullYear();
				
				expired = (nowYear > year) || ((nowYear == year ) && (nowMonth > month));
				
				result = allDigits(elems[0]) && (month > 0) && (month < 13) &&
						 allDigits(elems[1]) && ((elems[1].length == 2) || (elems[1].length == 4));
			}
			
			if (!result) {
				alert('Please enter a date in the format MM/YY for the "' + fieldLabel +'" field.');
				formField.focus();
			} else {
				if (expired) {
					result = false;
					alert('The date for "' + fieldLabel +'" has expired.');
					formField.focus();
				}
			}
		} 
		
		return result;
	}
	
	function isValidCreditCardNumber(formField,ccType,fieldLabel,required) {
		var result = true;
		var ccNum = formField.value;
	
		if (required && !validRequired(formField,fieldLabel))
			result = false;
	 
		if (result && (formField.value.length>0)) { 
			if (!allDigits(ccNum)) {
				alert('Please enter only numbers (no dashes or spaces) for the "' + fieldLabel +'" field.');
				formField.focus();
				result = false;
			}	
	
			if (result) { 
				if (!LuhnCheck(ccNum) || !validateCCNum(ccType,ccNum)) {
					alert('Please enter a valid card number for the "' + fieldLabel +'" field.');
					formField.focus();
					result = false;
				}	
			} 
	
		} 
		
		return result;
	}
	
	function LuhnCheck(digits)
	{
		digits = digits.replace(/[^0-9]/g, "");
	   var sum = 0;
	   var alt = false;
	   var numvar = 0;
	   for(var i = digits.length - 1; i >= 0; i--)
	   {
	     numvar = parseInt(digits.charAt(i));
	     if(alt)
	     {
	       numvar *= 2;
	       if(numvar > 9)
	       {
	         numvar -= 9;
	       }
	     }
	     sum += numvar;
	     alt = !alt;
	   }
	   return sum % 10 == 0;
	 }
	
	function GetRadioValue(rArray)
	{
		for (var i=0;i<rArray.length;i++)
		{
			if (rArray[i].checked)
				return rArray[i].value;
		}
		
		return null;
	}
	
	
	function validateCCNum(cardType,cardNum)
	{
		var result = false;
		cardType = cardType.toUpperCase();
		
		var cardLen = cardNum.length;
		var firstdig = cardNum.substring(0,1);
		var seconddig = cardNum.substring(1,2);
		var first4digs = cardNum.substring(0,4);
	
		switch (cardType)
		{
			case "VISA":
				result = ((cardLen == 16) || (cardLen == 13)) && (firstdig == "4");
				break;
			case "AMEX":
				var validNums = "47";
				result = (cardLen == 15) && (firstdig == "3") && (validNums.indexOf(seconddig)>=0);
				break;
			case "MASTERCARD":
				var validNums = "12345";
				result = (cardLen == 16) && (firstdig == "5") && (validNums.indexOf(seconddig)>=0);
				break;
			case "DISCOVER":
				result = (cardLen == 16) && (first4digs == "6011");
				break;
			case "DINERS":
				var validNums = "068";
				result = (cardLen == 14) && (firstdig == "3") && (validNums.indexOf(seconddig)>=0);
				break;
		}
		return result;
	}
	
	function validCCForm(ccTypeField,ccNumField,ccExpField)
	{
		var result = isValidCreditCardNumber(ccNumField,ccTypeField.value,"Credit Card Number",true) &&
			isValidExpDate(ccExpField,"Expiration Date",true);
		return result;
	}
	/*
	http://forums.devshed.com/t98154/se942e87a81eb29d47402ca54bf67f470.html
	http://www.ietf.org/rfc/rfc3106.txt
	<p>Card Type:
	<select name="Ecom_Payment_Card_Type">
	<option value="VISA">Visa
	<option value="MASTERCARD">MasterCard
	<option value="AMEX" selected>American Express
	<option value="DISCOVER">Discover
	<option value="DINERS">Diners Club</option> 
	</select><br>
	Credit Card Number: <input name="Ecom_Payment_Card_Number" size="19" maxlength="19"><br>
	Expiration Date (MM/YY): <input name="ccExp" size="7"><br>
	</p>
	
	*/
	
	/////////////////////////////////// END: Credit Card Validation
	
function checkExpireDate(monthId, yearId) {
	var m = document.getElementById(monthId);
	var y = document.getElementById(yearId);
	var today = new Date();
	var month = today.getMonth()+1;
	var year = today.getFullYear();
	var monthNodes = m.childNodes;
	
	if (y.value==year) {
		for (var i=0; i<monthNodes.length; i++) {
			if (monthNodes[i].value<month && monthNodes[i].value!='') {
				try {
					monthNodes[i].disabled = true;
				} catch (er) {}
			}
		}
		if (m.value<month && m.value!='') {
			m.selectedIndex = 0;
			alert("Date is invalid. Please check the expiration date on your card.");
		}
	} else if (y.value>year || y.value=='') {
		for (var i=0; i<monthNodes.length; i++) {
			try {
				monthNodes[i].disabled = false;
			} catch (er) {}
		}
	}
}

