function validate($form, $fields) {
	$form = document.forms[$form];
	var $errors = [];
	var $focus;
	for(var $i = 0; $i < $fields.length; $i ++) {
		var $field = $fields[$i];
		switch($field.type) {
			case "checkboxes":
			$field.element = $form[$field.field + "[]"];
			break;
			case "fck":
			$field.element = $field.field;
			break;
			default:
			$field.element = $form[$field.field];
			break;
		}
		if($field.element && elementVisible($field)) {
			var $valid = true;
			switch($field.type) {
				case "text":
				if($field.required && !validateText($field.element)) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "number":
				if(validateText($field.element)) {
					if(!validateNumber($field.element)) {
						$errors.push($field.title + " must contain only numbers");
						$valid = false;
					}
				} else if($field.required) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "integer":
				if(validateText($field.element)) {
					if(!validateInteger($field.element)) {
						$errors.push($field.title + " must be a whole number");
						$valid = false;
					}
				} else if($field.required) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "float":
				if(validateText($field.element)) {
					if(!validateFloat($field.element)) {
						$errors.push($field.title + " must be a numeric value");
						$valid = false;
					}
				} else if($field.required) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "email":
				if(validateText($field.element)) {
					if(!validateEmail($field.element)) {
						$errors.push($field.title + " is invalid");
						$valid = false;
					}
				} else if($field.required) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "reentry":
				if(!validateReentry($field.element, $form[$field.source])) {
					$errors.push($field.title + " do not match");
					$valid = false;
				}
				break;
				case "checkbox":
				if(!validateCheckbox($field.element)) {
					$errors.push($field.error);
					$valid = false;
				}
				break;
				case "checkboxes":
				if(!validateCheckboxes($field.element)) {
					$errors.push($field.error);
					$valid = false;
				}
				break;
				case "radios":
				if(!validateCheckboxes($field.element)) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "file":
				if(validateText($field.element)) {
					if(!validateFile($field.element, $field.extensions)) {
						$errors.push($field.title + " is an invalid file format");
						$valid = false;
					}
				} else if(parseInt($field.element.getAttribute("req"))) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
				case "fck":
				if($field.required && !validateFCK(CKEDITOR.instances[$field.element])) {
					$errors.push($field.title + " is required");
					$valid = false;
				}
				break;
			}
			if(!$valid && !$focus) $focus = $field;
		}
	}
	var $error = "";
	if($errors.length > 0) {
		if($errors.length > 1) {
			$error += "Please correct the following errors:\n";
		} else {
			$error += "Please correct the following error:\n";
		}
		for(var $i = 0; $i < $errors.length; $i ++) {
			$error += "- " + $errors[$i] + "\n";
		}
		alert($error);
		focusTab($focus);
		switch($focus.type) {
			case "fck":
			CKEDITOR.instances[$focus.element].focus();
			break;
			default:
			$focus.element.focus();
			break;
		}
		return false;
	} else {
		return true;
	}
}

function validateText($field) {
	return($field.value != "");
}

function validateNumber($field) {
	return(/^[0-9 ]+$/.test($field.value));
}

function validateInteger($field) {
	return(/^[0-9]+$/.test($field.value));	
}

function validateFloat($field) {
	return(/^[0-9]*(\.[0-9]+)?$/.test($field.value));
}

function validateEmail($field) {
	return(/^[\w']+([\.-][\w']+)*@\w+([\.-]\w+)*(\.\w{2,4})$/.test($field.value));
}

function validateReentry($field, $source) {
	return($field.value == $source.value);
}

function validateCheckbox($field) {
	return($field.checked);
}

function validateCheckboxes($field) {
	$valid = false;
	if(!$field.length) $field = [$field];
	for(var $i = 0; $i < $field.length; $i ++) {
		if($field[$i].checked) {
			$valid = true;
			break;
		}
	}
	return $valid;
}

function validateFile($field, $valid) {
	if(!$valid) $valid = ["gif", "jpg", "png"];
	var $extension = $field.value.split(".").pop().toLowerCase();
	for(var $i = 0; $i < $valid.length; $i ++) if($extension == $valid[$i]) return true;
	return false;
}

function validateFCK($field) {
	return $field.getData() != "";
}

function checkAll($checkbox, $form) {
	$form = document.forms[$form];
	for(var $i = 0; $i < $form.length; $i ++) {
		var $field = $form[$i];
		if($field.type == "checkbox") {
			$field.checked = $checkbox.checked;
		}
	}
}

function elementVisible($field) {
	var $element = getElement($field);
	do {
		if($element.style.display == "none") return false;
		$element = $element.parentNode;
	} while($element.tagName.toLowerCase() != "body");
	return true;
}

function focusTab($field) {
	var $element = getElement($field);
	while($element.tagName.toLowerCase() != "body") {
		if($element.className == "TabContent") {
			selectTab($element.id.substring(7));
			break;
		} else {
			$element = $element.parentNode;
		}
	}
}

function getElement($field) {
	switch($field.type) {
		case "checkboxes":
		var $element = $field.element[0];
		break;
		case "radios":
		if($field.element.length) {
			var $element = $field.element[0];
		} else {
			var $element = $field.element;
		}
		break;
		case "fck":
		var $element = document.getElementById("cke_" + $field.element);
		break;
		default:
		var $element = $field.element;
		break;
	}
	return $element;
}
