//Bob Hanson hansonr@stolaf.edu gvst.js -- functions for fusion.stolaf.edu/gca/nist
//
ThermoData=new Array()
Names=new Array()
Equations=new Array()
P=new Array()
Rgas = 8.31451

ithisequation=-1
lastequation=""
lastname=""
zoomstate=1 //normal
zoomxmax=1000

function getShomateData(name,t,isextrapolateok,ifix,V,n,ifirst,press){
 var sout=""
 if(t==0)t=V[0]
 var is298=(t==298.15)
 var Data=ThermoData[name].Data
 var i2=Data[0].length
 for (var i=1;i<i2;i++){
	if(t>=Data[0][i-1] && t<=Data[0][i])break
 }
 if(i==i2 && isextrapolateok)i=(t<Data[0][0]?1:i2-1)
 if(i==i2 && !is298)return t+","

/*
Cp = A + B*t + C*t2 + D*t3 + E/t2
H - H298.15= A*t + B*t2/2 + C*t3/3 + D*t4/4 - E/t + F - H
S = A*ln(t) + B*t + C*t2/2 + D*t3/3 - E/(2*t2) + G
    Cp = heat capacity (J/mol*K)
    H = standard enthalpy (kJ/mol)
    S = standard entropy (J/mol*K) - Rgas ln press
    t = temperature (K) / 1000.
*/

 var A=Data[1][i]
 var B=Data[2][i]
 var C=Data[3][i]
 var D=Data[4][i]
 var E=Data[5][i]
 var F=Data[6][i]
 var G=Data[7][i]
 var H=Data[8][i]
 var t=t/1000
 var t2=t*t
 var t3=t2*t
 var t4=t3*t
 var Ho=ThermoData[name].Ho+(is298?0: A*t + B*t2/2 + C*t3/3 + D*t4/4 - E/t + F - H)
 var So=(is298?ThermoData[name].So:A*Math.log(t) + B*t + C*t2/2 + D*t3/3 - E/(2*t2) + G)
 var Go=Ho-t*So
 var Cpo=A + B*t + C*t2 + D*t3 + E/t2
 if(ifix){
	Ho=fix(Ho)
	So=fix(So)
	Go=fix(Go)
	Cpo=fix(Cpo)
 }
 if(n){
	var s=So-Rgas*Math.log(press)
	V[ifirst+1]+=Ho*n
	V[ifirst+2]+=s*n
	V[ifirst+3]+=(Ho-t*s)*n
	V[ifirst+4]+=Cpo*n
	return
 }
 var V=[t*1000,Ho,So,Go,Cpo]
 return V
}

function fix(v){
 if(v=="")return ""
 var S=(v+".").split(".")
 return S[0]+"."+S[1].substring(0,1)
}


function loadData(imode){
 if(0 && !imode){
	setTimeout("loadData(1)",1000)
	return
 }
 var userformula=(nistinfo.document.location.search+"&formula=H2&").split("formula=")[1]
 userformula=userformula.split("&")[0]
 document.msg.data.value=parseNistHTML(userformula,nistinfo.document.getElementById("nistinfo").innerHTML)
}

function textof(s){
 var sout=""
 var S=s.replace(/\>/g,"<").split("<")
 for(var i=1;i<S.length;i+=2)S[i]=""
 return S.join("")
}

function getTheData(name,sdata){
 lastname=name
  var A=ThermoData[name]
 if(A)return A.info
 document.title=""

 var s=sdata.split("Shomate")[2]
 if(!s)return "//"+name+": NO SHOMATE EQUATION DATA"

 A=ThermoData[name]=new Array()
 document.title=name
 var nistformula=getInfo(sdata,'Formula:</strong> ',"</li>")
 if(nistformula.indexOf("<li>")>0)nistformula=nistformula.split("<li>")[0]  //IE 
 A.nistformula=textof(nistformula)
 Names[A.nistformula]=A.name=name
 A.Ho=parseFloat(parseTableLine("<td>"+getInfo(sdata,'Delta><sub>f</sub>H',"</tr>"))[1])
 A.So=parseFloat(parseTableLine("<td>"+getInfo(sdata,'<td align=left>S',"</tr>"))[1])
 if(!A.Ho)A.Ho=0
 if(!A.So)return "Ho="+A.Ho+" No So data found"

 s=s.split("Reference")[0]
 A.Data=parseTable(s)
 if(A.Data[0]){
  for(var i=1;i<A.Data[0].length;i++){
	A.Data[0][i-1]=parseFloat(A.Data[0][i].split(" - ")[0])
	A.Data[0][i]=parseFloat(A.Data[0][i].split(" - ")[1])
  }
  for(var i=1;i<A.Data.length;i++){
	for(var j=1;j<A.Data[i].length;j++)A.Data[i][j]=parseFloat(A.Data[i][j])
  }
 }
 createInfo(A)
 showGraph(name)
 return A.info
}

function parseNistHTML(userformula,sdata){
 var s=""
 sdata=sdata.replace(/\n/g,"").replace(/STRONG/g,"strong").replace(/\/A/g,"/a").replace(/TD/g,"td").replace(/TR/g,"tr").replace(/TH/g,"th").replace(/SUB/g,"sub").replace(/LI/g,"li").replace(/\"/g,"")
 var name=getInfo(sdata,'name=Top>',"</a>")
 Names[userformula]=name
 Names[name]=userformula
 return getTheData(name,sdata)
}

function showGraph(name){
	graphinfo.document.location=ThermoData[name].divgraph
	document.getElementById("zoomspan").style.visibility="hidden"
	setNoteExtra(ThermoData[name].extrapolatedfrom)
	showData298()
}

function getInfo(sdata,s0,s1){
 var i=sdata.indexOf(s0)
 var j=sdata.indexOf(s1,i+1)
//alert(i+" "+j+" "+s0+" "+s1+" "+sdata)
 if(i<0|| j<0)return ""
 return sdata.substring(i+s0.length,j)
}

function parseTable(sdata){
 var Data=new Array()
 var S=sdata.split("<tr")
 for(var i=1;i<S.length;i++){
	Data[Data.length]=parseTableLine(S[i])
 }
 return Data
}

function parseTableLine(sline){
 var S=sline.replace(/\//g,"").replace(/\<t(h|d)/g,"<td").split("<td")
 var s=""
 var A=new Array()
 for(var i=1;i<S.length;i+=2){
	A[A.length]=S[i].substring(S[i].indexOf(">")+1,S[i].length)
 }
 return A
}

function createInfo(A){
 var tdata="T(K),DELTA_f_Ho(kJ/mol),So(J/mol-K),Delta_f_Go(kJ/mol),Cpo(J/mol-K)\n"
 tdata+=getShomateData(A.name,298.15)+"\n"
 var V=new Array()
 var g="dograph.htm?"
 var t1=A.Data[0][0]
 if(t1==298)t1=300
 var t2=A.Data[0][A.Data[0].length-1]
 A.t1=t1
 A.t2=t2
 for(var t=t1;t<=t2;t+=100){
	V=getShomateData(A.name,t)
	tdata+=V+"\n"
	g+=V[0]+","+V[3]+","
 }
 A.divgraph=g+";xaxislabel=T(Kelvin);yaxislabel=G(kJ/mol);title="+A.name+";xmin=0;ymax=0;docurve=true;dopoints=false"
 A.info="name,"+A.name+"\nformula,"+A.nistformula+"\nHo,"+A.Ho+"\nSo,"+A.So+"\n"+A.Data.join("\n")+"\n"+tdata
}


function newData(name,userformula,nistformula,Ho,So,Data){
 var A=ThermoData[name]=new Array()
 Names[userformula]=name
 Names[nistformula]=name
 Names[name]=userformula
 A.name=name
 A.nistformula=nistformula
 A.Ho=Ho
 A.So=So
 A.Data=Data
 checkExtrapolation(A)
 createInfo(A)
}

function checkExtrapolation(A){
 var V1=getShomateData(A.name,298.15,0)
 var V2=getShomateData(A.name,298.1499,1)
 if(Math.abs(V1[0]-V2[0])<1 && Math.abs(V1[1]-V2[1])<1){
	A.extrapolatedfrom=A.Data[0][0]
	A.Data[0][0]=240
 }else{
	//alert(A.name+" "+V1+" "+V2)
 }
}


function newEquation(seqn){
 for(var i=0;i<Equations.length;i++)if(Equations[i].seqn==seqn)return i
 lastequation=seqn
 var E=Equations[Equations.length]=new Array()
 E.seqn=seqn
 seqn=seqn.replace(/\-/g,"+").replace(/\s+/g,"")
 var isprod=0
 var S=seqn.split("+")
 var s=""
 var schem=""
 var n=0
 E.Species=new Array()
 E.defaultPress=""
 for(var i=0;i<S.length;i++)if(S[i]){
	schem=S[i]
	if(schem.charAt(0)==">"){
		isprod=1
		schem=schem.substring(1,schem.length)
	}
	if(parseFloat(schem)){
		for(var j=0;j<schem.length;j++)if("0123456789./".indexOf(schem.charAt(j))<0)break
		n=(j?eval(schem.substring(0,j)):1)
		schem=schem.substring(j,schem.length)
	}else{
		n=1
	}
	var C=E.Species[E.Species.length]=new Array()
	C.formula=schem
	C.n=n
	C.isprod=isprod
	E.defaultPress+="P["+schem+"]=1\n"
 }
 s=""
 isprod=0
 E.html="<font color~blue>"

 for(var i=0;i<E.Species.length;i++){
	C=E.Species[i]
	if(!isprod && C.isprod){
		s+=" --> "
		E.html+=" </font><img src~arrow.gif><font color~red>"
		isprod=1
	}else if(i>0){
		s+=" + "
		E.html+=" + "
	}
	s+=(C.n==1?"":C.n+" ")+C.formula
	E.html+=(C.n==1?"":C.n+" ")+setsubs(C.formula)
 }
 E.html+="</font>"
 E.setting=s
 return Equations.length-1
}

function getEquationList(){
 var s="\n<select name=eqnlist onchange=doSetEquation() onkeypress=\"setTimeout('doSetEquation()',50)\">\n<option selected value=-1>Select an Equation</option>"
 for(var i=0;i<Equations.length;i++)s+="\n<option value="+i+">"+Equations[i].seqn+"</option>"
 s+="\n<option value=9999>new equation...</option></select>"
 document.write(s)
}

function doOK(){
 var userformula=document.info.formula.value
 if(Names[userformula]&&ThermoData[Names[userformula]]){
	var name=Names[userformula]
	document.msg.data.value=ThermoData[name].info
	graphinfo.document.location=ThermoData[name].divgraph
	document.title=name
	return
 }
 document.info.submit()
}

function doGetGraph(name){
 if(!name)name=lastname
 if(!ThermoData[name]){
	alert("Load the data first.")
	return
 }
// open(ThermoData[name].divgraph)
 showGraph(name)
}

function doGetNistInfo(form){
 loadData()
}

function doGetJS(){
 var s=""
 var sout='ThermoData=new Array()\nNames=new Array()\nA="A";B="B";C="C";D="D";E="E";F="F";G="G";H="H"\n'
 var A=new Array()

 for (var n in ThermoData){
	A=ThermoData[n]
	if(A.name){
		sout+="newData('"+A.name+"'"
		sout+=",'"+Names[A.name]+"'"
		sout+=",'"+A.nistformula+"'"
		sout+=","+A.Ho
		sout+=","+A.So
		sout+=",[["+A.Data[0]+"]"
		for(var i=1;i<=8;i++)sout+=",["+A.Data[i]+"]"
		sout+="]"
		sout+=")\n"
	}
 }
 sout+="\nEquations=new Array()\n"
 for(var i=0;i<Equations.length;i++)if(Equations[i].Species)sout+="newEquation('"+Equations[i].seqn+"')\n"
 document.msg.data.value=sout
}

function doSetEquation(i){
 if(arguments.length==0)i=parseInt(document.eqn.eqnlist[document.eqn.eqnlist.selectedIndex].value)
 if(i<0)return
 ithisequation=i
 var E=Equations[i]
 if(!E){
	ithisequation=-1
	var s=prompt("New Equation?",lastequation)
	if(!s)return
	i=Equations.length
	var j=newEquation(s)
	E=Equations[j]
	ithisequation=j
	if(!E||!E.Species)return
	var c=document.eqn.eqnlist
	if(j==i){
		var o=new Option(s,j)
		c.options[c.options.length-1]=o
		var o=new Option("new equation...",9999)
		c.options[c.options.length]=o
	}
	c.selectedIndex=j+1
 }
 setPartialPressures(E,1)
 document.title=E.setting
 doGetGraphEqn()
}

function getGData(E,isprod){
 var t1=0
 var t2=10000000
 var S=new Array()
 var V=new Array()
 var C=new Array()
 var f=""
 for(var i=0;i<E.Species.length;i++)if(E.Species[i].isprod==isprod){
	C=E.Species[i]
	f=C.formula
	if(!Names[f]||!ThermoData[Names[f]]){
		alert("No data found for "+f+"...loading...")
		getNistData(f)
		return 0
	}
	S=ThermoData[Names[f]]
	if(S.t1>t1)t1=S.t1
	if(S.t2<t2)t2=S.t2
	if(!P[f])P[f]=1.0
 }
 var n=t2-t1
 while(n>50)n=Math.floor(n/2)
 var n=Math.floor((t2-t1)/n)
 var ipt=-1
 var nstep=(t1>1000?n:zoomstate<1?5:20)

 E.Data298=[298.15,0,0,0,0,0,0,0,0]
 addVdata(E.Species,E.Data298,0,0)
 addVdata(E.Species,E.Data298,1,0)

 if(t2==10000000)t2=0
 for(var t=t1;t<=t2;t+=nstep){
	if(t>1000)nstep=n
	ipt++
	V[ipt]=(isprod?[t,"","","","",0,0,0,0]:[t,0,0,0,0])
	addVdata(E.Species,V[ipt],isprod,1)
 }
 return V
}

function addVdata(S,V,isprod,ifix){
	var ifirst=(isprod?4:0)
	for(var i=0;i<S.length;i++)if(S[i].isprod==isprod){
		C=S[i]
		getShomateData(Names[C.formula],0,0,0,V,C.n,ifirst,P[C.formula])
		if(!C.npts)C.npts=0
		C.npts++
	}
	if(!ifix)return
	V[ifirst+1]=fix(V[ifirst+1])
	V[ifirst+2]=fix(V[ifirst+2])
	V[ifirst+3]=fix(V[ifirst+3])
	V[ifirst+4]=fix(V[ifirst+4])
}

function doGotoNist(){
 var formula=document.info.formula.value
 var s="http://webbook.nist.gov/cgi/cbook.cgi?Formula="+formula+"&MatchIso=on&NoIon=on&Units=SI&cTG=on"
 open(s)
}


function setsubs(sform){
 if(!sform)return ""
 var s=""
 var sf=""
 var minussign="&#150;"
 var sdigits=" 0123456789."
 var isnum=false
 var s2=""
 var ihavechar=false
 for (var i=0;i<sform.length;i++){
  s=sform.charAt(i)
  isnum=(sdigits.indexOf(s)>0)
  if(isnum){
 	if(!ihavechar)isnum=0
  }else{
	ihavechar=1
  }
  sf=sf + (isnum?"<sub>"+s+"</sub>":s)
 }
 return sf
}

function getNistData(sform){
 document.info.formula.value=sform
 document.info.submit()
}

function setPartialPressures(E,isreset){
 P=new Array()
 if(isreset)document.press.pressdata.value=E.defaultPress
 var s=document.press.pressdata.value.replace(/\[/g,"['").replace(/\]/g,"']").replace(/\'\'/g,"'")
 eval(s)
}

function doGetGraphEqn(){
 if(ithisequation<0){
	alert("First you need to select an equation.")
	return
 }

 var E=Equations[ithisequation]
 if(!E)return
 setPartialPressures(E,0)
 E.RData=getGData(E,0)
 if(!E.RData)return
 E.PData=getGData(E,1)
 if(!E.PData)return
 var sout="T(K),DELTA_f_Ho(reactants kJ/mol),S(reactants J/mol-K),Delta_f_Go(reactants kJ/mol),Cpo(reactants J/mol-K),DELTA_f_Ho(products kJ/mol),S(products J/mol-K),Delta_f_Go(products kJ/mol),Cpo(products J/mol-K)\n"
 sout+=E.RData.join("\n")+"\n\n" 
 sout+=E.PData.join("\n")+"\n" 
 document.msg.data.value=sout
 document.getElementById("zoomspan").style.visibility="visible"
 var t=0
 var name=""
 var t1=0
 for(var i=0;i<E.Species.length;i++){
	name=Names[E.Species[i].formula]
	t1=ThermoData[name].extrapolatedfrom
	if(t1 && t1>t)t=t1
 }
 setNoteExtra(t)

 var g="dograph.htm?"
 var E=Equations[ithisequation]
 E.ymin=E["ymin"+zoomstate]
 var ineedymin=(!E.ymin)
 var y=0
 var x=0
 if(ineedymin)E.ymin=0
 for(var i=0;i<E.RData.length;i++){
	x=parseFloat(E.RData[i][0])
	y=parseFloat(E.RData[i][3])
	if(x<=zoomxmax*zoomstate){
		g+=x+","+y+","
		if(ineedymin && y<E.ymin)E.ymin=y
	}
 }
 for(var i=0;i<E.PData.length;i++){
	x=parseFloat(E.PData[i][0])
	y=parseFloat(E.PData[i][7])
	if(x<=zoomxmax*zoomstate){
		g+=E.PData[i][0]+","+y+","
		if(ineedymin && y<E.ymin)E.ymin=y
	}
 }
 E["ymin"+zoomstate]=E.ymin
 s="<font color~blue>"+E.html.replace(/\-/,"</font>-").replace(/\-\>/,"-><font color~red>")+"</font>"
 E.divgraph=g+";ymin="+E.ymin+";xaxisaty="+E.ymin+";xaxislabel=T(Kelvin);yaxislabel=G(kJ/mol);xmin=0;ymax=0;docurve=true;dopoints=false;title="+E.html
 setNewWinLink(E.divgraph)
 showData298(E)
 graphinfo.document.location=E.divgraph

 //document.msg.data.value=E.divgraph.length
}

function doZoom(incr){
 var z=zoomstate
 zoomstate*=incr
 if(zoomstate<0.6)zoomstate=0.5
 if(zoomstate>8)zoomstate=8
 if(z!=zoomstate)doGetGraphEqn()
}

function setNewWinLink(s){
	document.getElementById("newwinlink").href=s
}

function setNoteExtra(t){
	document.getElementById("noteextra").innerHTML=(t?"(data extrapolated from "+t+" to 240 Kelvin)":"")
}

function showData298(E){
	var s=""
	if(E){
		var dH=fix(E.Data298[5]-E.Data298[1])
		var dS=fix(E.Data298[6]-E.Data298[2])
		var dG=fix(E.Data298[7]-E.Data298[3])
		s="<center><table border=1 cellpadding=5><tr><td bgcolor=#e0e0e0>&Delta;<sub>r</sub>H<sub>298</sub>="+dH+" kJ/mol"
		+"<br>&Delta;<sub>r</sub>S<sub>298</sub>="+dS+" J/mol-K"
		+"<br>&Delta;<sub>r</sub>G<sub>298</sub>="+dG+" kJ/mol</td></tr></table></center>"
	}
	document.getElementById("data298").innerHTML=s
}