/**
 * DUE FOR REDESIGN
 * Remove dependancy on labels
 */
/**
* Form Field Validation
*/
var ValidationCode = new Object();
ValidationCode.VALID = 0;
ValidationCode.INVALID = 1;
ValidationCode.EMPTY = 2;

function validate(form) {
	var reqLabels = getRequiredLabels(form);
	var errorMessage = '';

	for(var i = 0; i < reqLabels.length; i++) {
		var code = validateLabelField(reqLabels[i]);
		if(code != ValidationCode.VALID) {
			// TODO: add error class to label
			var labelText = getLabelText(reqLabels[i]);

			if(errorMessage == '') {// first error
				errorMessage = 'Please correct the following errors and try again:\n';
				// TODO: set field focus
			}

			if(code == ValidationCode.INVALID) {
				errorMessage += labelText + ' is invalid\n';
			}
			else if(code == ValidationCode.EMPTY) {
				errorMessage += labelText + ' is required\n';
			}
		}
		else {
			// TODO: remove error class from label
		}
	}

	if(errorMessage != '') {
		alert(errorMessage);
		return false;
	}
	return true;
}

function validateLabelField(reqLabel) {
	// TODO: Allow radio and checkbox fields to be marked as required without having to validate them
	var code = ValidationCode.VALID;

	var fieldNode = getFieldNode(reqLabel.childNodes);
	if(fieldNode == null) {
		alert('Field not found!');
		return ValidationCode.INVALID;
	}

	if(fieldNode.tagName == 'INPUT' && fieldNode.type == 'text') {

		var dataType = reqLabel.className.split(' ')[1];// class="required dataType" TODO: move to regular expression to remove dependancy on class order
		var fieldValue = fieldNode.value.trim();
		if(fieldValue == '') {
			code = ValidationCode.EMPTY;
		}
		else {
			if(dataType == 'alpha') {
				code = isAlphabetic(fieldValue);
			}
			else if(dataType == 'numeric') {
				code = isNumeric(fieldValue);
			}
			else if(dataType == 'alphaNumeric') {
				code = isAlphaNumeric(fieldValue);
			}
			else if(dataType == 'email') {
				code = isEmail(fieldValue);
			}
			else if(dataType == 'phone') {
				code = isPhone(fieldValue);
			}
			else if(dataType == 'postalCode') {
				code = isPostalCode(fieldValue);
			}
			else if(dataType == 'money') {
				code = isMoney(fieldValue);
			}
			else if(dataType == 'date') {
				code = isDate(fieldValue);
			}
			else {// Debug markup
				alert('Data type not defined: '+dataType);
			}
		}
	}
	else if(fieldNode.tagName == 'SELECT') {
		if(fieldNode.options[fieldNode.selectedIndex].value == '') {
			code = ValidationCode.EMPTY;
		}
		else {
			code = ValidationCode.VALID;
		}
	}
	return code;
}

/**
* Finds all labels classed as required
*/
function getRequiredLabels(form){
	var reqLabels = form.getElementsByTagName('label');
	var found = [];
	for(var i = 0; i < reqLabels.length; i++) {
		if(hasToken(reqLabels[i].className,'required')) {
			found[found.length] = reqLabels[i];
		}
	}
	return found;
}

/**
* Returns an <input> element node with type="text", or a <select> element node
*/
function getFieldNode(labelNodes) {
	for(var i = 0; i < labelNodes.length; i++) {
		if(labelNodes[i].nodeType == 1){// element node
			if((labelNodes[i].tagName == 'INPUT' && labelNodes[i].type == 'text') ||
				labelNodes[i].tagName == 'SELECT') {
				return labelNodes[i];
			}
		}
	}
	return null;
}

/**
* Returns the label text value
*/
function getLabelText(reqLabel){
	var labelNodes = reqLabel.childNodes;
	for(var i = 0; i < labelNodes.length; i++) {
		if(labelNodes[i].nodeType == 3) {
			return labelNodes[i].nodeValue.trim();// trim removes the linefeed
		}
	}
	return getFieldNode(labelNodes).name;// or 'Unknown'; don't expect to need this
}

/**
* Testing functions for text input fields
*/
function isAlphabetic(str) {
	var alphaExp = /^[a-zA-Z\'\-\s]*$/;// allow apostrophes, hyphens & spaces in names
	if(alphaExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isNumeric(str) {
	var numericExp = /^[0-9]*$/;
	if(numericExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isAlphaNumeric(str) {
	var alphaNumExp = /^[a-zA-Z0-9\'\-\s]*$/;// allow apostrophes, hyphens & spaces in names
	if(alphaNumExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isEmail(str) {
	var emailExp = /^[\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,4}$/;
	if(emailExp.test(str) && 
		str.charAt(0) != "." &&
		!str.match(/\.\./)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isMoney(str) {
	var moneyExp = /^\$?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/;
	if(moneyExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isPhone(str) {
/*
	var phoneExp = /^[01]?\s*[\(\.-]?(\d{3})[\)\.-]?\s*(\d{3})[\.-](\d{4})$/;
	if(phoneExp.test(str)) { 
*/
	var temp = str.replace(/\D/g, "");// replace non-numeric (braces, spaces, periods)
	if(temp.length == 7 || temp.length == 10) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isPostalCode(str) {
	var postalExp = /^[A-Za-z]\d[A-Za-z](\s?|-)\d[A-Za-z]\d$/;
	if(postalExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}

function isDate(str) {
	// dd/mm/yyyy but allow (- space / .) as separator
	var dateExp = /^([0-3]{0,1}[0-9])[\-\s\/\.]([0-1]{0,1}[0-9])[\-\s\/\.]((19|20)[0-9]{2})$/;
	if(dateExp.test(str)) {
		return ValidationCode.VALID;
	}
	return ValidationCode.INVALID;
}


