// CSS Function Definitions ---------------------------------------------------------------------------------------------------
	
	// This function appends a subclass name to a CSS style class name.
	function appendCSSStyleName (name, subclass)
		{	return containsCSSStyleName(name, subclass) ? name : ( name + " " + subclass );
		}; // function appendCSSStyleName (name, subclass)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function determines if a subclass name appears in a CSS style class name.
	function containsCSSStyleName (name, subclass)
		{	var pos = -1;
			
			// Didn't find the subclass name.
			if ( !name )
				{	return false;
				} // if ( !name )
			
			// Found the subclass name.
			else if ( name == subclass )
				{	return true;
				} // else if ( name == subclass )

			// Found the subclass name.
			else if ( name.indexOf(subclass + " ") == 0 )
				{	return true;
				} // else if ( name.indexOf(subclass + " ") == 0 )

			// Found the subclass name.
			else if ( (pos = name.indexOf(" " + subclass)) == (name.length - subclass.length - 1) && pos >= 0 )
				{	return true;
				} // else if ( (pos = name.indexOf(" " + subclass)) == (name.length - subclass.length - 1) && pos >= 0 )

			// Found the subclass name.
			else if ( name.indexOf(" " + subclass + " ") >= 0 )
				{	return true;
				} // else if ( name.indexOf(" " + subclass + " ") >= 0 )

			// Didn't find the subclass name.
			else
				{	return false;
				}; // else
		}; // function containsCSSStyleName (name, subclass)	

	// ------------------------------------------------------------------------------------------------------------------------

	// This function removes a subclass name appears in a CSS style class name.
	function removeCSSStyleName (name, subclass)
		{	var pos = -1;
		
			// Didn't find the subclass name.
			if ( !name )
				{	return "";
				} // if ( !name )
			
			// Found the subclass name.
			else if ( name == subclass )
				{	return "";
				} // else if ( name == subclass )

			// Found the subclass name.
			else if ( name.indexOf(subclass + " ") == 0 )
				{	return name.substring(subclass.length, name.length);
				} // else if ( name.indexOf(subclass + " ") == 0 )

			// Found the subclass name.
			else if ( (pos = name.indexOf(" " + subclass)) == (name.length - subclass.length - 1) && pos >= 0 )
				{	return name.substring(0, name.length - subclass.length - 1);
				} // else if ( (pos = name.indexOf(" " + subclass)) == (name.length - subclass.length - 1) && pos >= 0 )

			// Found the subclass name.
			else if ( name.indexOf(" " + subclass + " ") >= 0 )
				{	var pos = name.indexOf(" " + subclass + " ");
					return name.substring(0, pos) + name.substring(pos + subclass.length + 1, name.length);
				} // else if ( name.indexOf(" " + subclass + " ") >= 0 )

			// Didn't find the subclass name.
			else
				{	return name;
				}; // else
		}; // function removeCSSStyleName (name, subclass)

// Quiz Global Definitions ----------------------------------------------------------------------------------------------------

	var QUIZ_CLASS_CORRECT		= "correct";
	var QUIZ_CLASS_INCORRECT	= "incorrect";
	var QUIZ_CLASS_ONCOMPLETE	= "oncomplete";
	var QUIZ_CLASS_ONINCOMPLETE	= "onincomplete";

// Quiz Function Definitions --------------------------------------------------------------------------------------------------
	
	// This function shows the answer for a static quiz.
	function quiz_static_show_answer (control)
		{	// Set the containing quiz into the oncomplete state.
			quiz_set_oncomplete(control);
		}; // function quiz_static_show_answer (control)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function hides the answer for a static quiz.
	function quiz_static_hide_answer (control)
		{	// Set the containing quiz into the oncomplete state.
			quiz_reset(control);
		}; // function quiz_static_hide_answer (control)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function checks if an input's value is correct.
	function quiz_check_ans (control)
		{	// The user answered correctly.
			if ( control )
				{	// Determine if the answer is correct.
					var is_correct = quiz_input_correct(control);

					// Is this a wrong checkbox?
					var wrong_checkbox = control.type == "checkbox" && control.getAttribute("correct") == "no";

					// Get the class name to apply.
					var classname = is_correct ? QUIZ_CLASS_CORRECT : ( control.getAttribute("correct") == "yes" ? "" : QUIZ_CLASS_INCORRECT );

					// Use a blank class name of checkboxes marked as the wrong answer.
					var classname	= ( classname == QUIZ_CLASS_CORRECT && wrong_checkbox ) ? "" : classname;	

					// Get the current classname.
					var curr_classname = control.parentNode.className;

					// Remove both correct/incorrect subclasses.
					curr_classname = removeCSSStyleName(curr_classname, QUIZ_CLASS_CORRECT);
					curr_classname = removeCSSStyleName(curr_classname, QUIZ_CLASS_INCORRECT);

					// Set the parent's class to correct.
					control.parentNode.className = appendCSSStyleName(curr_classname, classname);

					// Check the quiz.
					quiz_check_is_complete(control);
				}; // if ( control )
		}; // function quiz_check_ans (control)

	// ------------------------------------------------------------------------------------------------------------------------

	// This method determines if a quiz is complete and sets its status accordingly.
	function quiz_check_is_complete (node)
		{	// Now set the quiz to completed if needed.
			var quiz = quiz_get_quiz(node);

			// No quiz element?
			if ( !quiz )
				{	return;
				}; // if ( !quiz )

			// Get the answer containers.
			var nodes = quiz ? quiz.getElementsByTagName("div") : false;

			// Get the number of answers.
			var num_nodes = nodes ? nodes.length : 0;			

			// Boolean value indicating whether the quiz is completed.
			var completed = true;

			// Makes sure all the answers are correct.
			// for ( var index = 0; completed && index < num_nodes; index++ )
			for ( var index = 0; index < num_nodes; index++ )
				{	// Check the next node.
					if ( containsCSSStyleName(nodes.item(index).className, "q") )
						{	completed = completed && quiz_check_node(nodes.item(index));							
						}; // if ( containsCSSStyleName(nodes.item(index).className, "q") )
				}; // for ( var index = 0; index < num_nodes; index++ )

			// Get the current classname.
			var curr_classname = quiz.className;

			// Remove both correct/incorrect subclasses.
			curr_classname = removeCSSStyleName(curr_classname, QUIZ_CLASS_ONCOMPLETE);
			curr_classname = removeCSSStyleName(curr_classname, QUIZ_CLASS_ONINCOMPLETE);

			// Mark the quiz as completed or uncompleted.
			quiz.className = appendCSSStyleName(curr_classname, completed ? QUIZ_CLASS_ONCOMPLETE : QUIZ_CLASS_ONINCOMPLETE);
		}; // function quiz_check_is_complete (node)

	// ------------------------------------------------------------------------------------------------------------------------

	// This method determines if a question node's answer is correct.
	function quiz_check_node (node)
		{	// Nothing to check.
			if ( !node )
				{	return false;
				}; // if ( !node )

			// Find the text input control.
			var nodes	= node.getElementsByTagName("input");
			node		= nodes.length == 1 ? nodes.item(0) : false;
			if ( !node )
				{	return false;
				}; // if ( !node )
			return node.getAttribute("correct") == "yes" ? quiz_input_correct(node) : true;
		}; // function quiz_check_node (node)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function returns the containing quiz.
	function quiz_get_quiz (node)
		{	// Find the quiz element.
			while ( node && !(node.nodeName.toLowerCase() == "div" && containsCSSStyleName(node.className, "quiz")) )
				{	node = node.parentNode;
				}; // while ( node && !(node.nodeName.toLowerCase() == "div" && containsCSSStyleName(node.className, "quiz")) )

			return node;
		}; // function quiz_get_quiz (node)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function checks if an input's value is correct.
	function quiz_input_correct (control)
		{	// Get the input type.
			var type = control.type;

			// Check the fill-in.
			if ( type == "text" )
				{	// Get the answer and value.
					var ans = "" + (control ? control.getAttribute("ans") : "");
					var val = "" + (control ? control.value : "");

					// Trim leading and trailing whitespace and convert to lowercase.
					ans = ans.replace(/^\s+|\s+$/, "").toLowerCase();
					val = val.replace(/^\s+|\s+$/, "").toLowerCase();

					return val == ans;
				} // if ( type == "text" )

			// Check the selection.
			else if ( type == "checkbox" )
				{	return ( control.checked && control.getAttribute("correct") == "yes" ) || ( !control.checked && control.getAttribute("correct") != "yes" );
				} // else if ( type == "checkbox" )

			// Invalid type.
			else
				{	return false;
				}; // else
		}; // function quiz_input_correct (control)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function sets a quiz into the initial state, searching up the DOM as needed.
	function quiz_reset (node)
		{	// Find the quiz element.
			node = quiz_get_quiz(node);

			// Append the CSS style.
			if ( node )
				{	var classname	= node.className; 
					classname		= removeCSSStyleName(classname, QUIZ_CLASS_ONCOMPLETE);
					node.className	= appendCSSStyleName(classname, QUIZ_CLASS_ONINCOMPLETE);
				}; // if ( node )
		}; // function quiz_reset (node)

	// ------------------------------------------------------------------------------------------------------------------------

	// This function sets a quiz into the oncomplete state, searching up the DOM as needed.
	function quiz_set_oncomplete (node)
		{	// Find the quiz element.
			node = quiz_get_quiz(node);

			// Append the CSS style.
			if ( node )
				{	var classname	= node.className; 
					classname		= removeCSSStyleName(classname, QUIZ_CLASS_ONINCOMPLETE);
					node.className	= appendCSSStyleName(classname, QUIZ_CLASS_ONCOMPLETE);
				}; // if ( node )
		}; // function quiz_set_oncomplete (node)

	// ------------------------------------------------------------------------------------------------------------------------

	function quiz_show_answer (control, show)
		{	// Get the parent node.
			var parent = control && control.parentNode ? control.parentNode : false;

			// Get all the input controls.
			var inputs = parent ? parent.getElementsByTagName("input") : false;

			// Get the number of inputs.
			var num_inputs = inputs ? inputs.length : 0;

			// The input to set.
			var input = false;

			// Find the input.
			for ( var index = 0; index < num_inputs; index++ )
				{	if ( inputs.item(index).getAttribute("name") == "ans" )
						{	input = inputs.item(index);
						}; // if ( inputs.item(index).getAttribute("name") == "ans" )
				}; // for ( var index = 0; index < num_inputs; index++ )

			// Set the input's value.
			if ( input )
				{	input.value			= control.innerHTML == "Show Answer" ? input.getAttribute("ans") : "";
					control.innerHTML	= control.innerHTML == "Show Answer" ? "Hide Answer" : "Show Answer";
					quiz_check_ans(input);					
				}; // if ( input )
		}; // function quiz_show_answer (control)