var validateDebug = true;
var validateMsg = "";

function validateAll(form) {

	// Validate all elements that have a validate attribute for this form.
	// If an error is encountered, stop here and let the focus stay on the
	// error element.
	if (validateDebug) window.status = "Checking fields for validity...";
	var elements = form.elements;

	for (var i=0; i<elements.length; i++) {
		if (elements[i].getAttribute("validate") != null)
			if (!validate(elements[i])) {
				if (validateDebug) window.status = "Not all fields are valid.";
				return false;
			}
	}
	if (validateDebug) window.status = "All fields are valid.";
	return true;
}

function validate(obj) {
	validateMsg = obj.getAttribute("validate_msg");
	if (validateMsg == null)
		validateMsg = "";
	else
		validateMsg = validateMsg.replace(/\\n/g,'\n').replace(/\\t/g,'\t');
	// The different validation types go here.
	var type = obj.getAttribute("validate");
	if (type == "text")
		return validateText(obj);
	if (type == "date")
		return validateDate(obj);
	if (type == "select")
		return validateSelect(obj);
	if (type == "selectWithValue")
		return validateSelectWithValue(obj);		
	if (type == "logic")
		return validateLogic(obj);
	if (type == "number")
		return validateNumber(obj);
	if (type == "rollingdate")
		return validateRollingDate(obj);
	if (type == "comparerollingdates")
		return validateCompareRollingDates(obj);
	if (type == "minmax")
		return validateMinMax(obj);
	if (type == "email")
		return validateEmail(obj);
	if (type == "selectAtLeastOne")
		return validateSelectAtLeastOne(obj);
	if (type == "selectAtLeastOneCheckbox")
		return validateSelectAtLeastOneCheckbox(obj);
	if (type == "selectOnlyOneCheckbox")
		return validateSelectOnlyOneCheckbox(obj);
	if (type == "validateChooseAtLeastOneMixed")
		return validateChooseAtLeastOneMixed(obj);
		
	alert("Unknown validation type " + obj.getAttribute("validate"));
	return false;

}

function validateText(text) {

	//text.value = (text.value.replace(/^\W+/,'')).replace(/\W+$/,'');
	if (text.getAttribute("validate_min")) {
		if (text.value.length < parseInt(text.getAttribute("validate_min"), 10)) {
			alert(validateMsg + "Your text cannot be shorter than " + text.getAttribute("validate_min") + " characters.\n(Your text has " + (text.getAttribute("validate_min") - text.value.length) + " too few.)");
			text.focus();
			return false;
		}
	} else {
		if (text.value == "") {
			alert(validateMsg + "You must provide a value for this field.");
			text.focus();
			return false;
		}
	}
	if (text.getAttribute("validate_max")) {
		if (text.value.length > parseInt(text.getAttribute("validate_max"), 10)) {
			alert(validateMsg + "Your text cannot be longer than " + text.getAttribute("validate_max") + " characters.\n(Your text has " + (text.value.length - text.getAttribute("validate_max")) + " too many.)");
			text.focus();
			return false;
		}
	}
	return true;
}

function validateSelect(select) {
	var selected = 0;
	var all = false;
	
	for (var i=0; i<select.length; i++) {
		if (select[i].selected) {
			selected++;
			
			if (select[i].value == "") {
				all = true;
			}
		
		}
	}
	
	if (all && (selected > 1)) {
		alert(validateMsg + "You cannot choose 'ALL' and another option.");
		select.focus();
		return false;
	}
	
	alert(selected)
	if (selected == 0) {
		alert(validateMsg + "You must select an option.");
		select.focus();
		return false;
	}
	return true;
}

function validateSelectWithValue(select) {
	var selected = 0;
	for (var i=0; i<select.length; i++) {
		if (select[i].selected) {
			
			if (select[i].value == "") {
				alert(validateMsg + "You must select an option.");
				select.focus();
				return false;
			}
		}
	}
	return true;
}

function validateLogic(logic) {
	if ((logic[logic.selectedIndex].value == "EQUALS")
		|| (logic[logic.selectedIndex].value == "ALL EXCL")) {
		var codes = logic.form[logic.getAttribute("validate_element")];
		var selected = false;
		for (var i=0; i<codes.length; i++) {
			if (codes[i].selected)
				selected = true;
		}
		if (!selected) {
			alert(validateMsg + "You must select at least one option.");
			codes.focus();
			return false;
		}
	} else {
		var codes = logic.form[logic.getAttribute("validate_element")];
		var selected = false;
		for (var i=0; i<codes.length; i++) {
			if (codes[i].selected)
				selected = true;
		}
		if (selected) {
			alert(validateMsg + "You must not select any options when you choose ALL.");
			codes.focus();
			return false;
		}
	}
	return true;
}

function validateCompareRollingDates(hidden) {
	var start;
	var end;
	var focus;
	var start_rolling = hidden.form[hidden.getAttribute("validate_start_rollingdate")];
	var start_specific = hidden.form[hidden.getAttribute("validate_start_specificdate")];
	var end_rolling = hidden.form[hidden.getAttribute("validate_end_rollingdate")];
	var end_specific = hidden.form[hidden.getAttribute("validate_end_specificdate")];
	var today = new Date();
	today = new Date(today.getFullYear(), today.getMonth(), today.getDate());

	if (start_rolling.value != "") {
		start = new Date(today.getTime() + (parseInt(start_rolling.value, 10)+1)*24*60*60*1000);
		focus = start_rolling;
	} else {
		start = convertStringToDate(start_specific.value);
		focus = start_specific;
	}

	if (end_rolling.value != "") {
		end = new Date(start.getTime() + today.getTime() + (parseInt(end_rolling.value, 10)+1)*24*60*60*1000);
	} else {
		end = convertStringToDate(end_specific.value);
	}

	if (start > end) {
		alert(validateMsg + "Your start date must not be later than your end date.");
		focus.focus();
		return false;
	}
	return true;
}

function convertStringToDate(string) {
	// Converts FC's 7/AUG/2004 to a Date object.
	var aDate = string.split("/");
	var day, month, year;
	day = parseInt(aDate[0], 10);
	year = parseInt(aDate[2], 10);
	switch (aDate[1].toUpperCase()) {
		case "JAN": month = 0; break;
		case "FEB": month = 1; break;
		case "MAR": month = 2; break;
		case "APR": month = 3; break;
		case "MAY": month = 4; break;
		case "JUN": month = 5; break;
		case "JUL": month = 6; break;
		case "AUG": month = 7; break;
		case "SEP": month = 8; break;
		case "OCT": month = 9; break;
		case "NOV": month = 10; break;
		case "DEC": month = 11; break;
		default: 0;
	}
	return new Date(year, month, day, 23, 59, 59, 999);
}

function validateRollingDate(radioObj) {
	var result = true;
	radio = radioObj.form[radioObj.name];
	for (var i=0; i<radio.length; i++) {
		var name = radio[i].getAttribute("validate_element");
		if (radio[i].checked) {
			if (radio[i].getAttribute("validate_type") == "date")
				result = validateDate(radio[i].form[name]);
			if (radio[i].getAttribute("validate_type") == "number")
				result = validateNumber(radio[i].form[name]);
		} else {
			radio[i].form[name].value = "";
		}
	}
	return result;
}

function validateNumber(text) {
	text.value = (text.value.replace(/^\W+/,'')).replace(/\W+$/,'');

	if (text.value.search(/\D+/) >= 0) {
		alert(validateMsg + "You must provide a valid number for this field.");
		text.focus();
		return false;
	}

	var val = parseInt(text.value, 10);

	if (isNaN(val)) {
		alert(validateMsg + "You must provide a valid number for this field.");
		text.focus();
		return false;
	}

	if (text.getAttribute("validate_min")) {

		if (val < parseInt(text.getAttribute("validate_min"), 10)) {
			alert(validateMsg + "Your number cannot be less than " + text.getAttribute("validate_min") + ".");
			text.focus();
			return false;
		}
	}
	if (text.getAttribute("validate_max")) {
		if (val > parseInt(text.getAttribute("validate_max"), 10)) {
			alert(validateMsg + "Your number cannot be greater than " + text.getAttribute("validate_max") + ".");
			text.focus();
			return false;
		}
	}
	return true;
}

function validateDate(textbox) {
	// This is as long as it is so it can return a helpful message of why its not valid.
	var aDate = textbox.value.split("/");
	var day, month, year;
	var month_invalid = false;
	var max_days;
	var sError = "";
	var month_num;
	var this_date;

	if (aDate.length == 3) {
		day = parseInt(aDate[0], 10);
		month = aDate[1].toUpperCase();
		year = parseInt(aDate[2], 10);
		if (!isNaN(day) && !isNaN(year)) {
			if ((year > 2100) || (year < 1900))
				sError += "\nYour year (" + year + ") is invalid. (It should be 1900-2100.)";
			switch (month) {
				case "JAN": month_num = 1; max_days = 31; break;
				case "FEB":
					month_num = 2;
					if (new Date(year,2-1,29).getDate()==29)
						max_days = 29;
					else
						max_days = 28;
					break;
				case "MAR": month_num = 3; max_days = 31; break;
				case "APR": month_num = 4; max_days = 30; break;
				case "MAY": month_num = 5; max_days = 31; break;
				case "JUN": month_num = 6; max_days = 30; break;
				case "JUL": month_num = 7; max_days = 31; break;
				case "AUG": month_num = 8; max_days = 31; break;
				case "SEP": month_num = 9; max_days = 30; break;
				case "OCT": month_num = 10; max_days = 31; break;
				case "NOV": month_num = 11; max_days = 30; break;
				case "DEC": month_num = 12; max_days = 31; break;
				default:
					month_invalid = true;
					max_days = 31;
			}
			if ((day > max_days) || (day < 1))
				sError += "\nYour day (" + day + ") of the month is invalid. (It should be 1-31 depending on the month.)";
			if (month_invalid)
				sError += "\nYour month (" + month + ") is invalid. (It should be the first 3 letters like 'AUG'.)";
		} else {
			sError += "\nWhere each value is a valid number.";
		}
	} else {
		sError += "\n'" + textbox.value + "' is not a valid date.";
	}

	if (sError != "") {
		alert(validateMsg + "Date fields must be of the format\n\n\tdd/mmm/yyyy\n" + sError);
		textbox.focus();
		return false;
	}

	var this_date = new Date(year, month_num - 1, day);

	if (textbox.getAttribute("validate_min")) {
		var min_type = (textbox.getAttribute("validate_min").toLowerCase().replace(/^\W+/,'')).replace(/\W+$/,'')
		var min;
		var today = new Date();
		if (min_type == "tomorrow")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
		else if (min_type == "today")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate());
		else if (min_type == "yesterday")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
		else
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate());

		if (this_date < min) {
			alert(validateMsg + "This date cannot be before " + min_type + ".");
			textbox.focus();
			return false;
		}
	}

	return true;
}

function validateMinMax(hidden) {
	var min = hidden.form[hidden.getAttribute("validate_min")];
	var max = hidden.form[hidden.getAttribute("validate_max")];
	var min_name = hidden.getAttribute("validate_min_name");
	var max_name = hidden.getAttribute("validate_max_name");

	if (min_name == null) min_name = "minimum";
	if (max_name == null) max_name = "maximum";

	if (parseInt(min.value, 10) > parseInt(max.value, 10)) {
		alert(validateMsg + "The " + min_name + " cannot be greater than the " + max_name + ".");
		min.focus();
		return false;
	}

	return true;
}

function validateEmail(email) {

	var str = email.value;

	// are regular expressions supported?
  	var supported = 0;

	if (window.RegExp) {
		var tempStr = "a";
	    var tempReg = new RegExp(tempStr);
	    if (tempReg.test(tempStr)) supported = 1;
	}

	if (!supported) {
		if ((str.indexOf(".") > 3) && (str.indexOf("@") > 0)) return true;

		alert(validateMsg + "Please enter a valid email address");
    	email.focus();
    	return false;
    }

    if (supported) {
		var r1 = new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)");
		var r2 = new RegExp("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$");

		if (!r1.test(str) && r2.test(str)) return true;

		alert(validateMsg + "Please enter a valid email address");
		email.focus();
		return false;
  }
}

function validateSelectAtLeastOne(logic) {

	var codes = logic.form[logic.getAttribute("validate_element")];
	var selected = false;


	for (var i=0; i<codes.length; i++) {
		if (codes[i].selected) {
			selected = true;
		}
	}

	if (!selected) {
		alert(validateMsg + "You must select at least one option.");
		codes.focus();
		return false;
	}

	return true;
}

function validateSelectAtLeastOneCheckbox(input) {

	var groupName = input.getAttribute("groupName");
// alert(groupName);
	var alternateInput = input.getAttribute("alternateInput");
	var form = input.form;
	var elements = form.elements;
	var focusElement;

	var alternateElement = form[alternateInput];
	if (alternateElement) {
		if (alternateElement.value != '') {
			return true;
		}
	}

	for (var i=0; i<elements.length; i++) {
		if (elements[i].getAttribute("validate_element") == groupName) {
			if (elements[i].checked){
				return true;
			}
		}
	}
	if(validateMsg==null) {
		alert("You must select at least one " + groupName + " option.");
	} else {
		alert(validateMsg + "You must select at least one option.");
	}
	return false;
}

function validateSelectOnlyOneCheckbox(input) {

	var groupName = input.getAttribute("groupName");
	var form = input.form;
	var elements = form.elements;
	var counter = 0;

	for (var i=0; i<elements.length; i++) {

		if (elements[i].getAttribute("validate_element") == groupName) {
			if (elements[i].checked){
				counter++;
			}
		}
	}

	if (counter==1) {
		return true;
	}

	if(validateMsg==null) {
		alert("You must select one " + groupName + " option.");
	} else {
		alert(validateMsg + "You must select one option.");
	}
	return false;
}


function validateChooseAtLeastOneMixed (input) {
	var groupName = input.getAttribute("groupName");
	var form = input.form;

	var alternateElement1 = form[input.getAttribute("alternateInput1")];
	if (alternateElement1 && alternateElement1.value != '') return true;

	var alternateElement2 = form[input.getAttribute("alternateInput2")];
	if (alternateElement2 && alternateElement2.value != '') return true;

	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
		if (elements[i].getAttribute("validate_element") == groupName && elements[i].checked) return true;
	}

	alert (validateMsg == null ? "You must select at least one " + groupName + " option." :
		validateMsg + "You must select at least one option.");

	return false;
}


