//CHECKJS  D:\js\safety\safety.js 5/29/2003 7:57:12 AM
VER="3/18/05 feeback: <a href=mailto:hansonr@stolaf.edu>Bob Hanson</a>"
ACSpamphlet="<a target=_blank href=http://membership.acs.org/c/ccs/pub_3.htm><i>Safety in Academic Chemistry Laboratories</i></a>"

//program options
debugging=true&&false
autodisplay=1
istest=false&&true
iscramble=true
isprintable=(document.location.search.indexOf("printable")>=0)

Color=new Array()
Color.excellent="#A0FFA0"
Color.learning="#FFFFA0"
Color.wrong="#FF0000"
Color.untried="#FFFFFF"

docstyle="<style>"
docstyle+="body,td,th,tr,p,.p {font-size:12pt}"
docstyle+="H2 {font-size:24pt}"
docstyle+="H3 {font-size:16pt}"
docstyle+="table,form,blockquote,td,tr,body{margin-top: 1px; margin-bottom: 1px;}"
docstyle+=".q{position:relative}"
docstyle+=".table0{background-color:white}"
docstyle+=".table1{background-color:#F0F8FF}"
docstyle+=".table2{background-color:#FFF8DC}"
docstyle+="sub,sup{font-size:80%}"
docstyle+="a{color:darkred}"
docstyle+="a.scorelink{text-decoration:none}"
docstyle+=".btn{position:absolute;top:100;left:500}"
docstyle+=".pt{background-color:#FFCC00}"
docstyle+=".p{background-color:#FFCC00}"
docstyle+=".symbol{font-family:symbol}"
docstyle+=".prologbody{background-color:#000000}"
docstyle+=".prologinfobody{background-color:#000000;color:#FFCC00;font-size:14pt;margin-left:11mm;margin-right:11mm}"
docstyle+=".epiloginfobody{background-color:#000000;color:#FFCC00;font-size:14pt;margin-left:11mm;margin-right:11mm}"
docstyle+=".epilogbody{background-color:#000000}"
docstyle+=".leftMain{}"
docstyle+=".rightMain{}"
docstyle+=".ref{font-size:10pt}"
docstyle+="SectionTitleDone{color:blue}"
docstyle+="</style>"

//not user adjustable:

//for Questions
TITLE=0
QUEST=1
ANS=2
REF=3

//for Sections.Questions
IPT=0
QNUM=1
IGNORE=2
NTRIES=3

//global initializations
MINUS=sym("-")
EACUTE=sym("#3")
sdigits=" 0123456789"
Ans=new Array()
Score=new Array()
Done=new Array()
Ntries=new Array()
Isok=new Array()
Sections=new Array()
nQuest=0
nSections=0
nimage=0
nimage0=0
mytime0=0
toggle=1
alldone=0

function check(n,a,img,isec,iques){
	var isok=(Ans[n]==a?1:0)
	if(!Score[n])Score[n]=(isok?1:-1)
	Sections[isec].Questions[iques][IGNORE]=isok
	Ntries[n]++
	Isok[n]=isok
	Sections[isec].Questions[iques][NTRIES]++
	if(isok && Sections[isec].Questions[iques][NTRIES]==1){
		Done[n]=1
	}else{
		Sections[isec].Questions[iques][IGNORE]=0
		if(isok)Sections[isec].Questions[iques][NTRIES]=0
	}
	document.images[img].src=(Done[n]?"okg.gif":isok?"oky.gif":"x.gif")
	var i=getNLeftInSection(isec)
	if(Sections[isec].Done){
		showDiv("SectionTitle"+isec,"")
		showDiv("SectionTitleDone"+isec,getSectionTitle(isec))
	}else{
		showDiv("SectionTitle"+isec,getSectionTitle(isec))
	}
	showDiv("score",getScore())
	if(debugging)showDiv("debug",dumpS("check"+n+" "+isec+" "+iques))
}

function getQuestionInfo(){
	nimage=document.images.length
	nQuest=0
	nSections=0
	for(var i=1;i<Questions.length;i++){
		if(Questions[i][TITLE]){
			Sections[nSections]=new Array()
			Sections[nSections].Ipt=i
			Sections[nSections].Questions=new Array()
			Sections[nSections].Title=Questions[i][TITLE]
			Sections[nSections].Done=0
			nSections++
		}else{
			nQuest++
			Score[nQuest]=Done[nQuest]=Ntries[nQuest]=Isok[nQuest]=0
			//[index into Questions, absolute question #,ignore this entry,# tries]
			Sections[nSections-1].Questions[Sections[nSections-1].Questions.length]=[i,nQuest,0,0]
			var a=Questions[i][ANS]
			if(a.indexOf("*")<0)alert("Question "+nQuest+": "+Questions[i][QUEST]+"\n\nhas no correct answer indicated.")
			if(a.lastIndexOf("*")>a.indexOf("*")+1)alert("Question "+nQuest+": "+Questions[i][QUEST]+"\n\nhas two correct answer indicated.")
		}
	}
}


function getQuestion(isec,iques){
	var sout=""
	var s=""
	var i=0
	var isquiz=1
	var headerrow=""
	if(iques>=0){
		i=Sections[isec].Questions[iques][IPT]
		nimage=nimage0
		nq=Sections[isec].Questions[iques][QNUM]
		sout="<b>"+Sections[isec].Title+"&nbsp;&nbsp;"+"</b>"+getRef(i,nq)
		headerrow="<tr><td width=1></td><td align=left width=20></td><td width=500></td></tr>"
	}else{
		i=isec
		if(Questions[i][TITLE]){
			sout="<hr><h3>"+Questions[i][TITLE]+"</h3><p>"
			return sout
		}

		nq++
		isquiz=0
		headerrow="<tr><td width=10></td><td width=1></td><td width=500></td></tr>"
	}

	var q=Questions[i][QUEST].replace(/’/g,"'")
	var a=Questions[i][ANS].replace(/’/g,"'")
	var A=a.split(";")
	var ABC="abcdefghij"
	var r=""
	var isok=0
	var nsort=A.length-(a.indexOf("**")>=0||a.indexOf(" of the above")>=0?1:0)
	var ni=0
	toggle=3-toggle
	sout+="<table width=600><tr><td align=left class=table"+toggle+">"
	sout+="\n<table "+(istest?"border":"")+" width=600>"
	+headerrow
	+"<tr><td valign=top align=right>"+(isquiz?"":nq+".")+"</td><td align=left colspan=2 valign=top>"+q+"<br>&nbsp;</td></tr>"
	
	if(iscramble){
		for(var j=0;j<nsort-1;j++){if(Math.random()>0.5){
				a=A[j]
				A[j]=A[j+1]
				A[j+1]=a
		}}
	}
	for(var j=0;j<A.length;j++){
		s=A[j]
		if(s.indexOf("*")>=0){
			isok=true
			Ans[nq]=j
			if(!istest)s=s.replace(/\*/g,"")
		}else{
			isok=false
		}

		if(s.indexOf("~")==0)s=setsubs(s.substring(1,s.length),0)
		sout+="\n<tr><td align=left>"
		+"<img src="+(!istest?"transp.gif":isok?"ok.gif":"x.gif")+" name=img"+nimage+"></td>"
		+"<td valign=top align=right>"+(isquiz?"<a href=javascript:check("+nq+","+j+","+nimage+","+isec+","+iques+")>"+ABC.charAt(j)+"</a>":ABC.charAt(j))+")&nbsp;&nbsp;</td><td align=left valign=top>"+s+"</td>"
		if(!isquiz && j==A.length-1)sout+="<td valign=bottom>"+getRef(i,0)+"</td>"
		sout+="</tr>"
		nimage++
	}
	
	sout+="</table>"
	sout+="</td></tr></table>"
	sout=sout.replace(/\[\[\-\]\]/g,MINUS).replace(/\[\[eacute\]\]/g,EACUTE)
	return sout
}

function setsubs(sform,icharge){
	var s=""
	var sf=""
	if(arguments.length==1)icharge=0
	var iabs=Math.abs(icharge)
	for (var i=0;i<sform.length;i++)
	{
		s=sform.charAt(i)
		sf=sf + (sdigits.indexOf(s)>0?"<sub>"+s+"</sub>":s)
	}
	if(icharge)sf+="<sup>"+(iabs==1?"":iabs)+(icharge>0?"+":minussign)+"</sup>"
	return sf
}

function getAllQuestions(){
	nq=0
	var sout="<form name=info>"
	for(var i=1;i<Questions.length;i++)sout+=getQuestion(i,-1)
	sout+="</form>"
	return sout//.replace(/\</g,"<br>&lt;")
}

function showEnd2(){
	var sout="<center><form><input type=button value=\"Score the Exam\" onclick=showScore()></form></center>"
	+"<center><form><input type=button value=\"New Blank Exam\" onclick=showNew()></form></center><pre>\n\n\n\n\n</pre>"
	now=new Date()
	return sout
}

function showNew(){
	var S=(document.location+"").split("?")
	document.location=S[0]
}

function showTop(){
	var sout=docstyle
	sout+="<title>"+nQuest+" Questions That Could Save Your Life Laboratory Safety Quiz</title>"
	sout+="<H2>"+nQuest+" Questions That Could Save Your Life</h2>"
//	+"<span class=heading></span>"
	return sout
}

function getBtns(){
	var sout="<table>"
	for(var i=0;i<nSections;i++){
		sout+="<tr>"//(i==0?"<tr>":i%2==0?"</tr><tr>":"")
		sout+="<td nowrap class=catTd><a href=javascript:doNext("+i+",-1,-1)><span id=SectionTitle"+i+">"+getSectionTitle(i)+"</span></a><span id=SectionTitleDone"+i+"></span></td>"
		sout+="</tr>"
	}
	sout+="</tr></table></center>"
	return sout
}

function getSectionTitle(isec){
 var n=getNLeftInSection(isec)
 var sout=Sections[isec].Title+" ("+(n?n:"DONE")+")"
 return sout
}

function getLeader(){
 var s=""
 s+="<table align=center width=500 cellpadding=10><tr><td align=center bgcolor=#C0FFC0><table><tr><td>"
 +"This laboratory safety quiz is based on material in the American Chemical Society pamphlet "+ACSpamphlet+". "
 +"<p>You can take this quiz in any order. Select a section from the list or a question from the number block. You don't necessarily have to know the answer to a question -- the idea is to learn as you go. "
 +"But if you are serious about safety, then you should read the ACS pamphlet carefully, and your overall goal should be to get the questions right on the FIRST try and achieve 100% in all sections. "
 +"If you get a question wrong, you will be asked it again. "
 +"If you get it right on the FIRST try, you get a green check and it counts 1 point toward your score; if you get it wrong, think a bit and try another answer. You can still get half a point. "
 +"<p>If you can get 100% in 15 minutes, then consider yourself a an expert. But don't let it go to your head. "
 +"<p>If you get a lot of yellow checks, you're still learning. Consider taking another look at <i>Safety in Academic Chemistry Laboratories</i> and trying again."
 +"<p>Note to CHOs: It is absolutely trivial to modify this quiz to your own specifications. Just ask me, and I will send you the code, the images, and the simple Excel file that contains the questions."
 +getContact()
 +"</td></tr></table></td></tr></table>"
 return s
}

function showAll(){
 nimages=nimage=document.images.length
 getQuestionInfo()
 var s=showTop()
 if(isprintable){
	document.write(s)
	document.write(getAllQuestions())
	document.write(getContact())
	return
 }
 s+="<table>"
 +"<tr><td class=leftMain nowrap valign=top>"+getBtns()+"<div id=score>"+getScore()+"</div></td>"
 +"<td class=rightMain valign=top>"
 +"<div id=qcell>"
 +getLeader()
 +"</div><div id=debug></div>"
 +"</td></tr>"
 +"</table>"
// +showAllQuestions()
 document.write(s)
}

function doNext(isec,inotthisq,thisques){
	var sout="<form name=info>"
	var S=new Array()
	var iques=thisques
	if(thisques>=0){
		S[0]=thisques
	}else{
		for(var i=0;i<Sections[isec].Questions.length;i++){
			if(!Sections[isec].Questions[i][IGNORE])S[S.length]=i
		}
		randomize(S)
	}
	for(var i=0;i<S.length;i++){
		iques=S[i]
		if(Sections[isec].Questions[iques][QNUM]!=inotthisq){
			sout+=getQuestion(isec,iques)
			inotthisq=Sections[isec].Questions[iques][QNUM]
			break
		}
	}
	sout+="</form>"
	if(iques>=0){
		sout+="<a href=javascript:doNext("+isec+","+inotthisq+",-1)>another in this section</a>"
		if(debugging)sout+="&nbsp;&nbsp;&nbsp;&nbsp;iques="+iques+" QNUM="+inotthisq+" S="+S
	}else{
		sout+="No more questions in this section."
		i=getNextSection()
		sout+=getReport(i)
	}
//	sout+="<P>"+Score+"<P>"+Ntries
	showDiv("qcell",sout)
	//if(debugging)showDiv("debug",sout.replace(/\</g,"<br>&lt;"))
	if(debugging)showDiv("debug",dumpS("doNext"))
}

function getNextSection(){
 for(var i=0;i<Sections.length;i++){
	if(!Sections[i].Done)return i
 }
 return -1
}	


function randomize(S){
 var i0=0
 var i1=0
 var n=0
 if(S.length<2)return(S.length-1)
 for(i=0;i<100;i++){
  i0=rand(S.length)
  i1=i0
  while(i1==i0)i1=rand(S.length)
  n=S[i0];S[i0]=S[i1];S[i1]=n
 }
}

function rand(n){
 if(n<=0)return -1
 var i=n
 while(i==n)i=Math.floor(Math.random()*n)
 return i 
}

function showDiv(sd,sinfo){
 var d=(document.getElementById?document.getElementById(sd):0)
 if(d){
	d.innerHTML=sinfo
 }else{
	alert("Your browser will not work for this quiz. Please try another.")
 }
}

function getRef(i,nq){
	var s=Questions[i][REF]
	if(!istest)s=s.split("/")[0]
	return "<span class=ref>"+(nq?"#"+nq+" source:":"")+s+"</span>"
}

function getNLeftInSection(isec){
 var n=0
 for(var i=0;i<Sections[isec].Questions.length;i++){
	if(!Sections[isec].Questions[i][IGNORE]){
		n++
	}
 }
 if(n==0)Sections[isec].Done=1
 return n
}

function dumpS(msg){
 var sout=msg
 for(var i=0;i<Sections.length;i++){
  sout+="<br>"+Sections[i].Title+" "+Sections[i].Done
  for(var j=0;j<Sections[i].Questions.length;j++)sout+="<br>  "+Sections[i].Questions[j] +"?"+Sections[i].Questions[j][QNUM]+" Done="+Done[Sections[i].Questions[j][QNUM]]+" Ntries="+Ntries[Sections[i].Questions[j][QNUM]]
 }
 sout+="<br>Done="+Done
 sout+="<br>Ntries="+Ntries
 return sout
}

function getScore(){
	var c=""
	var nq=0
	var ncol=12
	var sout="<table cellspacing=0 cellpadding=0><tr><td>"
	sout+="<table border=1 cellspacing=0 cellpadding=2><tr>"
	for(var i in Color)sout+="<td bgcolor="+Color[i]+">"+i+"</td>"
	sout+="</tr></table>"
	sout+="</td><td>&nbsp;&nbsp;&nbsp;&nbsp;<a href=javascript:showReport()>score quiz</a></td>"
	sout+="</tr></table>"

//	sout+="(Click on a number to display that question.)"
	sout+="<table cellspacing=0>"
	for(var isec=0;isec<Sections.length;isec++){
		for(var iques=0;iques<Sections[isec].Questions.length;iques++){
			nq=Sections[isec].Questions[iques][QNUM]
			if(nq%ncol==1)sout+="<tr>"
			if(Score[nq]==1){
				c=Color.excellent
			}else if(!Ntries[nq]){
				c=Color.untried
			}else if(Isok[nq]){
				c=Color.learning
			}else{
				c=Color.wrong
			}
			sout+="<td align=center bgcolor="+c+"><a class=scorelink href=javascript:doNext("+isec+",-1,"+iques+")>"+nq+"</a></td>"
			if(nq%ncol==0)sout+="</tr>"
		}
	}
	sout+="</tr></table>"
	sout+="<p>A <a target=_blank href=./index.htm?printable>printable version</a> of this quiz is available."
	sout+="<br><a href=javascript:getIntro()>Instructions</a>"
	sout+="<br>"+ACSpamphlet
	return sout
}

function getIntro(){
	showDiv("qcell",getLeader())
}

function getContact(){
	return "<p>(preliminary version "+VER+")"
}

function getReport(inext){
 now=new Date()
 var sout="<table border=1 cellspacing=0>"
 var nq=0
 var S=new Array()
 var score=0
 var tried=0
 var overallscore=0
 var overalltried=0
 var l=0
 var mytime=mytime0+((new Date())-now)/1000
 var mm=Math.floor(mytime/60)
 var ss=Math.floor(mytime-mm*60)
 var mmss=mm+" minute"+(mm==1?"":"s")+" and "+ss+" second"+(ss==1?"":"s")
 var alldone=(inext<0)
 sout+="<tr><tr><td>Section</td><td>#</td><td>tried</td><td>correct</td><td>score</td></tr>"
 for(var isec=0;isec<Sections.length;isec++){
	tried=score=0
	l=Sections[isec].Questions.length
	for(var iques=0;iques<l;iques++){
		nq=Sections[isec].Questions[iques][QNUM]
		if(Score[nq]==1){
			score++
			tried++
		}else if(Isok[nq]){
			tried++
			score+=0.5
		}else if(Ntries[nq]){
			tried++
		}
	}

	sout+="<tr><td>"+(Sections[isec].Done?Sections[isec].Title:"<a href=javascript:doNext("+isec+",-1,-1)>"+Sections[isec].Title+"</a>")
	+"</td><td align=center>"+l
	+"</td><td align=center>"+tried
	+"</td><td align=center>"+score
	+"</td><td align=right>"+(Math.floor(score/l*1000)/10)+"%</td></tr>"
	overallscore+=score
	overalltried+=tried
 }
 sout+="<tr><td>overall"
	+"</td><td align=center>"+nQuest
	+"</td><td align=center>"+overalltried
	+"</td><td align=center>"+overallscore
	+"</td><td align=right>"+(Math.floor(overallscore/nQuest*1000)/10)+"%</td></tr>"
 sout+="</table>"
 if(overalltried==nQuest)sout+="<p>Congratulations! You have answered all of the questions. In all, it took you "+mmss+" to complete the test. "+(mytime<=600?"That is a very good time! Now go practice what you have learned.":"You should repeat the test and try to get 100% within 15 minutes.")
 return sout
}

function showReport(){
 showDiv("qcell",getReport())
}
