//CHECKJS  C:\temp\sudoku\sudoku3d.js 11/6/2005 12:30:08 PM
//sudoku3d.js hansonr@stolaf.edu 7:00 AM 10/28/2005
//3d functions using Jmol  http://jmol.sourceforge.net
isjmolinitialized=0
isjmolreset=0
thisslicen=0
thisr_or_c=0
dorotatemodel=0
rsep=5.0
csep=-5.0
ksep=-7.0
connectwidth=150
isliveconnecterror=0
showremainingonly=0
Output=new Array()
AtomPt=new Array()
AtomInfo=[
	["O","oxygen","red"],
	["S","sulfur","orange"],
	["B","boron","yellow"],
	["Be","beryllium","green"],
	["Na","sodium","cyan"],
	["N","nitrogen","blue"],
	["I","iodine","indigo"],
	["He","helium","violet"],
	["C","carbon","grey"],
	["H","hydrogen","white"]
]

function addAtom(Array,n,itype,y,x,z){
	Array.atoms[n-1]=rformat(x+.001,10)+rformat(y+.001,10)+rformat(z+.001,10)+" "+AtomInfo[itype][0]+" "
}

function addBond(Array,n,Ainfo,Binfo,soff){
	if(Ainfo.length>2||Binfo.length>2){
		//must be strong group
		return n
	}
	var a=atomOf(Ainfo)
	var b=atomOf(Binfo)
	if(soff.indexOf("="+a+" ")>=0||soff.indexOf("="+b+" ")>=0)return n
	Array.bonds[n]=rformat(a,3)+rformat(b,3)+"  1  "
	return n+1
}

function addParam(sappcode,sname,svalue){
	return sappcode.replace(/\<param/,"<param name=\""+sname+"\" value=\""+svalue+"\" />\n<param")
}

function atomOf(Nodeinfo,i,j,k){
	if(arguments.length==1){
		i=Nodeinfo[1][0].row
		j=Nodeinfo[1][0].col
		k=Nodeinfo[0]
	}
	return k+j*9+i*81+1 //k+j*9+i*81+1
}

function clickModel(a,s,c,d,e,f,g){
//alert(s + " " + c + " " + d + " " + e + " " + f + " " + g)
	s=""+s
	//	document.getElementById("logmsg").innerHTML+="<br />"+s.replace(/\n/g,"<br />")
}

var doreset = false

function create3DModel(n,r_or_c){
	document.getElementById("chains").style.display="none"
	var irotate=(arguments.length<2 || dorotatemodel)
	if(r_or_c){
		n=-1
		thisr_or_c=r_or_c
	}
	if(r_or_c==0||thisr_or_c==0)irotate=0
	if(!n)n=0
	thisslicen=n
	var doslice = (n != 0 || thisr_or_c != 0)
	var idobonds=1
	var natoms=0
	var nbonds=0
	var sout=""
	var soff=""
	var slist=""
	var sknown=""
	var sdots=""
	var N=new Array()
	AtomPt=new Array()
	Output=new Array()
	Output.header=""
	Output.atoms=new Array()
	Output.bonds=new Array()
	Output.trailer="M  END"
	//Output.script="set specpower 40;set specular 60;set ambient 20;set diffuse 80;"//(thisr_or_c?"":"reset;")
	Output.script=""
	Output.script2=""
	for(var i=0;i<AtomInfo.length;i++)if(AtomInfo[i][2])Output.script+="color "+AtomInfo[i][1]+" "+AtomInfo[i][2]+";"
	Output.script+="hover off;select *;spacefill 250;wireframe "+connectwidth+";select hydrogen;wireframe 0.1;set echo bottom center; echo " 
		+ (doslice ? "\"\"" : "left-mouse drag to rotate model") + ";set echo top center; echo \""
	+(n>0?"just n="+n:n<0 && thisr_or_c<0?"column "+(-thisr_or_c):n<0 && thisr_or_c>0?"row "+thisr_or_c:"1 (red) - 9 (grey)")+"\";"
	//points
	for(var i=0;i<9;i++)for(var j=0;j<9;j++)for(var k=0;k<9;k++){
		addAtom(Output,++natoms,k,i*csep,j*rsep,k*ksep)
		AtomPt[natoms]=[i,j,k]
		if(n<0 && (thisr_or_c<0 && j!=-thisr_or_c-1 || thisr_or_c>0 && i!=thisr_or_c-1) || n>0 && k!=n-1){
			soff+="or atomno="+natoms+" "
		}else if(k==Data[i][j].N-1){
			sknown+="or atomno="+natoms+" "
		}else if(Data[i][j].N||!Data[i][j].Allowed[k]){
			soff+="or atomno="+natoms+" "
		}
	}
        var RowLabels = []
	var ColLabels = []
        if (doslice)getRowColumnLabels(n, thisr_or_c, RowLabels, ColLabels)
	var s = ""
	for (var i=0;i<9;i++){
		s += "set echo row"+i+"{ " 
			+ (n > 0 ? (-1 * rsep) + " " + (-i*rsep) + " " + ((n-1) * ksep) 
			:  thisr_or_c > 0 ? (-1 * rsep) + " " + (-thisr_or_c*rsep) + " " + (i * ksep) 
			: (-thisr_or_c * rsep) + " " + (1*rsep) + " " + (i * ksep) )
			+ "};set echo row" + i + " right;echo " + (RowLabels[i]?RowLabels[i]:'""')+";color echo " + (n > 0 || !doslice?  "red" : AtomInfo[i][2]) + ";"
		s += "set echo col"+i+"{" 
			+ (n > 0 ? (-2.0-i*csep) + " " + (10*csep+ (i%2 ? 6 : 2)) + " "  + ((n-1) * ksep) 
			:  thisr_or_c > 0 ? (i * rsep-2.0) + " " + (-thisr_or_c*rsep) + " " + (-13.5 * rsep+ (i%2 ? 6 : 2)) 
			: (-thisr_or_c * rsep) + " " + (2.0-i*rsep) + " " + (-13.5 *rsep + (i%2 ? 6 : 2)) )
			+ "};set echo col" + i + " left;echo " + (ColLabels[i]?ColLabels[i]:'""')+";color echo white;"
	}		

	Output.script+=s


	//axes
	var s = ";"
	var a0 = natoms
	for(var k=-0.5;k<9;k+=9)for(var i=-0.5;i<9;i+=3)for(var j=-0.5;j<9;j+=3){
		addAtom(Output,++natoms,9,i*csep,j*rsep,k*ksep)
		sdots+="or atomno="+natoms+" "
	}
	for (var i = 1; i <= 13; i+= 4)	s += "connect {atomno=" + (a0 + i) + "} {atomno="+(a0+i+3)+"};"
	for (var i = 1; i <= 4; i++)	s += "connect {atomno=" + (a0 + i) + "} {atomno="+(a0+i+12)+"};"
	for (var i = 1; i <= 16; i++)	s += "connect {atomno=" + (a0 + i) + "} {atomno="+(a0+i+16)+"};"
	a0 = natoms - 16
	for (var i = 1; i <= 13; i+= 4)	s += "connect {atomno=" + (a0 + i) + "} {atomno="+(a0+i+3)+"};"
	for (var i = 1; i <= 4; i++)	s += "connect {atomno=" + (a0 + i) + "} {atomno="+(a0+i+12)+"};"

//	for(var k=.5;k<9;k+=1)for(var i=-0.5;i<9;i+=9)for(var j=-0.5;j<9;j+=9){
//		addAtom(Output,++natoms,9,i*csep,j*rsep,k*ksep)
//		sdots+="or atomno="+natoms+" "
//	}

	Output.script+=s + "select atomno=730;color red;"

	//strong edges

	idogrid=(document.getElementById("chk_gridlines").checked?1:0)
	Output.script+="select hydrogen;spacefill off;wireframe " + (idogrid ? 0.1 : 0) + ";"
	checkOptions()
	getStrongChains(0)
	idobonds=(document.getElementById("chk_c").checked?1:0)
	if(idobonds)for(var i=0;i<StrongEdges.length;i++)nbonds=addBond(Output,nbonds,StrongEdges[i][0],StrongEdges[i][1],soff)

	//color chains?
	var icolorchains=(ishowchain>0 || document.getElementById("chk_cc").checked?1:0)
		for(var ichain=1;ichain<StrongChains.length;ichain++){
			for(var inode=0;inode<StrongChains[ichain].length;inode++){
				var N = StrongNodes[StrongChains[ichain][inode]];
				var D = N[0]
				slist+=D
				Output.script2+="select atomno="+atomOf(D)+";color "
				+ (nodeData(N,PARITY) <= 0 ? "translucent " : "")
				+ (!icolorchains ? "cpk" : ichain==ishowchain?"red":!ishowchain?AtomInfo[ichain%AtomInfo.length][2]:"white")+";"
			}
		}

	Output.header="!\nhttp://www.stolaf.edu/people/hansonr/sudoku\n\n"+rformat(natoms,3)+rformat(nbonds,3)+"\n"

	defscript=""
	if(irotate && n<0 && thisr_or_c>0 && doreset) defscript="moveto 1 0 0 0 0;delay 1;moveto 2 1 0 0 -90;"
	if(irotate && n<0 && thisr_or_c<0 && doreset) defscript="moveto 1 0 0 0 0;delay 1;moveto 2 -1 1 1 120;"
	if(sknown.length)Output.script+="select"+sknown.substring(2,sknown.length)+";spacefill "+(showremainingonly?0:400)+";"
	if(sdots.length)Output.script+="select"+sdots.substring(2,sdots.length)+";spacefill 25;"
	if(soff.length)Output.script+="select"+soff.substring(2,soff.length)+";spacefill 0;wireframe 0;"
	Output.script+=defscript
	Output.script+=Output.script2
	sout=Output.header
	sout+=Output.atoms.join("\n")+"\n"
	if(Output.bonds.length)sout+=Output.bonds.join("\n")+"\n"
	sout+=Output.trailer
	document.getElementById("numberblock").style.display="none"
	document.getElementById("selectspan").style.display="none"
	document.getElementById("sudoku").style.display="none"
	document.getElementById("jmol").style.display="block"
	//docWrite(Output.script)
	createAppletInline(sout,Output.script)
	thisviewmode="jmol"


}

function createAppletInline(smodel,script){
	if(isjmolinitialized && !isjmolreset && !isliveconnecterror){
		isliveconnecterror=1
		document.getElementById("jmolApplet0").script(script)
		isliveconnecterror=0 //won't get here if we have a LiveConnect error (Opera)
		return
	}
	if(!isjmolinitialized)jmolInitialize(".")
	isjmolinitialized=1
	isjmolreset=0
	jmolSetDocument(0)
	var s=jmolApplet(450,"set perspectivedepth OFF;"+script,"0")
	s=addParam(s,"loadInline",smodel.replace(/\n/g,"|"))
	//var s=jmolApplet(450,"set perspectivedepth OFF;select *;color atoms translucent","0")
	//s=addParam(s,"load", "1crn.pdb")
	s=addParam(s,"pickCallback","clickModel")
	document.getElementById("apphere").innerHTML=s//.replace(/\</g,"&lt;").replace(/\|/g,"<br />")
}

function doSetGridLines() {
	if (thisviewmode != "jmol")return
	create3DModel(thisslicen,thisr_or_c)
}

function doViewReset() {
	if (thisviewmode != "jmol")return
	jmolScript("moveto 2 0 0 0 0")
}

function doView3D(r_or_c, showonly){
	isjmolreset=0
	if(!r_or_c){
		r_or_c=0
	}

        if (showonly)
		thisslicen=showonly
        else if(thisviewmode=="jmol")
		thisslicen=0
	if(r_or_c)thisslicen=-1
	doreset = (thisr_or_c * r_or_c <= 0)
	thisr_or_c=r_or_c
	thisviewmode="jmol"
	dorotatemodel=1
	create3DModel(thisslicen,r_or_c)
	dorotatemodel=0
}

function doViewRemaining(){
	showremainingonly=1
	create3DModel(0)
	showremainingonly=0
}

function doViewStrong(){
	isjmolreset=1
	thisr_or_c=0
	thisslicen=0
	ishowchain=0
	thisviewmode="jmol"
	dorotatemodel=1
	create3DModel(0)
	dorotatemodel=0
}

function rformat(s,n){
	s="                         "+s
	return s.substring(s.length-n,s.length)
}

