//Bob Hanson, St. Olaf College, 1:20 PM 11/8/00

datasource="Shift parameters are from <em>Tables of Spectral Data for Structure Determination of Organic Compounds</em>, by Pretsch, Clerc, Seibl, and Simon (Translated by K. Biemann), Springer-Verlag: Berlin, 1983, pp H255-H260."
datasource+="<br>2nd-Order calculations are adapted from <em>Laoccon</em>, by Hans Reich."
datasource+="<br>Cascading Style Sheet code adapted from work by George Wiger."

baseshift=7.36
aromaticsplit=7.5
isdetail=false

X="" //for generic groups
Y="" //for generic groups

Pos=new Array(6)
Split=new Array(6)
Couple=new Array(6)
Color=new Array(6)

/*
 If the Substituents array is set up with the 6 substituents 
 (indexes into Groups[]), then a call to 

 generatespectrum("title here")

 actually draws it.

 Symmetry is checked to see if doublets drop down to singlets.
 This is only pertinent in three cases: 
 benzene itself, 1,2-diX, and 1,4-diX-2,3-diY, and 1,2,3,4-tetraX 
 All other symmetry cases do not result in degeneracy of COUPLED protons.  

*/

Substituents=new Array(0,0,0,0,0,0) //benzene
Symmetry=new Array("0,0,0,0,0,0"
	,"0,1,0,0,1,0,0,1,0,0,1,0"
	,"0,1,2,2,1,0,0,1,2,2,1,0"
	,"0,1,1,1,1,0,0,1,1,1,1,0"
)
issymmetric=false
thismf=""

function dotestcalc(){
	getsubstituentsfromlist(document.info.testcalc.value + ",H,H,H,H,H,H")
	generatespectrum("TESTING: "+Substituents.toString())
}

function dodetails(){
	isdetail=true
	generatespectrum("")
	isdetail=false
}

function showmatrix(A,nrows,firstrow){
	if(nrows==0){
		var sout="\n"+A.length+" cols: "+A.join("\t")
	}else{
		var sout="\n"+nrows+" rows"
		var ilast=(firstrow?nrows+1:nrows)
		for (var i=firstrow;i<ilast;i++){
			sout+="\n"+i+": "+A[i].join("\t")
		}
	}
	return sout+"\n\n"
}

function loadNMRinfo(){
	var fminhz=fminppm*hzperppm
	var fmaxhz=fmaxppm*hzperppm
	Nuclei=0
	//here we map substituent numbers onto spin-set numbers
	mJcoupl=new Array()
	mShifts=new Array()
	IofN=new Array()
	NofI=new Array()
	for (var i=0;i<6;i++){
		if (Substituents[i]==0){
			Nuclei++
			mShifts[Nuclei]=Pos[i]*hzperppm
			mJcoupl[Nuclei]=new Array()
			NofI[i]=Nuclei
			IofN[Nuclei]=i
		}
	}
	for(var i=1;i<=Nuclei;i++){
		for(var j=1;j<=Nuclei;j++)mJcoupl[i][j]=0
	}
	for(var i=1;i<=Nuclei;i++){
		var m=IofN[i]
		for(var j=0;j<Couple[m].length;j++){
			var n=NofI[Couple[m][j]]
			mJcoupl[i][n]=aromaticsplit
			mJcoupl[n][i]=aromaticsplit
		}
	}
	gFreq=new Array()
	gInten=new Array()
	gWhich=new Array()
	gDisplay=new Array()
	CalcSpectrum(Nuclei,MinInt,mShifts,mJcoupl,gFreq,gInten)
	resolve(gFreq,gInten,gDisplay,fminhz,fmaxhz,reshz)
	var s=ThisMolecule[0]+"\n"+grouplist()+"\nsecond order peak assignments are not always possible\n\nppm\tint\tassignment\n\n"
	var sH=""
	var vs2=20
	var ns=0
	var A=new Array()
	var S=new Array()
	for(var i=0;i<gDisplay.length;i++){
		if(gDisplay[i][0]){
			var p=ppm(i,fminhz,reshz)
			var nH=gDisplay[i][1]
			nH=nH.substring(1,2)
			nH=sdigits.indexOf(nH)-1
			Spectrum[ns]=new Array(p,gDisplay[i][0]*vs2+1,nH)
			ns++
			A=gDisplay[i][1].split(",")
			sH=""
			for(var j=1;j<A.length;j++)sH+=(j==1?"":",")+abcdof(parseInt(A[j]))
			S[S.length]=new Array(roundoff(p,3)+"\t"+roundoff(gDisplay[i][0],2)+"\t"+sH+"\n",p)
		}
	}
	S=S.sort(osort)	
	for(var i=0;i<S.length;i++)s+=S[i][0]
	document.info.list.value+=s
	gFreq=new Array()
	gInten=new Array()
	gWhich=new Array()
	gDisplay=new Array()
}

function ppm(i,fminhz,reshz){return (fminhz+i*reshz)/hzperppm}

function resolve(gFreq,gInten,gDisplay,fminhz,fmaxhz,reshz){
	
	var n=(fmaxhz-fminhz)/reshz+1
	for(var i=0;i<n;i++)gDisplay[i]=new Array(0,"")
	
	for(var i=1;i<gFreq.length;i++){
		var f=gFreq[i]
		if(f<=fmaxhz && f>=fminhz){
			var j=Math.floor((f-fminhz)/reshz)
			gDisplay[j][0]+=gInten[i]
			var s=gWhich[i]+1
			var n=IofN[s]
			if(s>0 && gDisplay[j][1].indexOf(","+n)<0){
				s=","+n
				if(gDisplay[j][1]<s){gDisplay[j][1]+=s}else{gDisplay[j][1]=s+gDisplay[j][1]}
			}
		}
	}
}

function checksymmetry(){
	var s=""
	var N=new Array(0,0,0,0,0,0)
	var isnew=false
	var nnew=0
	for(var i=0;i<6;i++){
		if(Substituents[i]>0){
			isnew=true
			for(var j=0;j<i;j++){
				if(isnew && Substituents[j]==Substituents[i]){
					if(N[j]==0){nnew++;N[j]=nnew}
					N[i]=N[j]
					isnew=false
				}
			}
			if(isnew){nnew++;N[i]=nnew}
		}
	}
	s=N.toString()
	isnew=0
	for(var i=0;i<Symmetry.length;i++){
		if(Symmetry[i].indexOf(s)>=0)isnew=i+1
	}
	return isnew
}

function getsubstituentsfromlist(s){
	var S=s.split(",")
	Substituents=new Array(findsub(S[0]),findsub(S[1]),findsub(S[2]),findsub(S[3]),findsub(S[4]),findsub(S[5]))
}

function findsub(s){
	for(var i=0;i<Groups.length;i++){
		if(Groups[i][0].indexOf(s+"|")==0)return i
	}
	return 0
}

function generatespectrum(title){	
	var s=""
	var p=0
	var S=new Array()
	var isgeneric=title.charAt(0)=="*"
	document.info.list.value=""
	issymmetric=(isgeneric?0:checksymmetry())
	var ncouple=buildmolecule("ThisMolecule",title)
	hzperppm=getmhz()
	reshz=hzperppm/75	//peak resolution

	//alert(ncouple)
	//alert(ThisMolecule)
	var isfirstorder=(document.info.order.checked==false)
	drawspectrum(ThisMolecule)
	thismf=fixformula("C6"+grouplist(1))

	if(ncouple==0|| isfirstorder||issymmetric){
		
		for(i=1;i<ThisMolecule.length;i++){
			p=ThisMolecule[i][1]
			s=roundoff(p,3)+"\t"
			s+=ThisMolecule[i][2]+"\t"
			s+=ThisMolecule[i][3]+"\t"
			s+=(ThisMolecule[i][3]=="s"?"":ThisMolecule[i][4])+"\t"
			s+="H_"+abcdof(parseInt(ThisMolecule[i][0].substring(1,2))-1)+"\n"
			S[S.length]=new Array(s,p)
		}
		S=S.sort(osort)	
		s=ThisMolecule[0]+" "+thismf+"\n"+grouplist()+"\nppm\tint\ttype\tJ\tassignment\n"
		for(var i=0;i<S.length;i++)s+=S[i][0]
		document.info.list.value+=s
	}else{
		clearspectrum()
		loadNMRinfo()
		setHcolors()
		writelines()
	}
}

function getshift(isub){
	return baseshift+orthosum(isub)+metasum(isub)+parasum(isub)
}

function showshift(isub){
	var s=isub
	var i1=(isub+4)%6
	var i2=(isub+2)%6
	s+="\northo: "+orthosum(isub)
	s+="\nmeta: "+metasum(isub)
	s+="\npara: "+parasum(isub)
	return s
}
function orthosum(isub){
	var i1=(isub+5)%6
	var i2=(isub+1)%6
	return Groups[Substituents[i1]][2]+Groups[Substituents[i2]][2]
}
function metasum(isub){
	var i1=(isub+4)%6
	var i2=(isub+2)%6
	return Groups[Substituents[i1]][3]+Groups[Substituents[i2]][3]
}
function parasum(isub){
	var i1=(isub+3)%6
	return Groups[Substituents[i1]][4]
}

function getsplitting(isub){
	var i1=(isub+5)%6
	var i2=(isub+1)%6
	if(Substituents[i1]>0 && Substituents[i2]>0)return "'s'"
	if(Substituents[i1]==0 && Substituents[i2]==0)return "'t'"
	return "'d'"
}

function getcoupling(isub,C){
	var i1=(isub+5)%6
	var i2=(isub+1)%6
	var i=0
	if(Substituents[i1]==0){C[i]=i1;i++}
	if(Substituents[i2]==0){C[i]=i2;i++}
	return i
}

function buildmolecule(name,title){
	var Sout=new Array(6)
	Pos=new Array(6)
	Split=new Array(6)
	Couple=new Array(6)
	Color=new Array(6)
	var N=new Array(6)
	var s=""
	var isnew=false
	var ncouple=0
	var ColorList=new Array()
	for(var i=0;i<6;i++){
		Sout[i]=""
		Pos[i]=""
		Split[i]=""
		Couple[i]=new Array()
		N[i]=0
		if(Substituents[i]==0){
			Color[i]=i
			Sout[i]="H"+(i+1)	
			Pos[i]=getshift(i)
			Split[i]=(issymmetric?"'s'":getsplitting(i))
			ncouple+=(issymmetric?0:getcoupling(i,Couple[i]))
			isnew=1
			for(var j=0;j<i;j++){
				if(isnew && Pos[j]==Pos[i] && Split[j]==Split[i]){
					Sout[j]+=","+Sout[i]
					N[j]++
					isnew=0
					Color[i]=j
				}
			}
			N[i]=isnew
		}
	}

	var n=0
	var c=0
	for(var i=0;i<6;i++){if(Substituents[i]==0){
		c=Color[i]
		if(!ColorList[c]){
			ColorList[c]=++n
		}
//		Color[i]=ColorList[c]
	}}
	setorder()


	s=""
	for(var i=0;i<6;i++){
		if(N[i]){
			s+=",['"+Sout[i]+"',"+Pos[i]+","+N[i]+","+Split[i]+(Split[i]=='s'?"":","+aromaticsplit)+"]"
		}
	}
	s=name+"=new Array('"+title+" '"+s+")"
	eval(s)
	return ncouple
}

function setorder(){
	Orderof=new Array()
	S=new Array()
	for(var i=0;i<6;i++){
		if(Substituents[i]==0){
			S[Color[i]]=new Array(Color[i],Pos[i])
		}
	}
	S=S.sort(osort)
	for(var i=0;i<S.length;i++){
		if(S[i])Orderof[S[i][0]]=i+1
	}

}

function osort(a,b){
	return(!a?1:!b?-1:a[1]<b[1]?-1:a[1]>b[1]?1:0)
}

Groups=new Array(["H|H",0,0.00,0.00,0.00]
	//
	,["alkyl groups"]
	,["Me|Me",0,-0.20,-0.12,-0.22]
	,["Et|Et",0,-0.14,-0.06,-0.17]
	,["iPr|iPr",0,-0.13,-0.08,-0.18]
	,["tBu|tBu",0,0.02,-0.08,-0.21]
	,["CH2Cl|ClCH2",0,0.0,0.0,0.0]
	,["CH2OH|HOCH2",0,-0.07,-0.07,-0.07]
	,["CCl3|Cl3C",0,0.64,0.13,0.10]
	,["CF3|F3C",0,0.32,0.14,0.20]
	//
	,["vinyl and aryl groups"]
	,["CH=CH2|C2H=CH",0,0.06,-0.03,-0.10]
	,["CH=CHPh|PhCH=CH",0,0.15,-0.01,-0.16]
	,["Ph|Ph",0,0.37,0.20,0.10]
	//
	,["acetylenic groups"]
	,["CCH|HCC",0,0.15,-0.02,-0.01]
	,["CCPh|PhCC",0,0.19,0.02,0.0]
	//
	,["carbonyl groups"]
	,["CHO|HCO",0,0.56,0.22,0.29]
	,["Ac|Ac",0,0.62,0.14,0.21]
	,["COPh|PhCO",0,0.47,0.13,0.22]
	,["COtBu|tBuCO",0,0.44,0.05,0.05]
	//
	,["acid/ester groups"]
	,["CO2H|HOCO",0,0.85,0.18,0.27]
	,["CO2Me|MeOCO",0,0.71,0.11,0.21]
	,["CO2Et|EtOCO",0,0.63,0.13,0.20]
	,["CO2iPr|iPrOCO",0,0.70,0.09,0.19]
	,["CO2Ph|PhOCO",0,0.90,0.17,0.27]
	,["COBr|BrCO",0,0.80,0.21,0.37]
	,["COCl|ClCO",0,0.84,0.22,0.36]
	,["CONH2|NH2CO",0,0.61,0.10,0.17]
	//
	,["halides"]
	,["F|F",0,-0.26,0.00,-0.20]
	,["Cl|Cl",0,0.03,-0.02,0.09]
	,["Br|Br",0,0.18,-0.08,-0.04]
	,["I|I",0,0.39,-0.21,0.00]
	//
	,["amines"]
	,["NH2|H2N",0,-0.75,-0.25,-0.65]
	,["NHMe|MeNH",0,-0.80,-0.22,-0.68]
	,["NMe2|Me2N",0,-0.66,-0.18,-0.67]
	//
	,["ammonium salts"]
	,["NMe3|Me3N",1,0.69,0.36,0.31]
	//
	,["amides"]
	,["NHAc|AcNH",0,0.12,-0.07,-0.28]
	,["N(Me)Ac|AcN(Me)",0,-0.16,0.05,-0.02]
	//
	,["other N-containing groups"]
	,["NHNH2|NH2NH",0,-0.60,-0.08,-0.55]
	,["N=NPh|PhN=N",0,0.67,0.20,0.20]
	,["CN|NC",0,0.36,0.18,0.28]
	,["NO|ON",0,0.58,0.31,0.37]
	,["NO2|O2N",0,0.95,0.26,0.38]
	//
	,["alcohols,ethers,O-acyl groups"]
	,["OH|HO",0,-0.56,-0.12,-0.45]
	,["OMe|MeO",0,-0.48,-0.09,-0.44]
	,["OEt|EtO",0,-0.46,-0.10,-0.43]
	,["OPh|PhO",0,-0.29,-0.05,-0.23]
	,["OAc|AcO",0,-0.25,0.03,-0.13]
	,["OCOPh|PhCO2",0,-0.09,0.09,-0.08]
	,["OSO2Me|MeO2SO",0,-0.05,0.07,-0.01]
	//
	,["Si/P/S-containing groups"]
	,["SiMe3|Me3Si",0,0.22,-0.02,-0.02]
	,["PO(OMe)2|(MeO)2PO",0,0.48,0.16,0.24]
	,["SMe|MeS",0,-0.08,-0.10,-0.24]
	,["SPh|PhS",0,0.06,-0.09,-0.15]
	,["SO2Cl|ClSO2",0,0.76,0.35,0.45]
	,["SO2OMe|MeOSO2",0,0.60,0.26,0.33]
	,["SO3H|HOSO2",0,0.60,0.26,0.33]
)

Cmpds=new Array("|xxxxxxxx"
	,"aniline|NH2"
	,"anisole|OMe"
	,"benzaldehyde|CHO"
	,"benzene|H"
	,"benzenesulfonic acid|SO3H"
	,"benzoic acid|CO2H"
	,"o-bromoaniline|NH2,Br"
	,"m-bromoaniline|NH2,H,Br"
	,"p-bromoaniline|NH2,H,H,Br"
	,"o-bromoanisole|OMe,Br"
	,"m-bromoanisole|OMe,H,Br"
	,"p-bromoanisole|OMe,H,H,Br"
	,"bromobenzene|Br"
	,"o-bromobenzenesulfonic acid|Br,SO3H"
	,"m-bromobenzenesulfonic acid|Br,H,SO3H"
	,"p-bromobenzenesulfonic acid|Br,H,H,SO3H"
	,"2-bromo-1-ethyl-4-nitrobenzene|Et,Br,H,NO2"
	,"o-bromonitrobenzene|NO2,Br"
	,"m-bromonitrobenzene|NO2,H,Br"
	,"p-bromonitrobenzene|NO2,H,H,Br"
	,"o-chlorobenzoic acid|Cl,CO2H"
	,"m-chlorobenzoic acid|Cl,H,CO2H"
	,"p-chlorobenzoic acid|Cl,H,H,CO2H"
	,"p-chloroethylbenzene|Cl,H,H,Et"
	,"o-dibromobenzene|Br,Br"
	,"m-dibromobenzene|Br,H,Br"
	,"p-dibromobenzene|Br,H,H,Br"
	,"p-(N,N-dimethylamino)benzaldehyde|CHO,H,H,NMe2"
	,"p-ethylbenzenesulfonic acid|Et,H,H,SO3H"
	,"o-methoxybenzaldehyde|CHO,OMe"
	,"m-methoxybenzaldehyde|CHO,H,OMe"
	,"p-methoxybenzaldehyde|CHO,H,H,OMe"
	,"m-nitroacetophenone|NO2,H,Ac"
	,"p-nitroaniline|NH2,H,H,NO2"
	,"o-nitroanisole|OMe,NO2"
	,"m-nitroanisole|OMe,H,NO2"
	,"p-nitroanisole|OMe,H,H,NO2"
	,"p-nitrotoluene|Me,H,H,NO2"
	,"toluene|Me"
	,"p-toluenesulfonic acid|Me,H,H,SO3H"
	//,"Generic AB|X,X,X,X"
)

