/**
 * Finds the named field in the given form.
 *
 * @return The field if found, otherwise null
 */
function get_field (form, field_name)
{
	if (!form || !field_name) return null;

	var inputs = form.getElementsByTagName ('input');
	for (var i = 0; i < inputs.length; i++)
	{
		if (inputs [i].getAttribute ('name') == field_name)
		{
			return inputs [i];
		}
	}

	var textareas = form.getElementsByTagName ('textarea');
	for (var i = 0; i < textareas.length; i++)
	{
		if (textareas [i].getAttribute ('name') == field_name)
		{
			return textareas [i];
		}
	}

	// the named field wasn't found, so return null
	return null;
}

/**
 * Loops through all the forms on the page and if it finds a field named
 * "required" then it installs a checker on that forms submit button.
 */
function setup_forms ()
{
	// search through all the forms for a field named 'required'
	var forms = document.getElementsByTagName ('form');
	for (var i = 0; i < forms.length; i++)
	{
		if (get_field (forms [i], 'required') !== null)
		{
			install_checker (forms [i]);
		}
	}
}

/**
 * Installs a checker on the form passed
 *
 * @param form The form to have a checker installed on
 */
function install_checker (form)
{
	if (!form) return;

	form.setAttribute ('onsubmit', 'return check_form (this)');
}

/**
 * Checks that all required fields have been completed in the form
 *
 * @param form The form to check and submit
 *
 * @return True if all completed, false if not
 */
function check_form (form)
{
	if (!form) return false;

	var required = get_field (form, 'required').getAttribute ('value').split (',');

	var failed = new Array (0);

	var field;
	var field_name;

	for (var i = 0; i < required.length; i++)
	{
		field = get_field (form, required [i]);

		if (field !== null && !field.value)
		{
			failed.push (field);
		}
	}

	// submit form or give an error message
	if (failed.length < 1) return true;

	var error_msg = "Please fill out the following field(s) before submitting this form:\n\n";
	var missing_fields = new Array (0);

	for (var i = 0; i < failed.length; i++)
	{
		missing_fields.push (get_label (failed [i]));
	}

	error_msg += missing_fields.join ("\n");

	alert (error_msg);

	return false;
}

/**
 * Finds the label associated with the given field
 *
 * @param field The field to find the label for
 *
 * @return A string containing the label of the field, or the name if not found
 */
function get_label (field)
{
	var labels = document.getElementsByTagName ('label');

	for (var i = 0; i < labels.length; i++)
	{
		if (labels [i].getAttribute ('for') == field.getAttribute ('id'))
		{
			return to_string (labels [i]);
		}
	}

	// no label was found, so return the name of the field
	return field.getAttribute ('name');
}

/**
 * Returns a string containing all the text in the given node.
 */
function to_string (node)
{
	var string = "";

	if (node.nodeType == 3)
	{
		string = node.nodeValue;
	}
	else
	{
		for (var i = 0; i < node.childNodes.length; i++)
		{
			string += to_string (node.childNodes [i]);
		}
	}

	return string;
}

window.onload = setup_forms;