// ReAction Server - Support functions for XML based validation
// All code must comply with W3C DOM Level 1 Standard to ensure maximum cross browser support
//
// (c) Tikit Limited
// 
// Modifications:
// 10Mar05 - check for existence of maxLength attribute, only do check if it exists

function rsValidate(form)
{
// Get the node for this reaction from the XML island
// The form name will be 'RS' followed by the Reaction ID, e.g. RSREACTION1
var reactionXmlId = String(form.name + 'XML');
var reactionNode = rsGetReactionNode(reactionXmlId);
var field, ctrlNode, submitCtrl;
var warnMsg = '';
var ctrlLabel = '';
// Process each element in the form and match it with control info from the XML island
if (reactionNode){
	for (var i=0; i< form.length; i++) {
		field=form.elements[i];
		// look for and hang on to the submit control, we'll use it later
		if (field.name == 'SUBMIT' || field.type == 'submit')
			submitCtrl = field;
		// see if there's a node for this control
		ctrlNode = rsGetControlNode(reactionNode, field.name);
		if (ctrlNode){
			// there is... get the label
			ctrlLabel = rsGetChildNodeValue(ctrlNode, 'label');
			// if there's a trailing :, remove it so we can use it for prompts etc
			if (ctrlLabel){
				if (ctrlLabel.charAt(ctrlLabel.length-1) == ':')
					ctrlLabel = ctrlLabel.substr(0,ctrlLabel.length-1);
				}
			else{
				ctrlLabel = field.name;
				}
			// check control type
			switch(field.type){
				case 'text':
					// check for required status
					if (field.value.length == 0 && rsGetChildNodeValue(ctrlNode, 'required').toLowerCase() == 'yes'){
						warnMsg += '\n- A value is required for \'' + ctrlLabel + '\'.';
						}
					break;
				case 'textarea':
					// check for required status
					if (field.value.length == 0 && rsGetChildNodeValue(ctrlNode, 'required').toLowerCase() == 'yes'){
						warnMsg += '\n- A value is required for \'' + ctrlLabel + '\'.';
						}
					// check length
					var maxLen = rsGetChildNodeValue(ctrlNode, 'maxLength');
					if (maxLen && maxLen != '' && field.value.length >  maxLen){
						warnMsg += '\n- There is too much text for \'' + ctrlLabel + '\' - you entered ' + field.value.length + ' characters, but only ' + maxLen + ' are allowed.';
						}
					break;
				case 'select-one':
					break;
				case 'select-multiple':
					break;
				case 'checkbox':
					break;
				case 'submit':
					break;
				default:
					//alert('Other control type: ' + field.type);
					break;
			}	// end switch
		}
	}
	// If we haven't got the submit control yet (e.g. if it's a graphic), try this:
	if (!submitCtrl)
		submitCtrl = document.getElementById(form.name + 'SUBMIT');
}

// If no warning msg allow to proceed
if (!warnMsg){
	// hide submit button to prevent multiple clicks
	if (submitCtrl){
		// for IE, could set outerHTML. For cross-platform, get innerHTML on parent
		submitCtrl.parentNode.innerHTML = "<B>Processing, please wait...</B>";
		//OR could use: submitCtrl.width = 0;
		}
	return true;
	}

// Display warning 
alert('Please correct the following problems to allow us to process your response:\n' + warnMsg);

// return false so form doesn't get submitted
return false;
}

// Return the node representing the specified reaction
function rsGetReactionNode(reactionName)
{
// This will work for IE
var doc = window.document.getElementsByTagName('RSXMLINFO')[0];

// Need this for Mozilla
if (!doc)
	doc = window.document.getElementsByTagName('xml')[0];

if (doc){
	var eventNode = doc.getElementsByTagName('event')[0];
	var i = 0;
	var reactionNode;
	if (eventNode){
		while (eventNode.childNodes[i]){
			reactionNode = eventNode.childNodes[i];
			for (var j=0; j < reactionNode.attributes.length; j++){
				if (reactionNode.attributes[j]){
					if (reactionNode.attributes[j].name == 'id' && reactionNode.attributes[j].value == reactionName)
						return reactionNode;
					}
				}
			i++;
			}
		}
	}
else
	alert('Your browser does not permit us to validate your input.');
}

// Return a node representing the supplied control from the supplied reaction node
function rsGetControlNode(reactionNode, wantedControlName)
{
var controlsNode = reactionNode.getElementsByTagName('controls')[0];
var controlNode, controlName;
controlNode = controlsNode.firstChild;
while (controlNode){
	controlName = rsGetChildNodeValue(controlNode, 'name');
	if (controlName.toUpperCase() == wantedControlName.toUpperCase()){
		return controlNode;
		}
	controlNode = controlNode.nextSibling;
	}
}

// Return text contents of named child node
function rsGetChildNodeValue(parentNode, childNodeName)
{
var node = parentNode.firstChild;
while (node){
	if (node.nodeType == 1 && node.childNodes.length > 0){
		if (node.nodeName.toUpperCase() == childNodeName.toUpperCase()){
			return node.firstChild.nodeValue;
			}
		}
	node = node.nextSibling;
	}
// Return empty string if we didn't find match
return '';
}

