	var xmlDoc;				// XML doc with all questions
	var totalquestions;		// total questions
	var currentquestion;	// current question
	var httpresponse;		// response from HTTP request
	var nocorrect = 0;		// number of questions correct
	var noanswered = 0;		// number of questions answered
	var qans;				// array of questions answered
	var quizxml = 'quest.xml';
	var quizxmlurl = 'http://www.libertydrivingschool.net/quest.xml';
	
	function elem(psID) { 
	   if(document.all) { 
	      return document.all[psID]; 
	   } else if(document.getElementById) { 
	      return document.getElementById(psID); 
	   } else { 
	      for (iLayer = 1; iLayer < document.layers.length; iLayer++) { 
	         if(document.layers[iLayer].id == psID) 
	            return document.layers[iLayer]; 
	      }       
	   } 
	   return null; 
	} 
	
	function getURL(url)
	{ 
		var req = null; 

		document.ajax.dyn.value="Started...";
 
		if (window.XMLHttpRequest)
		{
 			req = new XMLHttpRequest();
			if (req.overrideMimeType) 
			{
				req.overrideMimeType('text/xml');
			}
		} 
		else if (window.ActiveXObject) 
		{
			try {
				req = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e)
			{
				try {
					req = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e) {}
			}
        	}


		req.onreadystatechange = function()
		{ 
			document.ajax.dyn.value="Wait server...";
			if(req.readyState == 4)
			{
				if(req.status == 200)
				{
					document.ajax.dyn.value="Received:" + req.responseText.length + ' byte(s)';	
					httpresponse = req.responseText;
					if (httpresponse != '') {
						textToXML(httpresponse);
					} else {
						alert('Unable to retrieve the questions for the quiz');
					}
				}	
				else	
				{
					document.ajax.dyn.value="Error: returned status code " + req.status + " " + req.statusText;
				}	
			} 
		}; 
		req.open("GET", url, true); 
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
		req.send(null); 
	}

	// convert the XML doc text into a XML object
	function textToXML(text)
	{
		// load the xml file into object
		// code for IE
		if (window.ActiveXObject)
		{
			xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
			xmlDoc.async = false;
			xmlDoc.loadXML(text);
			processQuestions()
		}
		// code for Mozilla, etc.
		else if (document.implementation &&	document.implementation.createDocument)
		{
			xmlDoc = document.implementation.createDocument("","",null);
			xmlDoc.loadXML(text);
			xmlDoc.onload = processQuestions;
		} else {
			alert('Your browser cannot handle this script');
		}
	}

	// process the question XML
	function processQuestions()
	{
		// document.getElementById("to").innerHTML=
		var questionset = xmlDoc.getElementsByTagName("questionset");
		var question = questionset[0].getElementsByTagName("question");
		totalquestions = question.length;
		currentquestion = 0;
		qans = new Array();
		for (var i=0; i < totalquestions; i++) {
			qans[i] = 0;
		}
		buildNavigation();
		buildQuestion();
	}

	// rounds number to X decimal places, defaults to 2
	function round(number,X) {
	    X = (!X ? 2 : X);
	    return Math.round(number*Math.pow(10,X))/Math.pow(10,X);
	}
	
	// parse the XML questions document
	function buildNavigation()
	{
		var text;
		
		text = '<p><table border="0" cellpadding="2" cellspacing="0" class="qtopnav">\n';
		text += '<tr>\n';
		text += '\t<td><input type="button" name="_prev" value="&lt;&lt; Prev" onclick="';
		if (currentquestion > 0)
			text += 'moveprevious()"></td>\n';
		else
			text += 'alert(\'You are at the first question, there is no previous question\')" disabled="TRUE"></td>\n';
		if (noanswered > 0) {
			var correctpct = round((100 * nocorrect) / noanswered) + '%';
			text += '\t<td align="center">'+nocorrect+' of '+noanswered+' answered correctly ('+correctpct+')</td>\n';
		} else {
			text += '\t<td align="center" class="qtopnavt">Question '+(currentquestion+1)+' of '+totalquestions+'</td>\n';
		}
		text += '\t<td align="right"><input type="button" name="_next" value="Next &gt;&gt;" onclick="';
		if (currentquestion < totalquestions - 1)
			text += 'movenext()"></td>\n';
		else
			text += 'alert(\'You are at the last question, there is no next question\')" disabled="TRUE"></td>\n';
		text += '</tr>\n';
		text += '</table></p>';
		// build the question key
		var qkeyclass, qkeylabel;
		text += '<p><table border="0" cellpadding="0" cellspacing="0" class="qkeynav">\n';
		for (var i=0; i < totalquestions; i++) {
			if (i % 18 == 0) text += '<tr>\n';
			if (i == currentquestion)
				qkeyclass = "qkeycurr";
			else if (qans[i] == 0)
				qkeyclass = "qkeyskip";
			else if (qans[i] < 0)
				qkeyclass = "qkeywrong";
			else
				qkeyclass = "qkeyright";
			if (currentquestion == i)
				qkeylabel = '<u><i><font class="quizcomplete">'+(i+1)+'</font></i></u>';
			else
				qkeylabel = i+1;
			text += '\t<td width="30" class="'+qkeyclass+'" onmouseover="this.className=\'qkeyhover\'" onmouseout="this.className=\''+qkeyclass+'\'" onclick="jumptoquestion('+i+')">'+qkeylabel+'</td>\n';
			if (i % 18 == 17) text += '</tr>\n';
		}
		if (i % 18 != 0) text += '</tr>\n';
		text += '</table></p>\n';
		document.getElementById("topnav").innerHTML = text;
	}
	
	// build the images that go along w/question
	function buildImages()
	{
		var questimg = document.getElementById("questionimg");
		var questionset = xmlDoc.getElementsByTagName("questionset");
		var question = questionset[0].getElementsByTagName("question");
		var image = question[currentquestion].getElementsByTagName("image");
		if (!image.length) {
			questimg.innerHTML = '';
			questimg.style.visibility = 'hidden';
			questimg.style.display = 'none';
			return;
		}
		text = '<p><table border="0" cellpadding="0" cellspacing="0" class="qimages" width="100%">\n';
		text += '<tr><td>\n'
		for (var i=0; i < image.length; i++) {
			text += '<img src="'+image[i].childNodes[0].nodeValue+'"';
			if (image[i].getAttribute("width") > 0)
				text += ' width="'+image[i].getAttribute("width")+'"';
			if (image[i].getAttribute("height") > 0)
				text += ' height="'+image[i].getAttribute("height")+'"';
			if (image[i].getAttribute("alt"))
				text += ' alt="'+image[i].getAttribute("alt")+'"';
			if (image[i].getAttribute("href"))
				text += ' onclick="location.href=\''+image[i].getAttribute("href")+'\'"';
			text += ' style="{margin: 5px 15px 5px 15px;}">';
		}
		text += '</td></tr>\n'
		text += '</table></p>\n';
		questimg.innerHTML = text;
		questimg.style.visibility = '';
		questimg.style.display = 'block';
	}
	
	// build the HTML for an individual question
	function buildQuestion()
	{
		var text, choice, label, chdiv;
		
		if (currentquestion < 0 || currentquestion > totalquestions - 1)
		{
			alert('Invalid question no. specified (question no = ' + currentquestion + ')');
			return;
		}
		var questionset = xmlDoc.getElementsByTagName("questionset");
		var question = questionset[0].getElementsByTagName("question")[currentquestion];
		var correctanswer = question.getAttribute("correctanswer");
		
		var questhtml = document.getElementById("question");
		questhtml.innerHTML = '<b>'+(currentquestion + 1)+'. '+question.childNodes[0].nodeValue+'</b>';
		// build the images displayed here
		buildImages();
		var answer = question.getElementsByTagName("answer");
		for (var i=0; i < answer.length; i++) {
			choice = document.getElementById("rbq"+(i+1));
			if (choice != null) choice.value = answer[i].getAttribute("index");
			if (choice != null) choice.checked = (Math.abs(qans[currentquestion]) == answer[i].getAttribute("index"));
			label = document.getElementById("rbq"+(i+1)+"label");
			if (label != null) label.innerHTML = String.fromCharCode(65+i)+'. '+answer[i].childNodes[0].nodeValue;
			chdiv = document.getElementById("rbq"+(i+1)+"div");
			if (chdiv != null) chdiv.style.visibility = '';
			if (chdiv != null) chdiv.style.display = 'block';
			// answer[i].getAttribute("index")
		}
		// hide the remaining choices
		for (; i < 8; i++) {
			chdiv = document.getElementById("rbq"+(i+1)+"div");
			if (chdiv != null) chdiv.style.visibility = 'hidden';
			if (chdiv != null) chdiv.style.display = 'none';
			choice = document.getElementById("rbq"+(i+1));
			if (choice != null) choice.checked = false;
		}
		// display or hide the "check answer"
		var submitdiv = document.getElementById("submitdiv");
		if (submitdiv) {
			if (qans[currentquestion] == 0) {
				submitdiv.style.visibility = '';
				submitdiv.style.display= 'block';
			} else {
				submitdiv.style.visibility = 'hidden';
				submitdiv.style.display= 'none';
			}
		}
	}
	
	// jump to a specific question in the quiz
	function jumptoquestion(questionno) {
		if (questionno >= 0 && questionno < totalquestions) {
			currentquestion = questionno;
			buildNavigation();
			buildQuestion();
			// display the answer result
			document.getElementById("result").innerHTML = '';
			buildAnswerResult();
			var qerr = document.getElementById("questionerr");
			if (qerr) {
				qerr.innerHTML = '';
				qerr.style.visibility = 'hidden';
				qerr.style.display = 'none';
			}
		}
	}
	
	// move to the next question
	function movenext() {
		if (currentquestion < totalquestions) {
			jumptoquestion(currentquestion + 1);
		}
	}

	// move to the next question
	function moveprevious() {
		if (currentquestion > 0)
			jumptoquestion(currentquestion - 1);
	}

	// display "correct" or "incorrect answer"
	function buildAnswerResult(correctanswer)
	{
		var answer, i;

		// determine the correct answer from XML
		var questionset = xmlDoc.getElementsByTagName("questionset");
		var question = questionset[0].getElementsByTagName("question");
		if (!correctanswer) {
			correctanswer = question[currentquestion].getAttribute("correctanswer");
		}
		if (qans[currentquestion] == 0) return;
		text = '<br>';
		if (qans[currentquestion] > 0) {
			text += '<p><b class="responsegood">Congratulations!  That is the correct answer.</b></p>';
		} else if (qans[currentquestion] < 0) {
			text += '<p><b class="responsebad">Sorry, your answer is incorrect.  The correct answer is:</b></p>';
			answer = question[currentquestion].getElementsByTagName("answer");
			for (i=0; i < answer.length; i++) {
				if (answer[i].getAttribute("index") == correctanswer) {
					text += '<blockquote>' + String.fromCharCode(65+i)+'. '+answer[i].childNodes[0].nodeValue + '</blockquote>';
				}
			}			
		} else if (qans[currentquestion] == -3) {
			text += '<p><b class="responsebad">Sorry, no correct answer exists for this question ('+correctanswer+')</b></p>';
		}
		// show indicator that survey is complete
		if (noanswered >= totalquestions) {
			text += '<p><b class="quizcomplete">The survey has been completed</b></p>';
		} else {
			// find the next unanswered question
			var unanswered = -1;
			for (i=currentquestion+1; i < totalquestions; i++)
				if (qans[i] == 0) {
					unanswered = i;
					break;
				}
			if (unanswered == -1) {
				for (i=0; i < currentquestion-1; i++)
					if (qans[i] == 0) {
						unanswered = i;
						break;
					}
			}
			// add continue button for next unanswered question
			if (unanswered != -1) {
				text += '<p align="center"><input type="button" name="continue" value="Continue ..." class="form" onclick="jumptoquestion('+unanswered+')"></p>\n';
			}
		}
			
		document.getElementById("result").innerHTML = text;
	}
	
	// build the HTML for an individual question
	function checkAnswer()
	{
		var text, qerr;
		
		if (currentquestion < 0 || currentquestion > xmlDoc.getElementsByTagName("questionset")[0].childNodes.length - 1)
		{
			alert('Invalid question no. specified (question no = ' + currentquestion + ')');
			return;
		}
		if (qans[currentquestion] != 0)
		{
			alert('You have already answered this question');
			return;
		}
		var questionset = xmlDoc.getElementsByTagName("questionset");
		var question = questionset[0].getElementsByTagName("question");
		var correctanswer = question[currentquestion].getAttribute("correctanswer");
		var userresponse = 0;
		for (var i=0; i < 8; i++) {
			choice = document.getElementById("rbq"+(i+1));
			if (choice && choice.checked)
				userresponse = choice.value;
		}
		if (userresponse == 0) {
			qerr = document.getElementById("questionerr");
			if (qerr) {
				qerr.innerHTML = '<b class="responsebad">Please choose an answer below</b><br><br>';
				qerr.style.visibility = '';
				qerr.style.display = 'block';
			}
			return;
		} else {
			qerr = document.getElementById("questionerr");
			if (qerr) {
				qerr.innerHTML = '';
				qerr.style.visibility = 'hidden';
				qerr.style.display = 'none';
			}
		}
		if (correctanswer != '') {
			if (userresponse == correctanswer) {
				qans[currentquestion] = userresponse;
				noanswered++;
				nocorrect++;
			} else {
				qans[currentquestion] = -userresponse;
				noanswered++;
			}
		} else {
			qans[currentquestion] = -3;
		}
		// display the answer result
		buildAnswerResult(correctanswer);
		
		// hide the "check answer" button
		var submitdiv = document.getElementById("submitdiv");
		if (submitdiv) {
			submitdiv.style.visibility = 'hidden';
			submitdiv.style.display= 'none';
		}
		buildNavigation();
	}
	
	// called when the page is first loaded
	function pageLoad() {
		if (window.ActiveXObject) {
			// the IE way...
			var curdate = new Date();
			var ts = curdate.getHours() * 3600 + curdate.getMinutes() * 60 + curdate.getSeconds();
			getURL(quizxml+'?ts='+ts);
		} else {
			// the Mozilla way...
			if (document.implementation && document.implementation.createDocument)
			{
				xmlDoc = document.implementation.createDocument("","",null);
				xmlDoc.load(quizxmlurl);
				xmlDoc.onload = processQuestions;
			}
		}
	}

