// mysched.js
// Copyright 2001 Bob Hanson, hansonr@stolaf.edu, St. Olaf College
// 12:15 PM 8/24/2005 fix 12am/pm

regadditions="MWF 10:10-10:30 Chapel\nT 11:10-11:30 Chapel\nTh 11:00-11:20 Chapel\n"
regaddinterim="M-F 10:10-10:30 Chapel\n"
schedWinOptions="menubar,scrollbars,resizable,alwaysRaised,width=800,height=600,top=50,left=50"
weekdays="U=Sunday M=Monday T=Tuesday W=Wednesday R=Thursday F=Friday A=Saturday"
digits=" 0123456789"
slotwitdth = 0
slotsperday = 0
FULLDAY = ""
NULLDAY = ""
firsttime=0
lasttime=23
minopen=1000 //25
slotwidth=60
ndays=7
WEEKDAYS="UMTWRFA"
BGColor = {}

function setslots(swidth){
	document.frm.SlotWidth.value = slotwidth = swidth
	slotsperday=(lasttime-firsttime)*60/slotwidth
	FULLDAY=""
	NULLDAY=""
	for(var i=0;i<slotsperday;i++)FULLDAY+="N"
	for(var i=0;i<slotsperday;i++)NULLDAY+="Y"
}

function dodisplay(ismine){
	docwrite(displayof(ismine))
}

function doshowhtml(ismine){
	docwrite("<body><pre>"+displayof(ismine).replace(/</g,"&lt;")+"</pre></body>",true)
}

//main functions

function displayof(ismine, dontshowtimes, skiphtml){
	if (arguments.length < 2) dontshowtimes = false
	var igroup=document.frm.grouptimes.checked
	var includekey=document.frm.includekey.checked
	var includetime=document.frm.includetime.checked
	var stext = document.frm.mytimes.value.replace(/\r/g,"\n")
		.replace(/\f/g,"").replace(/\t/g," ").replace(/\ +/g," ")
	var stitle=[document.frm.title.value]
	firsttime=0
	lasttime=23
	minopen=1000 //25
	slotwidth=60
	slotsperday=(lasttime-firsttime)
	var ifirst=timeof(document.frm.StartTime.value,0)
	var ilast=timeof(document.frm.EndTime.value,0)
	document.frm.StartTime.value=hhmmof(ifirst)
	document.frm.EndTime.value=hhmmof(ilast)
	firsttime=ifirst
	lasttime=ilast
	setslots(60/Math.ceil(60/parseInt(document.frm.SlotWidth.value)))
	WEEKDAYS=getdays(document.frm.Days.value,true)
	ndays=WEEKDAYS.length
	document.frm.Days.value=fixdays(WEEKDAYS,false)
	var schedule=new Array(ndays+1)
	var tr=new Array(ndays+1)
	var suser=[]
	var stask=[]
	var stime=[]
	var sdata=[]
	var ndata=0
	var sdisplay=""
	var thisuser=""
	var regschedule=""
	if(stext.indexOf("Satisfies:")>=0) {
		regschedule ="<pre>"+stext + "</pre>"
		stext=fixfromregistrar(stext, stitle)
	}
	var Lines = stext.split("\n")
	for (var i = 0; i < Lines.length; i++)if (Lines[i] && Lines[i].length >= 5){ // M 3-5
		var sline=Lines[i]
		if(sline.indexOf("bgcolor:")==0){
			var S=sline.split(":")
			BGColor[S[1]]=S[2]
			if(includekey)sdisplay+="\n<br>"+sline  
			sline=""	
		}
		if(sline.indexOf(" = ")>=0)sline=sline.split(" = ")[1]
		if(sline.length>0 && sline.indexOf(":")==sline.length-1 && sline.indexOf(" ")<0)thisuser=sline
		if (thisuser!=sline){
			sline = sline.replace(/\s*am/ig,"AM").replace(/\s*pm/ig,"PM").replace(/\s*\-\s*/g,"-")
			var sinfo=sline.split(" ")
			if(sinfo.length>=2){
				ndata++
				sdata[ndata]=(digits.indexOf(sinfo[0].charAt(0))>0 ? getweekcode(sinfo[1],sinfo[0])
					: sdata[ndata]=getweekcode(sinfo[0],sinfo[1]))
				suser[ndata]=thisuser
				var caption = (sline.indexOf("<span") >= 0 ? sline.substring(sline.indexOf("<span")) : sinfo[2])
				stask[ndata]=(sinfo.length==2?"":includekey?ndata+" ("+caption+")":caption)
				stime[ndata]=sinfo[0]+" "+sinfo[1]
				if(includekey)sdisplay+="\n<br>"+ndata+" = "+sline  
			}
		}
	}
	var ipt=0
	for(var iday=1;iday<=ndays;iday++){
		schedule[iday]=new Array(slotsperday)
		tr[iday]=new Array(slotsperday)
		for(var itime=0;itime<slotsperday;itime++){
			var s=""
			for(var i=1;i<=ndata;i++)
				s+=(sdata[i].charAt(ipt)=="N"?"<br>"+suser[i]+stask[i]+(includetime?"<br>"+stime[i]:""):"")
			schedule[iday][itime]=s
			if(itime>0 && schedule[iday][itime-1]== s){
				iprev=itime-1
				i=tr[iday][iprev]
				if(i<=0)iprev=-i
				tr[iday][iprev]++
				tr[iday][itime]=-iprev
			}else{
				tr[iday][itime]=1
			}
			ipt++
		}
		ipt++  //newline  
	}   
	tr[0]=new Array(slotsperday)
	for(var itime=0;itime<slotsperday;itime++){
		var imin=1000
		for(var iday=1;iday<=ndays;iday++){
			if(tr[iday][itime]>0){
				imin=Math.min(imin,tr[iday][itime])
			}else{
				imin=Math.min(imin,tr[iday][-tr[iday][itime]]-tr[iday][itime]-itime)
			}
		}
		tr[0][itime]=imin
	}
	
	var stable=maketable(schedule,tr,!dontshowtimes,igroup)
	if (skiphtml)return stable
	var s="<head>\n<title>"+stitle+"</title>\n<style>\n th{background-color:white;font-weight:bold;font-size:10pt}\n .open{color:red;background-color:white;font-size:10pt}\n .scheduled{background:lightgrey;font-size:10pt}\n.chapel{color:blue;background-color:yellow;font-size:10pt}\n</style>\n</head>\n"
	sdisplay=s+"<body>\n<h3>"+stitle+"</h3>\n"+stable+"<pre>\n"+sdisplay+"\n</pre>\n"+regschedule+"</body>\n"
	return sdisplay
}

function maketable(schedule,tr,showTimes,igroup){
	var sout="\n<table " + (showTimes ? "border=1" : "border=0 cellspacing=0 cellpadding=1") + " width=100%>\n<tr>\n<td nowrap></td>"
	var s="\n<th width="+Math.floor(100/(ndays+(showTimes ? 1 : 0)))+"%>"
	for(var iday=0;iday<ndays;iday++)
		sout+=s+fieldof(weekdays,WEEKDAYS.charAt(iday))+"</th>"
	sout+="\n</tr>"
	for(var itime=0;itime<slotsperday;itime++){
		if(igroup){
			var i=tr[0][itime]
			s=hhmmof(itime)+" - "+hhmmof(itime+i)
			s =(i>1?" rowspan="+i:"") + ">" + (showTimes ? s : "&nbsp;")
		} else {
			s = ">" + (showTimes ? hhmmof(itime) : "")
		}
		s = s.replace(/AM/g,"").replace(/PM/g,"")
		sout += "\n<tr>" + (showTimes ? "<th nowrap" : "<td style='font-size:1pt'") + s + (showTimes ? "</th>" : "</td>")
		for(var iday=1;iday<=ndays;iday++){
			s=schedule[iday][itime]
			if(s.length)s = (igroup ? s+"<br>&nbsp;" : s.substring(4))
			var S = s.split("<br>")
			if (S.length > 2) {
				for (var i= 0; i < S.length - 2; i++)
					if (S[i] == S[i+2])
						S[i] = "\n"
				s = S.join("\n").replace(/\n+/g,"\n").replace(/\n/g,"<br>")
			}
			var i=tr[iday][itime]
			var sopen=(i*slotwidth>minopen?"<br>OPEN<br>&nbsp;":"&nbsp;")
			var bgcolor=getbgcolor(s)
			if(i>0)
				sout += "\n<td align=center"
					+(i>1?" rowspan="+i:"")
					+(s.indexOf("Chapel")>=0 ? " class=chapel>"+s
					: s.length? (bgcolor?bgcolor:" class=scheduled ")+">"+s 
						: " class=open>"+sopen)
				   	+"</td>"
		}
		if(igroup){
			var s=""
			for(var iday=1;iday<=ndays;iday++)s+="<td></td>"
			for(var i=1;i<tr[0][itime];i++)sout+="\n</tr>\n<tr>"+s
			itime+=tr[0][itime]-1
		}
		sout+="\n</tr>"
	}   
	sout+="\n</table>"
	return sout
}

function fixfromregistrar(stext,stitle){
	var sout=""
	var st = ""
	var nac=0
	var scourse=""
	var ithis=-1
	setslots(10)
	includekey=document.frm.includekey.checked=false
	var S=stext.split("\n")
	for (var i=0;i<S.length;i++){
		var sline=S[i]
		if(sline.indexOf("Registered Courses for")>=0)st=sline
		if(sline.indexOf("Academic Year, ")>=0){
			nac++
			if(nac>1)break
			st+=" "+sline
			document.frm.title.value=st
			sout=(st.indexOf("Interim")>=0?regaddinterim:regadditions)
		}
		if(sline.length==0){
			ithis=i
			sout+="\n"
		}else if(ithis==i-1){
			scourse=sline.replace(/ /g,"").replace(/\(LAB\)/,"L")
		}else if((sline.indexOf("-1")>=0||sline.indexOf("-0")>=0)&&ithis==i-3){
			var L=sline.split(" ")
			sout+=L[1]+" "+L[2]+" "+scourse+"\n"
			ithis=i-2
		}
	}
	stitle[0] = st
	return sout
}

function getbgcolor(s){
	for(var i in BGColor)
		if(s.indexOf(i)>=0) return " class=scheduled style=background-color:"+BGColor[i]
	return ""
}

//utilities

function fieldof(slist,schar){
	var i=slist.indexOf(schar+"=")
	if(i<0)return ""
	var s=slist.substring(i+2,slist.length)
	var i=s.indexOf(" ")
	if(i<0)return s
	return s.substring(0,i)
}

function fixdays(sdays,toURA){
	var s=sdays
	if(toURA){
		if(s=="")s="MTWRF"
		return s.toUpperCase().replace(/SU/g,"U").replace(/SA/g,"A").replace(/TH/g,"R")
	}
	return s.toUpperCase().replace(/U/g,"Su").replace(/A/g,"Sa").replace(/R/g,"Th")
}

function docwrite(swhat,doheader,options){
	if (!options)options = schedWinOptions
	var s="<html>"+swhat+"</html>"
	var sm=""+Math.random()
	sm=sm.substring(3,10)
	var newwin=open('','MYSCHED_'+sm,options)
	newwin.document.write(s)
	newwin.document.close()
}

function timeof(stime,islate){
	var s=stime.toUpperCase()
	var ispm=(s.indexOf("P")>0)
	var isam=(s.indexOf("A")>0)
	s=s.replace(/[PAM ]/g,"")
	var i=s.indexOf(":")
	if(i<0&&s.length==4){
		isam=(s.charAt(0)=="0")
		s=s.substring(isam?1:0,2)+":"+s.substring(2,4)
	}
	if (s.indexOf(":")<0)s+=":00"
	var S=s.split(":")
	var hh=parseInt(S[0])
	if(hh==12){
		isam=!isam
		ispm=!ispm
	}
	hh+=(!isam && (ispm || hh<firsttime)?12:0)
	hh=(hh-firsttime)*60/slotwidth
	s="1."+S[1]
	var mm=parseFloat(s)-0.9999
	mm-=(islate?0.01:0)
	mm=mm*100/slotwidth
	i=Math.floor(hh+mm)
	if(i<0)i=0
	if(i>=slotsperday)i=slotsperday
	return i
}

function hhmmof(itime){
	var mm=itime*slotwidth 
	var hh=Math.floor(mm/60)
	mm=Math.floor(mm-hh*60) 
	hh+=firsttime
	var ispm=(hh>=12)
	if (hh>12) hh=hh-12
	var smm="00"+mm
	smm=smm.substring(smm.length-2,smm.length)
	return hh+":"+smm+" "+(ispm?"PM":"AM")
}


function getweekcode(dayinfo,timeinfo){
	var sout=""
	var daycode=getdaycode(timeinfo)
	var sdays=getdays(dayinfo)
	for(var i=0;i<ndays;i++)
		sout+=(sdays.indexOf(WEEKDAYS.charAt(i))>=0?daycode:NULLDAY)+"\n"
	return sout
}

function getdays(dayinfo){
	var sdays=fixdays(dayinfo,true)
	var i=sdays.indexOf("-")
	if (i>0){
		var s1=sdays.substring(i-1,i)
		var s2=sdays.substring(i+1,i+2)
		var i1=WEEKDAYS.indexOf(s1)
		var i2=WEEKDAYS.indexOf(s2)
		if(i1>=0 && i2>i1)sdays=s1+WEEKDAYS.substring(i1+1,i2)+s2
	}
	return sdays
}

function getdaycode(timeinfo){
	var i=timeinfo.indexOf("-")
	if(i<=0)return NULLDAY
	var stimes=timeinfo.split("-")
	var itime1=timeof(stimes[0],0)
	var itime2=timeof(stimes[1],1)+1
	if(itime2<=itime1)return NULLDAY
	return NULLDAY.substring(0,itime1)+FULLDAY.substring(itime1,itime2)+NULLDAY.substring(itime2,slotsperday)
}


