/*
 * Form.js
 *
 * Provided utility classes and functions for CMS forms
 *
 */

function printReceipt() {
	formObj=document.getElementById('PREVIEW_FORM');
	printVersion=window.open('about:blank','FORM_PREVIEW','toolbar=no,width=620,height=500,resizable=yes,menubar=yes,status=no,scrollbars=yes,left=100,top=100');
	formObj.target = 'FORM_PREVIEW';
	formObj.submit();
	printVersion.focus();
	return true;
}

/*
 * CMSAPI_Form
 * 
 * A part of the CMS_API, CMSAPI_Form is a Javascript class that helps provide client
 * side form validation, using an XML form configuration file.
 *
 * Copyright 2006 The University of Sydney
 *
 * Authors: Andrew Jessup
 *
 */

function CMSAPI_Form( validatorPath ){

	var requestObj = getHTTPObject(); 	// An Ajax helper class
	var validatorXMLObj = new Object;
	//var validatorXMLObj;

	this.start_validator_load = function() {
		requestObj.open("GET", (validatorPath), true);
		requestObj.onreadystatechange = this.end_validator_load;
		requestObj.send(null);
		return false;
	}

	this.end_validator_load = function() {
		if (requestObj.readyState == 4) {
			if(requestObj.status == 200) {
				this.validatorXMLObj=requestObj.responseXML;
				var formid = this.validatorXMLObj.getElementsByTagName("form")[0].getAttribute("identifier");
				var questionsEl = this.validatorXMLObj.getElementsByTagName("question");
				// Look for the 'submit' trigger to find the id of the submit & clear button
				var triggersEl = this.validatorXMLObj.getElementsByTagName("trigger");
				for(i=0;i<triggersEl.length;i++){
					var buttonItem = document.getElementById(triggersEl[i].getAttribute("obj_id"));
					var actionsEl = triggersEl[i].getElementsByTagName("action");
					for(j=0;j<actionsEl.length;j++){
						if(actionsEl[j].getAttribute("type")=="submit") {
							// Attach an event handler to the submit button to check the form
							buttonItem.onclick= function() {		// Called by form's onSubmit function
								return checkForm(questionsEl, formid);
							}
						}
					}
				}
			} else if (requestObj.status == 404) {
				showDebug("Configuration file "+validatorPath+" not found");
			}
		}
	}

	this.start_validator_load();
	this.validatorPath = validatorPath;	// URL to the validation XML file
} 

/*
 * This function clears the form
 */

function clearForm( formid ) {
	document.getElementById(formid).reset();
	return false;
}

/*
 * This is the function which actually checks that the fom is valid;
 */

function checkForm( questionsObj, formid ) {
	var formValid = true;
	
	// For each <question> in the schema...
	for(i=0;i<questionsObj.length;i++){
		var questionValid=true; var formItemValue = "";
		var questionObj = questionsObj[i];
		
		// Get the corresponding form item
		var formItemName = questionObj.getAttribute("identifier");
		var questionType = questionObj.getElementsByTagName("display")[0].getAttribute("mode");
		
		// Get the the value of the item (which iscontigngent on the type of item)
		switch(questionType) {
			case 'textline':
			case 'textarea':
				formItemValue = document.getElementsByName(formItemName)[0].value;
				break;
			case 'select':
				var theSelect = document.getElementsByName(formItemName)[0];
				formItemValue = theSelect[theSelect.selectedIndex].value;
				break;
			case 'date':
				var dateYear	= document.getElementsByName(formItemName+"_year")[0].value;
				var dateDay		= document.getElementsByName(formItemName+"_date")[0].value;
				var dateMonth	= document.getElementsByName(formItemName+"_month")[0].value;
				formItemValue = (dateYear && dateMonth && dateDay);
				break;
			case 'radio':
				radioItem = document.getElementsByName(formItemName);
				for (var q=0; q < radioItem.length; q++) {
					if (radioItem[q].checked)
						formItemValue = radioItem[q].value; 
				}
				break;
			case 'statement':
				statementItem = document.getElementsByName(formItemName)[0];
				if (statementItem.checked)
					formItemValue = 1;
				else
					formItemValue = 0;
				break;
			case 'checkbox':
				var valueArr = questionObj.getElementsByTagName("value");
				for (var q=0; q<valueArr.length; ++q) {
					if(document.getElementsByName(formItemName+'_'+valueArr[q].getAttribute("encoded").replace(/\./g,'_dot_'))[0].checked)
						formItemValue =+ valueArr[q].getAttribute("encoded");
				}
				break;
			case 'multiselect':
				var theSelect = document.getElementsByName(formItemName+"[]")[0];
				for (var q=0; q<theSelect.options.length; q++) {
					if(theSelect.options[q].selected==true)
						formItemValue =+ theSelect.options[q].text;
				}
				break;
		}
		
		// Reset the item
		displayError("",formItemName, false);
		
		// For each <validation>...
		for(j=0;j<questionObj.getElementsByTagName("validation").length;j++) {
			switch(questionObj.getElementsByTagName("validation")[j].getAttribute("type")) {
				case "mustNotBeEmpty":
					if(formItemValue.length==0 || formItemValue==0) {
						displayError(getCustomErrMsg("Please complete this field",questionObj.getElementsByTagName("validation")[j]),formItemName, true);
						formValid = false; questionValid = false;
					}
					break;
				case "mustNotBeNull":
					if(formItemValue == "null" || formItemValue == "NULL") {
						displayError(getCustomErrMsg("Please complete this field",questionObj.getElementsByTagName("validation")[j]),formItemName, true);
						formValid = false; questionValid = false;
					}
					break;
				case "mustBeEmail":
					if(!isEmail(formItemValue)) {
						displayError(getCustomErrMsg("You must provide a valid e-mail address",questionObj.getElementsByTagName("validation")[j]),formItemName, true);
						formValid = false; questionValid = false;
					}
					break;
			}

		}
	}

	toggleErrorBanner(!formValid, formid);
	if(!formValid)
		location.href="#";	// Go to top of form

	return formValid;
}

/*
 * This function checks to see if the schema dictates a custom error message.
 * If no custom message set then it returns the default.
 */

function getCustomErrMsg( defaultString, validationObj ) {
	var errMsg = defaultString;
	var customStrings = validationObj.getElementsByTagName("errorstring");
	if(customStrings.length>0)
		errMsg = getObjInnerText(customStrings[0]);
	return errMsg;
}

function getObjInnerText(obj){
	/* This is patch for cross platform DOM node access */
	if (document.all) { // IE;
		return obj.text;
	} else{
		if (obj.textContent) {
			return obj.textContent;
		} else {
			return "";
		}
	}
} 

function toggleErrorBanner( doShow, formid ) {
	bannerObj = document.getElementById(formid+"_errorsummary");
	if(doShow)
		bannerObj.style.display = 'block';
	else
		bannerObj.style.display = 'none';
}

function isEmail(str) {
	if(str.length==0)
		return true;
	var supported = 0;
	// are regular expressions supported?
	if (window.RegExp) {
		var tempStr = "a";
		var tempReg = new RegExp(tempStr);
		if (tempReg.test(tempStr))
			supported = 1;
	}
	if (!supported) 
		return (str.indexOf(".") > 2) && (str.indexOf("@") > 0);
	var r1 = new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)");
	var r2 = new RegExp("^.+\\@[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,4}|[0-9]{1,3})$");
	return (!r1.test(str) && r2.test(str));
}

function showDebug(errString) {
	alert("Form configuration error: "+errString);
	return true;
}

function displayError(errString, elementName, doShow) {

	var containerElement = document.getElementById(elementName+"_container");
	var errstringElement = document.getElementById(elementName+"_errors");
	if(doShow) {
		containerElement.className="angry";
		if(errstringElement.innerHTML) {
			var curHTML = errstringElement.innerHTML.toString();
			errstringElement.innerHTML = curHTML + ("<br />"+errString);
		} else {
			errstringElement.innerHTML=errString;
		}
	} else {
		containerElement.className="";
		errstringElement.innerHTML="";
	}

}

/* A helper function for determing how to get an XMLHttpRequest object on different browsers */

function getHTTPObject() {

		var xmlhttp;

		/*@cc_on
		@if (@_jscript_version >= 5)
		try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
		xmlhttp = false;
		}
		}
		@else
		xmlhttp = false;
		@end @*/

		if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
			try {
				xmlhttp = new XMLHttpRequest();
			} catch (e) {
				xmlhttp = false;
			}
		}

		return xmlhttp;

}

function changeBox(box_id) {
	box = document.getElementById(box_id);
	box.checked = !box.checked;
}

