var first = null;
	
function validateForm(theForm)
{
	first = null;
	var labels = theForm.getElementsByTagName("label");
	var error = false;

	for (var i = 0; i < labels.length; i++)
	{
		if (labels[i].className.classExists("required"))
		{
			var select = false;
			if (labels[i].getElementsByTagName("select")[0])
				select = true;
			
			var input = labels[i].getElementsByTagName("input")[0] || labels[i].getElementsByTagName("textarea")[0] || labels[i].getElementsByTagName("select")[0];
			var spans = labels[i].getElementsByTagName("span");
			var errorText = null;
			var labelText = null;
			
			for (var j = 0; j < spans.length; j++)
			{
				if (spans[j].className.classExists("labelText"))
				{
					labelText = spans[j];
				}
			}

			if (input != null)
			{
				if (input.value == "")
				{
					if (select)
						errorText = "Please select your " + labelText.childNodes[0].nodeValue.toLowerCase().replace(/:/, "");
					else
						errorText = "Please fill in your " + labelText.childNodes[0].nodeValue.toLowerCase().replace(/:/, "");
				}
				else if (input.getAttribute("type") == "radio" && !validRadio(labels[i].getElementsByTagName("input")))
				{
					errorText = "Please select an option";
				}
				else if (labels[i].className.classExists("requiredEmail") && !input.value.validEmail())
				{
					errorText = "Please supply a valid e-mail address";
				}
				else if (labels[i].className.classExists("requiredZipCode") && !input.value.validZipCode())
				{
					errorText = "Please supply a valid zip code";
				}
				else if (labels[i].className.classExists("requiredPhone") && !input.value.validPhone())
				{
					errorText = "Please supply a valid phone";
				}
				else if (labels[i].className.classExists("match-") && input.value.validMatch(labels[i].className, labelText) != "")
				{
					errorText = input.value.validMatch(labels[i].className, labelText);
				}

				if (errorText != null)
				{
					if (first == null)
					{
						first = input;
					}

					error = true;
					writeCorrection(labels[i], errorText);

					if (input.nodeName.toLowerCase() == "input" && input.getAttribute("type") == "text")
					{
						input.onkeyup = checkValidity;
					}
					else if (input.nodeName.toLowerCase() == "select")
					{
						input.onchange = checkValidity;
					}
					else if (input.nodeName.toLowerCase() == "input" && input.getAttribute("type") == "radio")
					{
						var radios = labels[i].getElementsByTagName("input");
						for (var j=0; j<radios.length; j++) 
						{
							radios[j].onchange = checkValidity;
						}
					}
				}
				else
				{
					labels[i].className = labels[i].className.addClass("completed");
					writeCorrection(labels[i]);
				}
			}
		}
		else
		{
			labels[i].className = labels[i].className.addClass("completed");
		}
	}

	if (error)
	{
		var errorSummary = document.getElementById("divErr1");
		if (!errorSummary)
			errorSummary = document.getElementById("divErr2");
		errorSummary.className = errorSummary.className.addClass("warning");
		writeSpan(errorSummary, "Please correct the fields shown below:");

		var fieldsets = theForm.getElementsByTagName("fieldset");

		for (var i = 0; i < fieldsets.length; i++)
		{
			if (!fieldsets[i].className.classExists("submit"))
			{
				var labels = fieldsets[i].getElementsByTagName("label");
				var completed = true;

				for (var j = 0; j < labels.length; j++)
				{
					if (!labels[j].className.classExists("completed"))
					{
						completed = false;
					}
				}

				if (completed)
				{
					fieldsets[i].className = fieldsets[i].className.addClass("completed");
				}
			}
			/*else
			{
				var editLink = document.getElementById("editLink");

				if (editLink == null)
				{
					editLink = document.createElement("a");
					editLink.id = "editLink";
					editLink.setAttribute("href", "#");
					editLink.onclick = editForm;
					writeSpan(editLink, "Edit the full form");
					fieldsets[i].appendChild(editLink);
				}
			}*/
		}

		if (first.focus) first.focus();

		return false;
	}

	return true;
}


function validRadio(radios)
{
	var ret = false;
	
	for (var i=0; i<radios.length; i++)
	{
		if (radios[i].checked)
		{
			ret = true;
			break;
		}
	}
	
	return ret;
}


function writeCorrection(label, text, correct)
{
	var spans = label.getElementsByTagName("span");
	var input = label.getElementsByTagName("input")[0] || label.getElementsByTagName("textarea")[0] || label.getElementsByTagName("select")[0];
	var image = label.getElementsByTagName("img")[0];

	if (typeof text == "undefined")
	{
		if (image != null)
		{
			label.removeChild(image);
		}

		for (var j = 0; j < spans.length; j++)
		{
			if (spans[j].className.classExists("correctionText"))
			{
				label.removeChild(spans[j]);

				break;
			}
		}
	}
	else
	{
		if (image == null)
		{
			image = document.createElement("img");
			image.className = "correctionIcon";
			if (input.getAttribute("type") == "radio")
			{
				image = label.insertBefore(image, input.parentNode);
			}
			else
				image = label.insertBefore(image, input);

			var newText = document.createElement("span");
			newText.className = "correctionText";
			label.appendChild(newText);
		}

		var spans = label.getElementsByTagName("span");

		for (var j = 0; j < spans.length; j++)
		{
			if (spans[j].className.classExists("correctionText"))
			{
				var correctionText = spans[j];

				break;
			}
		}

		if (correct == true)
		{
			image.setAttribute("src", "img/icon_tick.gif");
			image.setAttribute("alt", "Correct");
			correctionText.className = correctionText.className.removeClass("warning");
		}
		else
		{
			image.setAttribute("src", "img/icon_cross.gif");
			image.setAttribute("alt", "Incorrect");
			correctionText.className = correctionText.className.addClass("warning");
		}

		writeSpan(correctionText, text);
	}

	return true;
}


function writeSpan(span, text)
{
	var children = span.childNodes;

	for (var i = 0; children.length > 0;)
	{
		span.removeChild(children[i]);
	}

	var textNode = document.createTextNode(text);
	span.appendChild(textNode);

	return true;
}


function checkValidity()
{
	var label;
	if (this.getAttribute("type") == "radio")
		label = this.parentNode.parentNode;
	else
		label = this.parentNode;
	var spans = label.getElementsByTagName("span");
	var labelText = null;

	for (var j = 0; j < spans.length; j++)
	{
		if (spans[j].className.classExists("labelText"))
		{
			labelText = spans[j];
		}
	}

	if (this.value == "")
	{
		writeCorrection(label, "Please fill in your " + labelText.childNodes[0].nodeValue.toLowerCase().replace(/:/, ""));
	}
	else if (label.className.classExists("requiredEmail") && !this.value.validEmail())
	{
		writeCorrection(label, "Please supply a valid e-mail address");
	}
	else if (label.className.classExists("requiredZipCode") && !this.value.validZipCode())
	{
		writeCorrection(label, "Please supply a valid zip code");
	}
	else if (label.className.classExists("requiredPhone") && !this.value.validPhone())
	{
		writeCorrection(label, "Please supply a valid phone");
	}
	else if (label.className.classExists("match-") && this.value.validMatch(label.className, labelText) != "")
	{
		writeCorrection(label, this.value.validMatch(label.className, labelText));
	}
	else if (label.className.classExists("requiredRadio") && !validRadio(label.getElementsByTagName("input")))
	{
		writeCorrection(label, "Please select an option");
	}
	else
	{
		writeCorrection(label, "This field is correct", true);
	}

	return true;
}


function editForm()
{
	var form = this.parentNode;
	var editLink = document.getElementById("editLink");

	while (form.nodeName.toLowerCase() != "form")
	{
		form = form.parentNode;
	}

	var fieldsets = form.getElementsByTagName("fieldset");

	for (var i = 0; i < fieldsets.length; i++)
	{
		fieldsets[i].className = fieldsets[i].className.removeClass("completed");
	}

	var labels = form.getElementsByTagName("label");

	for (var i = 0; i < labels.length; i++)
	{
		labels[i].className = labels[i].className.removeClass("completed");
	}

	editLink.parentNode.removeChild(editLink);

	if (first.focus) first.focus();

	return false;
}


function focusField(target, okToFocusOnPop)
{
	// The form elements that will be tested. Anything with a dot indicates the "type" attribute of the element
	var formElements = ["input.text", "input.checkbox", "input.radio", "select", "textarea"];
	var selectedNode = null;

	// IE's selection method
	if (typeof document.selection != "undefined" && document.selection != null && typeof window.opera == "undefined")
	{
		var theSelection = document.selection;
		var textRange = document.selection.createRange();

		selectedNode = textRange.parentElement();
	}
	// W3 selection method. Currently only Mozilla & Safari support it. However, neither of them support ranges inside form objects, so this part is redundant. Merely included in case they decide to include support in the future
	else if (typeof window.getSelection != "undefined")
	{
		var theSelection = window.getSelection();

		// The Safari way to get the node that a selection starts in
		if (typeof theSelection.baseNode != "undefined")
		{
			selectedNode = theSelection.baseNode;
		}
		// The Mozilla way to get the node that a selection starts in
		else if (typeof theSelection.getRangeAt != "undefined" && theSelection.rangeCount > 0)
		{
			selectedNode = theSelection.getRangeAt(0).startContainer;
		}
	}

	// If a selected node was found above, check whether it's a selection inside one of the specified form element types
	if (selectedNode != null)
	{
		for (var i = 0; i < formElements.length; i++)
		{
			if (selectedNode.nodeName.toLowerCase() == formElements[i].replace(/([^.]*)\..*/, "$1"))
			{
				return false;
			}
		}
	}

	var forms = document.forms;

	// Do a check of each form element on the page. If one of them has a value, do not focus
	for (var i = 0; i < forms.length; i++)
	{
		var formElements = forms[i];

		for (var j = 0; j < formElements.length; j++)
		{
			if (formElements[j].getAttribute("type") == "checkbox" || formElements[j].getAttribute("type") == "radio")
			{
				if (formElements[j].checked != formElements[j].defaultChecked)
				{
					return false;
				}
			}
			else
			{
				if (typeof formElements[j].defaultValue != "undefined" && formElements[j].value != formElements[j].defaultValue)
				{
					return false;
				}
			}
		}
	}

	// If no form elements were found to be focused -- or with values -- go ahead and focus
	if (target && target.focus && (window.opener == null || okToFocusOnPop)) target.focus();

	return false;
}