function checkAll() {
	var el = document.forms[0].elements;
	newValue = noneChecked(el);
	for (var i=0; i < el.length; i++) {
		if (el[i].type == "checkbox")
			el[i].checked = newValue;
	}
	return;
}

function noneChecked(el) {
	for (var i=0; i < el.length; i++) {
		if (el[i].type == "checkbox") {
			if (el[i].checked) return false;
		}
	}
	return true;
}

// given a form input and an array of checks, perform data validation checks
function validate(input, label, checks) {
	for (i=0; i<checks.length; i++) {
		// replace first occurrence of | with (, and any other occurrences of | with ,
		// if there were no occurrences of | to begin with, add ( to the end of the check
		newCheck = checks[i].replace(/\|/, '(');
		newCheck = newCheck.replace(/\|/g, ', ');
		if (newCheck == checks[i]) {
				newCheck = newCheck + '(';
		} else {
				newCheck = newCheck + ', ';
		}
		valid = eval (newCheck + " input, label);");
		if (valid != true) {
			var theType = getType(input);
			if (theType != 'radio') {
				if (theType != 'select-one') {
						input.select();
				}
				input.focus();
			}
			alert(valid);
			return false;
		}
	}
	return true;
}

function checked(minimum, form, inputBase, label) {
	// valid if at least [minimum] checkboxes are checked
	// names of checkboxes are [inputBase]0, [inputBase]1, etc.
	var inputName;
	var input;
	var total = 0;
	for (var i=0; i < 1000; i++) { // 1000 prevents accidental infinite loop
		inputName = inputBase + i;
		input = eval('form.'+inputName);
		if (!input) break;

		if (input.checked) total++;
		if (total >= minimum) {
			return true;
		}
	}
	alert('Please select at least ' + minimum + ' "' + label + '" before continuing.');
	return false;
}

function validateGroup(f, baseName, label) {
	var el = f.elements;
	var oneChecked = false;
	for (c=0; c<100; c++) { 	// limit to 100 to avoid infinite loop
		chkName = baseName + c;
		if (el[chkName]) {
			if (el[chkName].checked) {
				oneChecked = true;
				break;
			}
		} else 
			break;
	}
	if (!oneChecked)
		alert('Please select at least one ' + label + ' before continuing.');
	return oneChecked;
}

// given a form input object, return its type
function getType(input) {
    if (!input.type) { return input[0].type; }
    else { return input.type; }
}
         
// given a form input, return its value
function getValue(input) {
	var inputType = getType(input);
	if (inputType == 'select-one') {
		return trim(input[input.selectedIndex].value);
	} else if (inputType == 'radio') {
		for (var i=0; i<input.length; i++) {
			if (input[i].checked)
				return trim(input[i].value);
		}
	} else if (inputType == 'checkbox') {
		if (input.checked)
			return trim(input.value);
		else
			return 0;
	} else {
		return trim(input.value);
	}
	return 0;       // this will be returned if, for example, 'input' is a radio, and nothing is selected
}

// given a form input, set its value
function setValue(inpt, val) {
	if (inpt.type == 'select-one') {
		for (var i=0; i<inpt.options.length; i++) {
			if (inpt.options[i].value == val) {
				inpt.selectedIndex = i;
				break;
			}
		}
	} else {
		inpt.value = val;
	}
}
        
// input value is required; it cannot be blank
function required(input, label) {
	var theType = getType(input);
	switch (theType) {
		case 'radio':
			valid = false;
			for (i=0; i<input.length; i++) {
				valid = valid || input[i].checked;
			}
			break;
		default:
			valid = (getValue(input) != '');
	} 
	if (!valid) {
		if (theType == 'select-one')
			return ('Please select a "' + label + '" before continuing.');
		else if (theType == 'radio')
			return ('Please choose a "' + label + '" before continuing.');
		else
			return ('Please fill the field "' + label + '" before continuing.');
	} else {        
		return true;
	}
}
        
// input value is required; it cannot be blank
function requiredWith(input, label, input2, label2, mustMatch) {
	var value1 = getValue(input);
	var value2 = getValue(input2);
	var inputSel;
	if (mustMatch)
		valid = (value1 == value2);
	else
		valid = ((value1 == '' && value2 == '') || (value1 != '' && value2 != ''));
	if (!valid) {
		if (mustMatch) {
			alert ('The field "' + label2 + '" must match the field "' + label + '" before continuing.');
			inputSel = input2;
		} else if (value1 == '') {
			alert ('Please fill in the field "' + label + '" before continuing.');
			inputSel = input;
		} else {
			alert ('Please fill in the field "' + label2 + '" before continuing.');
			inputSel = input2;
		}
		inputSel.select();
		inputSel.focus();
		return false;
	} else {        
		return true;
	}
}

// input value is required; it cannot be blank
function eitherOr(input, label, input2, label2) {
	var value1 = getValue(input);
	var value2 = getValue(input2);
	if (value1 == 0) value1 = '';
	if (value2 == 0) value2 = '';
	valid = (value1 != '' || value2 != '');
	if (!valid) {
		alert ('Please fill in either "' + label + '" or "' + label2 + '" before continuing.');
		input.select();
		input.focus();
		return false;
	} else {        
		return true;
	}
}

// input value is required; it cannot be blank
function numeric(input, label) { 
	valid = (!isNaN(getValue(input)));
	if (!valid) {
		return ("The field '" + label + "' must be a number.");
	}
	else {
		return true;
	}
}
       
// input value is required; it cannot be blank
function positive(input, label) { 
	valid = (getValue(input) > 0);
	if (!valid) {
		return ("The field '" + label + "' must be greater than zero.");
	}
	else {
		return true;
	}
}
        
// return whether or not the input value consists of alphabet characters
function alpha(input, label) {
	re = /^([\- a-zA-Z]| )*$/g;
	if (input.value.search(re) == -1)
		return ('The ' + label + ' can contain only alphabetic characters.');
	return true;
}

// trims whitespace from input
function trim(str) {
	return (str.replace(/^\W+/,'')).replace(/\W+$/,'');
}
 
// remove all whitespace from input
function strip(input) {
	var str = getValue(input);
	var str2 = (str.replace(/^\W+/,'')).replace(/\W+$/,'');
	input.value = str2;
}

// return whether or not the input value is a valid email address
function email(input, label) {
	var emailStr = trim(input.value);
	if (emailStr == '') { return true; }

	var emailPat = /^(.+)@(.+)$/;
	var specialChars = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
	var validChars = "\[^\\s" + specialChars + "\]";
	var quotedUser = "(\"[^\"]*\")";
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom = validChars + '+';
	var word = "(" + atom + "|" + quotedUser + ")";
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat = new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray = emailStr.match(emailPat);
	
	if (matchArray == null) {
		return ('The ' + label + ' seems incorrect.');
	}

	var user = matchArray[1];
	var domain = matchArray[2];
	if (user.match(userPat) == null) {
		return ('The ' + label + ' seems incorrect - check the username.');
	}

	var IPArray=domain.match(ipDomainPat);
	if (IPArray != null) {
		for (var i = 1; i = 4; i++) {
			if (IPArray[i] > 255) {
				return ('The ' + label + ' seems incorrect - check the IP address.');
			}
		}
		return true;
	} else {
	
		var domainArray = domain.match(domainPat);
		if (domainArray == null) {
			return ('The ' + label + ' seems incorrect - check the domain name.');
		}
	 
		var atomPat = new RegExp(atom,"g");
		var domArr = domain.match(atomPat);
		var len = domArr.length;
		if (domArr[len-1].length < 2 || domArr[len-1].length > 3) {
			return ('The ' + label + ' seems incorrect - check the domain.');
		}
	
		if (len < 2) {
			return ('The ' + label + ' seems incorrect - check the hostname.)');
		}
	}
	return true;
}

function exactly(len, input, label) {
	var val = getValue(input);
	var valid = (val.length == len || val.length == 0);
	if (!valid) {
		return ('The ' + label + ' must be exactly ' + len + ' characters long.');
	}
	return true;
}

function cc(input, label) {
	var val = getValue(input);
	var valid = (val.length == 16 || val.length == 15);
	if (!valid) {
		return ('The ' + label + ' must be 16 characters long.');
	}
	return true;
}

function atleast(len, input, label) {
	var val = getValue(input);
	var valid = (val.length >= len || val.length == 0);
	if (!valid) {
		return ('The ' + label + ' must be at least ' + len + ' characters long.');
	}
	return true;
}

function validPhone (len, input, label) {
	var val = getValue(input);
	if (val == '') return true;
	if (len == 'short')
	    var phonePat = /^(\d{3})-(\d{4})$/;
	else
	    var phonePat = /^(\d{3})-(\d{3})-(\d{4})$/;
    var matchArray = val.match(phonePat);

	if (matchArray == null)
		return ('The ' + label + ' seems incorrect.');

	return true;
}

function validPC (input, label) {
	var val = getValue(input);
	if (val == '') return true;
    var pcPat = /^\D\d\D \d\D\d$/;
    var matchArray = val.match(pcPat);

	if (matchArray == null)
		return ('The ' + label + ' seems incorrect.');

	return true;
}

function creditCard (input, label) {
	re = /^\d{4}( )?\d{4}( )?\d{4}( )?\d{4}( )?$/g;
	if (input.value.search(re) == -1)
		return ('The ' + label + ' appears to be invalid.');
		
	return true;
}

function matches(toMatch, input, label) {
	valid = (getValue(input) == toMatch);
	if (!valid) {
		return ('The ' + label + ' must match "' + toMatch + '".');
	} else {
		return true;
	}
}