// JavaScript Document
// Javascript Website Management System for TEAL courses at MIT
// Michael Danziger, CECI
// Professor Eric Hudson, Physics
// Alan Guth, Physics, modified 10/4/08, with all changes marked with
//    the date.  Further change on 10/9/08, also marked with date.
//
// For documentation, see JavaScriptPreferences.pdf in http://web.mit.edu/8.02t/www/helpfiles/
//
//////////// CONFIGURATION SECTION
// At the start of each semester, these variables must be modified to reflect the dates of that semester
// Note that if the site has been moved from http://web.mit.edu/8.02t/www , you will have to update the link pointers to reflect the new
// location of the website.  
// If you're running Dreamweaver, you can easily do a "Find and Replace" on this file (and the .lbi files -see below), searching on 
// "http://web.mit.edu/8.02t/www" and replacing with the new path
// You will also have to change the static links in the menu libraries (topnav_text.lbi, etc.) and apply those changes to the site.
// If you are preparing a version of this website for 8.02T, you will should also do a "Find and Replace" on all instances of "8.02" and
// replace them with "8.02". 
// Also note that the location of Dave Litster's histograming tools may change as well, in which case the links in the
// "writeDIPLinks()" function must be updated

//////////////////////////////END OF CONFIGURATION SECTION
var presentations = new Array();
var experiments = new Array();
var problemSets = new Array();
var mpProblemSets = new Array();
var InClass = new Array();
var modules = new Array();
var sections = new Array();

// this has to be initialized to something
var HourDelay = 13;	
// The significance of hourDelay was revised 10/4/08 by Alan Guth; now the
// solution links (InClass, Experiments, and PRS) will appear this many
// hours after the start (i.e., 12:00 am) of the day corresponding to the
// current Week/Day combination (e.g., W04D2) for TRF classes.  When set at
// 17, it means that Mon and Tues items will appear at 5 pm Tues, and Wed
// and Thurs items will appear at 5pm on Thurs.  Fri items will appear at
// 5pm on Fri.  Note that the value is also set in ContentAvailable.js, so
// the two values should be identical.

function setHourDelay(delay) {
	HourDelay = delay;
}


function setNumSections(num) {
	numberOfSections = num;
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		problemSets[sectionID] = new Array();
		mpProblemSets[sectionID] = new Array();
	}
}

// NOTE:  Right now, this function formats it's HTML as if it were being called from the same spot it has always been called in
// psets.htm (sitting in an overly complex table).  It should be made more generic so it could be called from anywhere without hosing 
// existing HTML code, but I don't have time to do that right now.
function writePSets(section) {
	var pnum = 1;
	//for (pnum=1;pnum<=NumPSets;pnum++) {
	for (var set in problemSets[section]) {
		if ((pnum % 2)==1) { 
			document.writeln('<tr bgcolor="cccccc">'); 
		} else {
			document.writeln('<tr>');
		}
		// write the left column "Due Date"
        document.writeln('<td height="27" width="29%">');
		document.writeln(problemSets[section][set].DueDateStr());
        document.writeln('</td>');
		// Now make the data column
        document.writeln('<td height="27" width="62%">');
        document.writeln(problemSets[section][set].LoadLine());
		document.writeln('</td>');

		// Finally make the extra columns (why are they there?  who knows?)
		document.writeln('<td height="2" width="5%">&nbsp;</td>');
		document.writeln('<td height="2" width="1%">&nbsp;</td>');
		document.writeln('<td height="2" width="1%">&nbsp;</td>');
		document.writeln('<td height="2" width="2%">&nbsp;</td>');
		document.writeln('</tr>');
		pnum++;
	}
}

// NOTE:  Right now, this function formats it's HTML as if it were being called from the same spot it has always been called in
// psets.htm (sitting in an overly complex table).  It should be made more generic so it could be called from anywhere without hosing 
// existing HTML code, but I don't have time to do that right now.
function writeMPSets(section) {
	var pnum = 1;
	//for (pnum=1;pnum<=NumPSets;pnum++) {
	for (var set in mpProblemSets[section]) {
		if ((pnum % 2)==1) { 
			document.writeln('<tr bgcolor="cccccc">'); 
		} else {
			document.writeln('<tr>');
		}
		// write the left column "Due Date"
        document.writeln('<td height="27" width="29%">');
		document.writeln(mpProblemSets[section][set].DueDateStr());
        document.writeln('</td>');
		// Now make the data column
        document.writeln('<td height="27" width="62%">');
        document.writeln(mpProblemSets[section][set].LoadLine());
		document.writeln('</td>');

		// Finally make the extra columns (why are they there?  who knows?)
		document.writeln('<td height="2" width="5%">&nbsp;</td>');
		document.writeln('<td height="2" width="1%">&nbsp;</td>');
		document.writeln('<td height="2" width="1%">&nbsp;</td>');
		document.writeln('<td height="2" width="2%">&nbsp;</td>');
		document.writeln('</tr>');
		pnum++;
	}
}


function getVarsFromURL() {
	// this returns an array of variables parsed from the URL string
	// variables are passed by appending a "?" to the end of the regular URL followed by a variable name and value in the format:
	// varname=value
	// you can submit multiple variables by separating each variable/value pair with an "&" character.  so, for example:
	// http://www.myhypotheticalpage.com/index.htm?VAR1=i&VAR2=like&VAR3=javascript!!
	// this function will return an array whos elements can be accessed by the variable name.  for example:
	// myArray[VAR1] = i, myArray[VAR2] = like, myArray[VAR3] = javascript!!, etc.
	
	var thisPath = document.location.href;
	var URLvars = thisPath.substring((1 + thisPath.lastIndexOf("?")));
	//alert(URLvars);
	var vars = new Array();
	//alert(URLvars.indexOf("&"));
	if (URLvars.indexOf(";") != -1)
	{
		var varPairs = URLvars.split(';');
		//alert(varPairs);
		
		for (i = 0; i < varPairs.length; i++)
		{
			values = varPairs[i].split('=');
			vars[values[0]] = values[1];
		}
	}
	else
	{
		var pair = URLvars.split('=');
		vars[pair[0]] = pair[1];
	}
	//alert(vars['SEC']);
	return vars;
}

function getMailAddr(email){
	// returns user and domain strings in an array from
	// a qualified internet email address user@domain.
	// if input is only the user part, domain is set to mit.edu

	var addr = new Array();
	if (email.indexOf("@") != -1) {
	    addr = email.split('@');
	} else {
	    addr[0] = email;
	    addr[1] = "mit.edu";
	}
	return addr;
}

function getUser(email){
	// returns user part of user@domain

	var addr = new Array();
	if (email.indexOf("@") != -1) {
	    addr = email.split('@');
	    return addr[0];
	} else {
	    return email;
	}
}

function getSectionFromURL(){
	var URLvars = getVarsFromURL();
	var sec = URLvars["SEC"];
	return sec;
}

function gotoURL(theURL){
	// this will open the URL and append the correct URL vars 
	//alert("gotoURL: " + theURL);
	URLvars = getVarsFromURL();
	URLstring = theURL + "?SEC=" + URLvars["SEC"];
	if (URLvars["TA"]) URLstring += ";TA=" + URLvars["TA"];
	
	document.location = URLstring;
}

function gotoMasteringPhysics() {
	document.location = "http://session.masteringphysics.com/myct?productID=22377";
}

function gotoILT(section) {
	var ILTpaths = new Array();
	//ILTpaths['L01'] = "http://fuschia.mit.edu/ilt/students/?courseID=12";
	//ILTpaths['L02'] = "http://fuschia.mit.edu/ilt/students/?courseID=14";
	//ILTpaths['L03'] = "http://fuschia.mit.edu/ilt/students/?courseID=15";
	//ILTpaths['L04'] = "http://fuschia.mit.edu/ilt/students/?courseID=13";
	//ILTpaths['L05'] = "http://fuschia.mit.edu/ilt/students/?courseID=16";
	//ILTpaths['L06'] = "http://fuschia.mit.edu/ilt/students/?courseID=17";
	//alert("HELLO?");
	ILTpaths['L01'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L02'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L03'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L04'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L05'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L06'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L07'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	ILTpaths['L08'] = "https://gluonsandquarks.mit.edu/grade_management.htm";
	
	document.location = ILTpaths[section];
}

function appendURLString(theString){
	// this writes theString with the URL vars appended
	URLvars = getVarsFromURL();
	URLstring = theURL + "?SEC=" + URLvars["SEC"];
	
	document.write(URLstring);
}

function writeDIPLinks(section) {
	// this writes the links to Dave Litster's data input pages (on experiment page)
	// and the DataStudio "howto" web page
	//alert("writeDIPLinks " + section);
	var basePath = "http://teal-srv.mit.edu/cgi-bin/" ;
	var sectionInt = sectionToInt(section);
	var sectionStr = (sectionInt < 10) ? ("0" + sectionInt) : sectionInt;
	var inputPath = "tealinp.pl?course=8.01;sec=" + sectionStr;
	var getdPath = "listlvdata.pl?course=8.01;sec=" + sectionStr;
	var plotPath = "ins/tealplt.pl?course=8.01;sec=" + sectionStr;
	var aggrPath = "ins/tealagg.pl?course=8.01";
	
	document.writeln('<a href="' + basePath + inputPath + '">Data Input Page</a> (Students)');
	//document.writeln('<br>');
	document.writeln('&nbsp;&nbsp;&nbsp;&nbsp;');
	document.writeln('<a href="' + basePath + plotPath + '">Plotting Page</a> (This Section, Instructors)');
	//document.writeln('<br>');
	document.writeln('&nbsp;&nbsp;&nbsp;&nbsp;');
	document.writeln('<a href="' + basePath + aggrPath + '">Plotting Page</a> (All Sections, Instructors)');
	document.writeln('<br>');
	document.writeln('<center><a href="' + basePath + getdPath + '">List Saved Data</a> (from LabVIEW)</center>');
	
}

function writeMPLinks(){
// This writes the header of the Mastering Physics Page (with links to the mastering physics website)
	document.writeln('<a href="http://www.masteringphysics.com/">Mastering Physics Website</a>;  ');
	document.writeln('<a href="http://web.mit.edu/8.02t/www/materials/Help/MPsignup/mpinfo.pdf">How to Sign Up</a><br>');
}

function appendSectionID(){
	var pageVars = getVarsFromURL();
	var mySec = pageVars["SEC"];
	
	document.write("?SEC=" + mySec);
}

function intToSection(myInt){
	var sectionID;
	sectionID = (myInt < 10) ? ("L0" + myInt) : ("L" + myInt);
	return sectionID;
}

function sectionToInt(section){
	//window.alert("AM I EVEN RUNNING? " + section);
	var secNum;
	secNum = section.substr(1);
	//window.alert(parseInt(10,secNum));
	return parseInt(secNum,10);	
}

function sectionToSchedType(section) {
	// converts a section ID to a schedType ID (ie. "MWF" or "TRF")
	/*if (section == "L01" || section == "L02" || section == "L03") 
	{
		return "MWF";
	}
	else
	{
		return "TRF";
	}*/
	return scheduleMap[section];
}

function splitCommaDelimited(theString) {
	//alert("splitCommaDel " + theString);

	var listArray = theString.split(",");
	return listArray;
}


// Constructor for Section class

function ClassSection(sectionID, sched) {
	
	function Compute_AddInstructor(firstname,lastname,email,contactString) {
		var names = new Array();
		var myaddr = getMailAddr(email);
		var user = myaddr[0];
		names[0] = firstname;
		names[1] = lastname;
		names[2] = myaddr[1];   //domain
		names[3] = contactString;
		this.Instructors[user] = names;
		//var officeHours = new Array();
		//officeHours[0] = officeDay;
		//officeHours[1] = hoursString;
		
		this.RegularOfficeHours[user] = new Array();
		//this.RegularOfficeHours[user].push(officeHours);
		this.SpecialOfficeHours[user] = new Array();
		this.CancelledOfficeHours[user] = new Array();
	}
	
	function Compute_AddGradTA(firstname,lastname,email,contactString) {
		var names = new Array();
		var myaddr = getMailAddr(email);
		var user = myaddr[0];
		names[0] = firstname;
		names[1] = lastname;
		names[2] = myaddr[1];   //domain
		names[3] = contactString;
		this.GradTAs[user] = names;
		//var officeHours = new Array();
		//officeHours[0] = officeDay;
		//officeHours[1] = hoursString;
		
		this.RegularOfficeHours[user] = new Array();
		//this.RegularOfficeHours[user].push(officeHours);
		this.SpecialOfficeHours[user] = new Array();
		this.CancelledOfficeHours[user] = new Array();
	}
	
	function Compute_AddUGradTA(firstname,lastname,email,contactString) {
		var names = new Array();
		var myaddr = getMailAddr(email);
		var user = myaddr[0];
		names[0] = firstname;
		names[1] = lastname;
		names[2] = myaddr[1];   //domain
		names[3] = contactString;
		this.UGradTAs[user] = names;
		//var officeHours = new Array();
		//officeHours[0] = officeDay;
		//officeHours[1] = hoursString;
		
		this.RegularOfficeHours[user] = new Array();
		//this.RegularOfficeHours[user].push(officeHours);
		this.SpecialOfficeHours[user] = new Array();
		this.CancelledOfficeHours[user] = new Array();
	}
	
	function Compute_AddDemoGroup(firstname,lastname,email,contactString) {
		var names = new Array();
		var myaddr = getMailAddr(email);
		var user = myaddr[0];
		names[0] = firstname;
		names[1] = lastname;

		names[2] = myaddr[1];   //domain
		names[3] = contactString;
		this.DemoGroup[user] = names;
		//var officeHours = new Array();
		//officeHours[0] = officeDay;
		//officeHours[1] = hoursString;
		
		this.RegularOfficeHours[user] = new Array();
		//this.RegularOfficeHours[user].push(officeHours);
		this.SpecialOfficeHours[user] = new Array();
		this.CancelledOfficeHours[user] = new Array();
	}
	
	function Compute_AddRegularOfficeHours(email,officeDay,hoursString) {
		var specialOH = new Array();
		var user = getUser(email);
		
		specialOH[0] = officeDay;
		specialOH[1] = hoursString;
		specialOH[2] = '<font color="red"><b>Cancelled.</b></font>';
		
		this.RegularOfficeHours[user].push(specialOH);
	}
	
	function Compute_AddSpecialOfficeHours(email,month,date,year,hoursString) {
		//alert("AddSpecialOfficeHours");
		var specialOH = new Array();
		var user = getUser(email);
		var theDate = new Date(year, month, date);
		specialOH[0] = theDate;
		specialOH[1] = hoursString;
		specialOH[2] = '<font color="red"><b>Cancelled.</b></font>';
		
		this.SpecialOfficeHours[user].push(specialOH);
	}
	
	function Compute_CancelOfficeHours(email,month,date,year) {
		//alert("AddSpecialOfficeHours");
		var specialOH = new Array();
		var user = getUser(email);
		var theDate = new Date(year, month, date);
		//specialOH[0] = theDate;
		//specialOH[1] = hoursString;
		
		this.CancelledOfficeHours[user].push(theDate);
	}
	
	function Compute_WriteList() {
		document.writeln("<h1>Instructors:</h1>");
		for (var inst in this.Instructors) {
			if (inst != "Staff") {
				var contact = (this.Instructors[inst][3] != undefined) ? ", " + this.Instructors[inst][3] : "";
				var email = inst + "@" + this.Instructors[inst][2];
				document.writeln(this.Instructors[inst][0] + " " + this.Instructors[inst][1] + ' (<a href="mailto:' + email + '">' + email + "</a>)" + contact + "<br>");
				//var contact = (this.Instructors[inst][2] != undefined) ? ", " + this.Instructors[inst][2] : "";
				//var contact = "";
				//document.writeln(this.Instructors[inst][0] + " " + this.Instructors[inst][1] + ' (<a href="mailto:' + inst + '@mit.edu">' + inst + "@mit.edu</a>)" + contact + "<br>");
			}
		}
		//document.writeln("<br><br>");
		document.writeln("<br>");
		document.writeln("<h1>Graduate TAs:</h1>");
		for (var inst in this.GradTAs) {
			var contact = (this.GradTAs[inst][3] != undefined) ? ", " + this.GradTAs[inst][3] : "";
			var email = inst + "@" + this.GradTAs[inst][2];
			document.writeln(this.GradTAs[inst][0] + " " + this.GradTAs[inst][1] + ' (<a href="mailto:' + email + '">' + email + "</a>)" + contact + "<br>");
			//var contact = (this.GradTAs[inst][2] != undefined) ? ", " + this.GradTAs[inst][2] : "";
			//var contact = "";
			//document.writeln(this.GradTAs[inst][0] + " " + this.GradTAs[inst][1]+  ' (<a href="mailto:' + inst + '@mit.edu">' + inst + "@mit.edu</a>)" + contact + "<br>");
		}
		//document.writeln("<br><br>");
		document.writeln("<br>");
		document.writeln("<h1>Undergraduate TAs:</h1>");
		for (var inst in this.UGradTAs) {
			var contact = (this.UGradTAs[inst][3] != undefined) ? ", " + this.UGradTAs[inst][3] : "";
			var email = inst + "@" + this.UGradTAs[inst][2];
			document.writeln(this.UGradTAs[inst][0] + " " + this.UGradTAs[inst][1] + ' (<a href="mailto:' + email + '">' + email + "</a>)" + contact + "<br>");
			//var contact = (this.UGradTAs[inst][2] != undefined) ? ", " + this.UGradTAs[inst][2] : "";
			//var contact = "";
			//document.writeln(this.UGradTAs[inst][0] + " " + this.UGradTAs[inst][1] + ' (<a href="mailto:' + inst + '@mit.edu">' + inst + "@mit.edu</a>)" + contact + "<br>");
		}
		//document.writeln("<br><br>");
		document.writeln("<br>");
		document.writeln("<h1>Technical Instructors:</h1>");
		for (var inst in this.DemoGroup) {
			var contact = (this.DemoGroup[inst][3] != undefined) ? ", " + this.DemoGroup[inst][3] : "";
			var email = inst + "@" + this.DemoGroup[inst][2];
			document.writeln(this.DemoGroup[inst][0] + " " + this.DemoGroup[inst][1] + ' (<a href="mailto:' + email + '">' + email + "</a>)" + contact + "<br>");
			//var contact = (this.DemoGroup[inst][2] != undefined) ? ", " + this.DemoGroup[inst][2] : "";
			//var contact = "";
			//document.writeln(this.DemoGroup[inst][0] + " " + this.DemoGroup[inst][1] + ' (<a href="mailto:' + inst + '@mit.edu">' + inst + "@mit.edu</a>)" + contact + "<br>");
		}
		//document.writeln("<br><br>");
		document.writeln("<br>");
	}
	
	function Compute_getLastNameFromHandle(handle) {
		var myName;
		for (var inst in this.Instructors){
			if (inst == handle) {
				myName = this.Instructors[inst][1];
			}
		}
		for (var inst in this.GradTAs){
			if (inst == handle) {
				myName = this.GradTAs[inst][1];
			}
		}
		for (var inst in this.UGradTAs){
			if (inst == handle) {
				myName = this.UGradTAs[inst][1];
			}
		}
		for (var inst in this.DemoGroup){
			if (inst == handle) {
				myName = this.DemoGroup[inst][1];
			}
		}
		return myName;
	}
	

	function Compute_CheckCancelledHours(handle,date) {
		var bCancelled = false
		if (this.CancelledOfficeHours[handle].length > 0) {
		for (var i = 0; i<this.CancelledOfficeHours[handle].length; i++) {
			if (this.CancelledOfficeHours[handle][i].getTime() == date.getTime()) {
				bCancelled = true
			}
		}
		}
		return bCancelled;
	}
		
	
	function Compute_WriteRegularOfficeHours(date) {
		for (var inst in this.RegularOfficeHours) {
			if (this.RegularOfficeHours[inst].length > 0) {
				for (var num in this.RegularOfficeHours[inst]) {
					if (this.RegularOfficeHours[inst][num][0] == date.getDay()) {
						var thename = this.getLastNameFromHandle(inst); 
						var x = (this.CheckCancelledHours(inst,date) == true) ? (2) : (1);
						if (inst == "Staff") {
							document.writeln("Staff: " + this.RegularOfficeHours[inst][num][x] + "<br>");
						}
						else {
							// hack... looking at this now, we shouldn't keep seperate arrays for Instructors/GradTAs/etc.
							// instead have one array, and add a flag to the "info" array that indicates what type of person it is.
							var email = null;
							for (var people in this.Instructors) {
								if (people == inst) {
									email = inst + "@" + this.Instructors[inst][2];
								}
							}
							for (var people in this.GradTAs) {
								if (people == inst) {
									email = inst + "@" + this.GradTAs[inst][2];
								}
							}
							//var email = inst + "@" + this.Instructors[inst][2];
							document.writeln('<a href="mailto:' + email +'">' + thename + "</a>: " + this.RegularOfficeHours[inst][num][x] + "<br>");
						}
						document.writeln("<br>");
					}
				}
			}
		}
	}
	
	function Compute_WriteSpecialOfficeHours(date) {
		//alert("WriteSpecialOfficeHours");
		for (var inst in this.SpecialOfficeHours) {
			if (this.SpecialOfficeHours[inst].length > 0) {
				for (var num in this.SpecialOfficeHours[inst]) {
					if (this.SpecialOfficeHours[inst][num][0].getTime() == date.getTime()) {
						var thename = this.getLastNameFromHandle(inst); 
						document.writeln("<b>Special Office Hours:</b><br>");
						//alert(this.SpecialOfficeHours[inst]);
						if (inst == "Staff") {
							document.writeln("Staff: " + this.SpecialOfficeHours[inst][num][1] + "<br>");
						}
						else {
							// hack... looking at this now, we shouldn't keep seperate arrays for Instructors/GradTAs/etc.
							// instead have one array, and add a flag to the "info" array that indicates what type of person it is.
							var email = null;
							for (var people in this.Instructors) {
								if (people == inst) {
									email = inst + "@" + this.Instructors[inst][2];
								}
							}
							for (var people in this.GradTAs) {
								if (people == inst) {
									email = inst + "@" + this.GradTAs[inst][2];
								}
							}
							
							//var email = inst + "@" + this.Instructor[inst][2];
							document.writeln('<a href="mailto:' + email +'">' + thename + "</a>: " + this.SpecialOfficeHours[inst][num][1] + "<br>");
						}
						document.writeln("<br>");
					}
				}
			}
		}
	}
			
	
	this.section = sectionID;
	this.schedType = sched;
	
	this.Instructors = new Array();
	this.GradTAs = new Array();
	this.UGradTAs = new Array();
	this.DemoGroup = new Array();
	
	this.RegularOfficeHours = new Array();
	this.SpecialOfficeHours = new Array();
	this.CancelledOfficeHours = new Array();
	
	this.AddInstructor = Compute_AddInstructor;
	this.AddGradTA = Compute_AddGradTA;
	this.AddUGradTA = Compute_AddUGradTA;
	this.AddDemoGroup = Compute_AddDemoGroup;
	this.AddRegularOfficeHours = Compute_AddRegularOfficeHours;
	this.AddSpecialOfficeHours = Compute_AddSpecialOfficeHours;

	this.CancelOfficeHours = Compute_CancelOfficeHours;
	this.WriteList = Compute_WriteList;
	this.getLastNameFromHandle = Compute_getLastNameFromHandle;
	this.WriteRegularOfficeHours = Compute_WriteRegularOfficeHours;
	this.WriteSpecialOfficeHours = Compute_WriteSpecialOfficeHours;
	this.CheckCancelledHours = Compute_CheckCancelledHours;
	
}
		

// Constructor for module class
function ClassModule(title,module) {
	function Compute_AddPresentation(day) {
		this.NPresentation++;
		this.Presentation[this.NPresentation] = day;
	}
	function Compute_AddInClass(section,day,num) {
		//(this.module == 2) ? alert("Computer_AddInClass(" + section + "," + day + "," + num + ")") : false;
		if (section == "DEFAULT")
		{
			for (var sections in this.NInClass)
			{
				if (sections != "DEFAULT")
				{
					this.NInClass[sections]++;
					this.InClass[sections][this.NInClass[sections]] = day+":"+num
					//this.InClass[sections].push(day+":"+num);

				}
			}
		}
		else 
		{
			this.NInClass[section]++;
			this.InClass[section][this.NInClass[section]] = day+":"+num;
			//this.InClass[(section)].push(day+":"+num);
		}
	}
	/*
	function Compute_AddExperiment(day,num) {
		this.NExperiment++;
		this.Experiment[this.NExperiment] = day+":"+num;
	}
	*/
	function Compute_AddExperiment(section,day,num) {
		//(this.module == 2) ? alert("Computer_AddInClass(" + section + "," + day + "," + num + ")") : false;
		if (section == "DEFAULT")
		{
			for (var sections in this.NInClass)
			{
				if (sections != "DEFAULT")
				{
					this.NExperiment[sections]++;
					this.Experiment[sections][this.NExperiment[sections]] = day+":"+num
					//this.InClass[sections].push(day+":"+num);

				}
			}
		}
		else 
		{
			this.NExperiment[section]++;
			this.Experiment[section][this.NExperiment[section]] = day+":"+num;
			//this.InClass[(section)].push(day+":"+num);
		}
	}
	function Compute_AddPSet(section,num) {
		this.NPSet[section]++;
		this.PSet[section][this.NPSet[section]] = num;
	}
	function Compute_AddMPPSet(section,num) {
		//alert("adding MPPSet to module");
		this.NMPPSet[section]++;
		this.MPPSet[section][this.NMPPSet[section]] = num;
	}
	function Compute_ModStr() {
		return ZeroPad(this.module);
	}
	/*
	function Compute_WriteExperiments() { // This routine creates a list of all experiments that fall under this module
		if (this.NExperiment > 0) {
			for (i=1;i<=this.NExperiment;i++) {
				day = this.Experiment[i].substr(0,5);
				num = this.Experiment[i].substr(6,8);
				document.writeln(experiments[day].Experiments[num].WriteupLine()+"<br>");
			}
		}
	}
	*/
	function Compute_WriteExperiments(section) { // This routine creates a list of all in class problems that fall under this module
		//alert("Computer_WriteInClass(" + section + ") " + this.NInClass[section] + this.module + " " + this.InClass[section]);
		
		if (this.NExperiment[section] > 0) {
			for (i=1;i<=this.NExperiment[section];i++) {
				day = this.Experiment[section][i].substr(0,5);
				//alert("this.NInClass: " + this.NInClass[section] + " day: " + day + " num: " + this.InClass[section][i].substr(6,8) + " sec: " + section + " InClass[day]: " + InClass[day][section]);
				num = this.Experiment[section][i].substr(6,8);
				if (experiments[day].Experiment[section][num].title != "") {
					weekDay = ShortStringToWeekDay(day,getSchedType(section));
					theDate = weekDay.GetDate();
					displayDate = ZeroPad(theDate.getMonth()+ 1) + "/" + ZeroPad(theDate.getDate()) + "/" + theDate.getFullYear();
					document.writeln(displayDate+": ");
					document.writeln(experiments[day].Experiment[section][num].WriteupLine()+"<br>");
				}
			}
		}
	}
	function Compute_WriteInClass(section) { // This routine creates a list of all in class problems that fall under this module
		//alert("Computer_WriteInClass(" + section + ") " + this.NInClass[section] + this.module + " " + this.InClass[section]);
		
		if (this.NInClass[section] > 0) {
			for (i=1;i<=this.NInClass[section];i++) {
				day = this.InClass[section][i].substr(0,5);
				//alert("this.NInClass: " + this.NInClass[section] + " day: " + day + " num: " + this.InClass[section][i].substr(6,8) + " sec: " + section + " InClass[day]: " + InClass[day][section]);
				num = this.InClass[section][i].substr(6,8);
				if (InClass[day].InClass[section][num].title != "") {
					weekDay = ShortStringToWeekDay(day,getSchedType(section));
					theDate = weekDay.GetDate();
					displayDate = ZeroPad(theDate.getMonth()+ 1) + "/" + ZeroPad(theDate.getDate()) + "/" + theDate.getFullYear();
					document.writeln(displayDate+": ");
					document.writeln(InClass[day].InClass[section][num].WriteupLine()+"<br>");
				}
			}
		}
	}
	function Compute_WriteList(section) {	// This routine creates a list of all course elements that fall under this module
		//alert("Computer_WriteList(" + section + ")");
// Study Guide
		//document.writeln('<b>Course Notes:</b> <a href="../../materials/modules/guide' + this.ModStr() + '.pdf">Course Notes</a>');
		//document.writeln('<br>');
//		document.writeln('There are '+this.NPresentation+' presentations<br>');
		document.writeln('<b>Presentations:</b> ');
		document.writeln('<br>');

// Presentations
		for (var days in presentations) {
			var addPres = false;
			var mods = splitCommaDelimited(presentations[days].modules[section]);
			for (var i = 0; i<mods.length;i++) {
				if (mods[i] == this.module) {addPres = true;}
			}
			if (addPres == true) {
				document.writeln(presentations[days].LoadLine(section) + "<br>");
			}
		}
		//if (this.NPresentation > 0) {
		//	document.writeln("<br><b>Presentations:</b><br>");
		//	for (var i=1;i<=this.NPresentation;i++) {
		//		document.writeln(presentations[this.Presentation[i]].LoadLine(section)+"<br>");
		//	}
		//}
// Problem Solving
		// Lame hack to make the In Class label not show if an InClass problem exists, but has been modified such that its title = ""
		var icDeleted = 0;
		for (var j=1; j<=this.NInClass[section];j++) {
			day = this.InClass[section][j].substr(0,5);
			num = this.InClass[section][j].substr(6,8);
			if (InClass[day].InClass[section][num].title == "") icDeleted++;
		}
		var icN = this.NInClass[section] - icDeleted;
		if (icN > 0) {
			document.writeln("<br><b>In Class Problem Solving:</b><br>");
			for (var i=1;i<=this.NInClass[section];i++) {
				day = this.InClass[section][i].substr(0,5);
				num = this.InClass[section][i].substr(6,8);
				if (InClass[day].InClass[section][num].title != "") document.writeln(InClass[day].InClass[section][num].LoadLine()+"<br>");
			}
		}
// Experiments
		// Lame hack to make the Experiments label not show if an experiment exists, but has been modified such that its title = ""
		var expDeleted = 0;
		for (var j=1; j<=this.NExperiment[section];j++) {
			day = this.Experiment[section][j].substr(0,5);
			num = this.Experiment[section][j].substr(6,8);
			if (experiments[day].Experiment[section][num].title == "") expDeleted++;
		}
		var expN = this.NExperiment[section] - expDeleted;
		if (expN > 0) {
			document.writeln("<br><b>Experiments:</b><br>");
			for (var i=1;i<=this.NExperiment[section];i++) {
				day = this.Experiment[section][i].substr(0,5);
				num = this.Experiment[section][i].substr(6,8);
				if (experiments[day].Experiment[section][num].title != "") document.writeln(experiments[day].Experiment[section][num].LoadLine()+"<br>");
			}
		}
// Problem Sets		
		if (this.NPSet[section] > 0) {
			document.writeln("<br><b>Problem Sets:</b><br>");
			for (var i=1;i<=this.NPSet[section];i++) {
				document.writeln(problemSets[section][this.PSet[section][i]].LoadLine()+"<br>");
			}
		}
		//Mastering Physics Problem Sets		
		if (this.NMPPSet[section] > 0) {
			document.writeln("<br><b>Mastering Physics Problem Sets:</b><br>");
			for (var i=1;i<=this.NMPPSet[section];i++) {
				document.writeln(mpProblemSets[section][this.MPPSet[section][i]].LoadLine()+"<br>");
			}
		}
		document.writeln("<br>");
	}
	this.title = title;
	this.module = module;
	this.NPresentation = 0;
	this.Presentation = new Array();
	this.NInClass = new Array();
	this.NInClass["DEFAULT"] = 0;
	this.NExperiment = new Array();
	this.NExperiment["DEFAULT"] = 0;
	
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.NInClass[sectionID] = 0;
		this.NExperiment[sectionID] = 0;
		//alert(sectionID);
	}
	
	this.InClass = new Array();
	this.InClass["DEFAULT"] = new Array();
	this.Experiment = new Array();
	this.Experiment["DEFAULT"] = new Array();
	
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.InClass[sectionID] = new Array();
		this.Experiment[sectionID] = new Array();
		//alert(sectionID);
	}
	
	//this.NExperiment = 0;
	//this.Experiment = new Array();
	//this.NPSet = 0;
	this.NPSet = new Array();
	this.PSet = new Array();
	this.NMPPSet = new Array(); //0;
	this.MPPSet = new Array();
	
	for (var i = 1; i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.NPSet[sectionID] = 0;
		this.PSet[sectionID] = new Array();
		this.NMPPSet[sectionID] = 0;
		this.MPPSet[sectionID] = new Array();
	}
	
	this.AddPresentation = Compute_AddPresentation;
	this.AddInClass = Compute_AddInClass;
	this.AddExperiment = Compute_AddExperiment;
	this.AddPSet = Compute_AddPSet;
	this.AddMPPSet = Compute_AddMPPSet;
	this.ModStr = Compute_ModStr;
	this.WriteExperiments = Compute_WriteExperiments;
	this.WriteInClass = Compute_WriteInClass;
	this.WriteList = Compute_WriteList;
	return this;
}


// Constructor for Presentation class
function ClassPresentation(day,title,shortTitle,module,info,PresAvail,PRSAvail,QAAvail,SumAvail) {
	
	var DEFAULT = "DEFAULT";
	
	function Compute_LoadLine(section) {
	//alert("Compute_LoadLine");
		var str;
		var bPA;
		var bQA;
		var bPRS;
		var bSum;
		//alert("LoadLine: " + section);
		(this.title[section] != null) ? (str = this.title[section] + ": " + this.shortTitle[section]) : (str = this.title[DEFAULT] + ": " + this.shortTitle[DEFAULT]);
		(this.PresAvail[section] != null) ? (bPA = this.PresAvail[section]) : (bPA = this.PresAvail["DEFAULT"]);
		(this.QAAvail[section] != null) ? (bQA = this.QAAvail[section]) : (bQA = this.QAAvail["DEFAULT"]);
		(this.PRSAvail[section] != null) ? (bPRS = this.PRSAvail[section]) : (bPRS = this.PRSAvail["DEFAULT"]);
		(this.SumAvail[section] != null) ? (bSum = this.SumAvail[section]) : (bSum = this.SumAvail[DEFAULT]);
		var presSection = (this.PresAvail[section] == null) ? ("DEFAULT") : section;
		var QASection = (this.QAAvail[section] == null) ? ("DEFAULT") : section;
		var PRSSection = (this.PRSAvail[section] == null) ? ("DEFAULT") : section;
		var SumSection = (this.SumAvail[section] == null) ? ("DEFAULT") : section;
		//var str = title + ": " + shortTitle;
		//var bPA = this.PresAvail[section];
		//var bQA = this.QAAvail;
		//var bPRS = this.PRSAvail;
		//alert("LoadLine: bPA = " + bPA + ", bQA = " +bQA + ", bPRS = " + bPRS);
		//str+="LoadLine: bPA = " + bPA + ", bQA = " +bQA + ", bPRS = " + bPRS+':  ';
		if (bPA >= 1 || bQA == 1 || bPRS >= 1 || bSum == 1) {
			str += ": ("
			// Take out PPT now, they shouldn't need it anymore EWH 9/10/07
			////'<a href="'+linkSpecificPPT(presSection,this.day)+'">PPT</a>, ' +
			if (bPA) str += '<a href="'+linkSpecificPresentationHTML(presSection,this.day)+'">PDF (Viewing)</a>, ' +
							'<a href="'+linkSpecificPresentationPDF(presSection,this.day)+'">PDF (Printing)</a>';

			if (bPA >= 1 && (bQA == 1 || bPRS >= 1 || bSum == 1)) str += ", " ;
			if (bQA == 1) str += '<a href="'+linkSpecificQA(QASection,this.day)+'">Q&A</a>';

			if (bQA == 1 && (bPRS >= 1 || bSum == 1)) str += ", "
			//--------> Timed release of PRS
			var weekDay = ShortStringToWeekDay(this.day,"TRF");
			// Above line modified 10/4/08 by Alan Guth, replacing
			//    getSchedType(section) by "TRF".  The goal of the change 
			//    is to time the release of all solutions from the TRF
			//    classes. 
			var theDate = weekDay.GetDate();
			var today = new Date();
			//var hourDelay = 0;
			//alert("HourDelay" +hourDelay);
			//alert("Check Date: "+ today.getTime() + " " + theDate.getTime() + (1000*60*60*hourDelay)); // today.toString());
			
			if (bPRS==2 || (bPRS == 1 && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay)))) 
				str += '<a href="'+linkSpecificPRS(PRSSection,this.day)+'">PRS</a>';
			if ((bPRS==2 || (bPRS == 1 && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay)))) && bSum == 1) str += ", ";
			if (bSum == 1) str += '<a href="'+linkSpecificPresSummary(SumSection,this.day)+'">Summary</a>';
			str += ")"
		}
		return str;
	}
	
	// ModifyData will be used set data in the arrays below
	function Compute_ModifyData(section,day,title,shortTitle,module,info,PresAvail,PRSAvail,QAAvail,SumAvail){
		// do nothing with day or module for now
		this.title[section] = (title == null) ? this.title["DEFAULT"] : title;
		this.shortTitle[section] = (shortTitle == null) ? this.shortTitle["DEFAULT"] : shortTitle;
		this.info[section] = (info == null) ? this.info["DEFAULT"] : info;
		this.modules[section] = (module == null) ? this.modules["DEFAULT"] : module;
		this.PresAvail[section] = PresAvail;
		this.PRSAvail[section] = PRSAvail;
		this.QAAvail[section] = QAAvail;
		this.SumAvail[section] = SumAvail;
	}
	
	function Compute_InfoString(section) {
		//var str;
		var bPA;
		var bQA;
		var bPRS;
		var bSum;
		//alert("LoadLine: " + section);
		//(this.title[section] != null) ? (str = this.title[section] + ": " + this.shortTitle[section]) : (str = this.title[DEFAULT] + ": " + this.shortTitle[DEFAULT]);
		(this.PresAvail[section] != null) ? (bPA = this.PresAvail[section]) : (bPA = this.PresAvail[DEFAULT]);
		(this.QAAvail[section] != null) ? (bQA = this.QAAvail[section]) : (bQA = this.QAAvail[DEFAULT]);
		(this.PRSAvail[section] != null) ? (bPRS = this.PRSAvail[section]) : (bPRS = this.PRSAvail[DEFAULT]);
		(this.SumAvail[section] != null) ? (bSum = this.SumAvail[section]) : (bSum = this.SumAvail[DEFAULT]);
		var presSection = (this.PresAvail[section] == null) ? ("DEFAULT") : section;
		var QASection = (this.QAAvail[section] == null) ? ("DEFAULT") : section;
		var PRSSection = (this.PRSAvail[section] == null) ? ("DEFAULT") : section;
		var SumSection = (this.SumAvail[section] == null) ? ("DEFAULT") : section;
		
		var text = "Section " + '<a href="javascript:gotoClassPage(' + "'" + section + "'" + "," + "'"+ this.day + "'" +  ')">' + section + '</a> ' + " is using ";
		if ((presSection == "DEFAULT") && (QASection == "DEFAULT") && (PRSSection == "DEFAULT") && (SumSection == "DEFAULT")) {
			text += "the default presentation materials.";
		} else {
			// check presentation
			if (presSection == "DEFAULT") {
				text += "the default presentation, ";
			} else if ((presSection != "DEFAULT") && (bPA == 0)) {
				text += "no presentation, ";
			} else if ((presSection != "DEFAULT") && (bPA == 1)) {
				var linktext = 'a <a href="'+linkSpecificPPT(presSection,this.day)+'">modified presentation</a>, ';
				text += linktext;
			}
			// check PRS
			if (PRSSection == "DEFAULT") {
				text += "the default PRS, ";
			} else if ((PRSSection != "DEFAULT") && (bPRS == 0)) {
				text += "no PRS, ";
			} else if ((PRSSection != "DEFAULT") && (bPRS == 1)) {
				var linktext = '<a href="'+linkSpecificPRS(PRSSection,this.day)+'">modified PRS</a>, ';
				text += linktext;
			}
			// check QA
			if (QASection == "DEFAULT") {
				text += "the default QA, ";
			} else if ((QASection != "DEFAULT") && (bQA == 0)) {
				text += "no QA, ";
			} else if ((QASection != "DEFAULT") && (bQA == 1)) {
				var linktext = '<a href="'+linkSpecificQA(QASection,this.day)+'">modified QA</a>, ';
				text += linktext;
			}
			// check summary
			if (SumSection == "DEFAULT") {
				text += "and the default summary.";
			} else if ((SumSection != "DEFAULT") && (bSum == 0)) {
				text += "and no summary.";
			} else if ((SumSection != "DEFAULT") && (bSum == 1)) {
				var linktext = 'and a <a href="'+linkSpecificPresSummary(SumSection,this.day)+'">modified summary</a>.';
				text += linktext;
			}
		}
		return text;
		
	}
		
	
	
	this.day = day;
	// title array
	this.title = new Array();
	this.title[DEFAULT] = title;
	
	this.shortTitle = new Array();
	this.shortTitle[DEFAULT] = shortTitle;
	
	this.module = module;
	this.modules = new Array();
	this.modules[DEFAULT] = module;
	// info array
	this.info = new Array();
	this.info[DEFAULT] = info;
	
	// PresAvail array
	this.PresAvail = new Array();
	this.PresAvail[DEFAULT] = PresAvail;
	
	// PRSAvail array
	this.PRSAvail = new Array();
	this.PRSAvail[DEFAULT] = PRSAvail;
	
	// QAAvail array
	this.QAAvail = new Array();
	this.QAAvail[DEFAULT] = QAAvail;
	
	// SUMMARY array
	this.SumAvail = new Array();
	this.SumAvail[DEFAULT] = SumAvail;
	
	//Populate based on the number of sections
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.title[sectionID] = null;
		this.shortTitle[sectionID] = null;
		this.info[sectionID] = null;
		this.PresAvail[sectionID] = null;
		this.PRSAvail[sectionID] = null;
		this.QAAvail[sectionID] = null;
		this.SumAvail[sectionID] = null;
		this.modules[sectionID] = module;
		//alert(sectionID);
	}
	
	this.ModifyData = Compute_ModifyData;
	this.LoadLine = Compute_LoadLine;
	this.InfoString = Compute_InfoString;
	return this;
}


// Constructor for Problem Set
function ClassProblemSet(dueTime,number,dueDate,module,qAvail,sAvail) {
	function Compute_LoadLine() {
		var str = "";
		var Path = "../../materials/ProblemSets/ps" + ZeroPad(this.number);

		var bq = qAvail;
		var bsol = sAvail;
		var URLVars = getVarsFromURL();
		var bTA = URLVars["TA"];
		var taPath = "";
		if (bTA)
		{
			var loc = String(document.location);
			taPath = loc.substring(0, loc.lastIndexOf("/"));
			taPath = taPath.substring(0, taPath.lastIndexOf("/"));
			taPath = taPath.substring(0, taPath.lastIndexOf("/"));
			taPath += "/materials/ProblemSets/Raw/ps" + ZeroPad(this.number);
			taPath = taPath.replace("http","https");
		}
		
		if (bq) str += '<a href="' + Path + '.pdf">'; else if (bTA) str += '<a href="'+ taPath + '.pdf">Unposted ';
		
		str += 'Problem Set ' + ZeroPad(this.number);
		if (bq || bTA) str += '</a>';

		if (bsol) str += ' (<a href="' + Path + 'sol.pdf">Solutions</a>)'; else if (bTA) str += ' (<a href="' + taPath + 'sol.pdf">Unposted Solutions</a>)';
		return str;
	}
	function Compute_DueDateStr() {
		var str = "Due " + this.dueDate.getCalendarDay() + " " + this.dueDate.getAbbrevCalendarMonth() + " " + this.dueDate.getDate();
		str += ", " + this.dueTime; //4:15 pm";

		return str;
	}
	this.number = number;
	this.dueDate = dueDate;
	this.dueTime = dueTime;
	this.module = module;
	this.qAvail = qAvail;
	this.sAvail = sAvail;
	this.LoadLine = Compute_LoadLine;
	this.DueDateStr = Compute_DueDateStr;
	return this;
}



// Constructor for Mastering Physics problem sets
function ClassMPProblemSet(dueTime,number,dueDate,module,qAvail,sAvail) {
	function Compute_LoadLine() {
		var str = "";
		var Path = "http://web.mit.edu/8.01t/www/materials/MasteringPhysics/mp" + ZeroPad(this.number);

		var bq = qAvail;
		var bsol = sAvail;
		
		//if (bq) str += '<a href="' + Path + '.pdf">'
		str += 'Mastering Physics Assignment ' + ZeroPad(this.number);
		//if (bq) str += '</a>';

		//if (bsol) str += ' (<a href="' + Path + 'sol.pdf">Solutions</a>)';
		return str;
	}
	function Compute_DueDateStr() {
		var str = "Due " + this.dueDate.getCalendarDay() + " " + this.dueDate.getAbbrevCalendarMonth() + " " + this.dueDate.getDate();
		str += ", " + this.dueTime;
		return str;
	}
	this.number = number;
	this.dueDate = dueDate;
	this.dueTime = dueTime;
	this.module = module;
	this.qAvail = qAvail;
	this.sAvail = sAvail;
	this.LoadLine = Compute_LoadLine;
	this.DueDateStr = Compute_DueDateStr;
	return this;
}


// Constructor for Experiment class

function ClassExperiment(day,title,module,writeup,datastudio,excel,solution,info) {
	function Compute_LoadLine() {
		var str = this.title;
		var bw = this.writeup != "";
		var bds = this.datastudio != "";
		var bex = this.excel != "";
		var bsol = this.solution != "";
		if (bw || bds || bwx || bsol) {
			str += ": ("
			if (bw) str += '<a href="' + this.writeup + '">Writeup</a>';
			if (bw && (bds || bex || bsol)) str += ", ";
			if (bds) str += '<a href="' + this.datastudio + '">LabVIEW</a>';
			//if (bds && (bex || bsol)) str += ", ";
			//if (bex) str += ', <a href="' + this.excel + '">Example</a>';
			//if (bex && bsol) str += ", ";
			//if (bsol) str += '<a href="' + this.solution + '">Report</a>';
			
			var URLvars = getVarsFromURL();
		var today = new Date();
		var myDate = ShortStringToWeekDay(this.day,"TRF");
		// Above line modified 10/4/08 by Alan Guth, replacing
		//    sectionToSchedType(URLvars["SEC"]) by "TRF".  The goal of
		//    the change is to time the release of all solutions from the
		//    TRF classes. 
		var theDate = myDate.GetDate();
		var solstring = ((today.getTime() < theDate.getTime() + (1000*60*60*hourDelay)) && URLvars["TA"]) ? "Unposted Solution" : "Solution";
		var solPath = this.solution;
			if (URLvars["TA"]) {
				var slash = this.solution.lastIndexOf("/");
				var filename = this.solution.substring(slash+1, this.solution.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name;
				var tapath = this.solution.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				solPath = tapath.replace("http", "https");
			}	
		if (bsol && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay) || URLvars["TA"])) str += ', <a href="' + solPath + '">' + solstring + '</a>';
			str += ") ";
		
			
			//str += ") ";
			
			//var URLvars = getVarsFromURL();
			if (URLvars["TA"]) {
				var slash = this.writeup.lastIndexOf("/");
				var filename = this.writeup.substring(slash+1, this.writeup.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name += "_TA";
				var tapath = this.writeup.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				tapath = tapath.replace("http", "https");
				//Teahing summary for labs not currently implemented
				//str += ', <a href="' + tapath + '">Teacher Summary</font></a>';
			}
			
			
		}
		return str;
	}
	function Compute_WriteupLine() {
		strInfo = this.title.split(":");	// split into "Experiment #:" and "Experiment Title"
		if (!strInfo[1]) strInfo[1] = strInfo[0];
		var str = strInfo[0]+":";
		var bw = this.writeup != "";
		var bsol = this.solution != "";
		if (bw) str += '<a href="' + this.writeup + '">'
		str += strInfo[1];
		if (bw) str += '</a>';
		//if (bsol) str += ' (<a href="' + this.solution + '">Report</a>) ';
		var URLvars = getVarsFromURL();
		var today = new Date();
		var myDate = ShortStringToWeekDay(this.day,"TRF");
		// Above line modified 10/4/08 by Alan Guth, replacing
		//    sectionToSchedType(URLvars["SEC"]) by "TRF".  The goal of
		//    the change is to time the release of all solutions from the
		//    TRF classes. 
		var theDate = myDate.GetDate();
		var solstring = ((today.getTime() < theDate.getTime() + (1000*60*60*hourDelay)) && URLvars["TA"]) ? "Unposted Solution" : "Solution";
		var solPath = this.solution;
			if (URLvars["TA"]) {
				var slash = this.solution.lastIndexOf("/");
				var filename = this.solution.substring(slash+1, this.solution.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name;
				var tapath = this.solution.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				solPath = tapath.replace("http", "https");
			}	
		if (bsol && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay) || URLvars["TA"])) str += ' (<a href="' + solPath + '">' + solstring + '</a>) ';
			//str += ") ";
		
		
			if (URLvars["TA"]) {
				var slash = this.writeup.lastIndexOf("/");
				var filename = this.writeup.substring(slash+1, this.writeup.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name += "_TA";
				var tapath = this.writeup.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				tapath = tapath.replace("http", "https");
				str += ' <a href="' + tapath + '">Teacher Summary</a>';
			}
		
		return str;
	}
	this.day = day;
	this.title = title;
	this.module = module;
	this.writeup = writeup;
	this.datastudio = datastudio;
	this.excel = excel;
	this.solution = solution;
	this.info = info;
	this.LoadLine = Compute_LoadLine;
	this.WriteupLine = Compute_WriteupLine;
	return this;
}


// NEW EXPERIMENT IMPLEMENTATION

function ClassExperimentList(section,day,title,module,writeup,datastudio,excel,solution,info) {
	function Compute_AddExperiment(section,day,title,module,writeup,datastudio,excel,solution,info) {
		this.NumExperiment[section]++;
		this.Experiment[section][this.NumExperiment[section]] = new ClassExperiment(day,title,module,writeup,datastudio,excel,solution,info);
		
		//alert("ClassInClasList adding to:  " + section + " " + this.InClass[section]);
		//this.InClass[section].push(new ClassInClass(title,module,question,solution,info));
		if (section == "DEFAULT") 
		{
			for (var sections in this.Experiment)
			{
				//window.alert("ClassInClassList adding to: " + sections);
				if (sections != "DEFAULT") {
				this.NumExperiment[sections]++;
				this.Experiment[sections][this.NumExperiment[sections]] = new ClassExperiment(day,title,module,writeup,datastudio,excel,solution,info);
				//this.InClass[sections].push(new ClassInClass(title,module,question,solution,info));
				}
			}
		}
		//else 
		//{
		//	this.NumInClass[section]++;
		//	//this.InClass[section][this.NumInClass[section]] = new ClassInClass(title,module,question,solution,info);
		//	this.InClass[section].push(new ClassInClass(title,module,question,solution,info));
		//}
	}
	
	function Compute_ClearExperiment(section) {
		/*for (var x in this.InClass[section]) {
			
			var modstring = this.InClass[section][x].module;
			var mods = splitCommaDelimited(modstring);
			alert("modstring " + section + " " +  modstring);
			for (var y in mods) {
				//alert(modules[parseInt(mods[y])].NInClass[section]);
				modules[parseInt(mods[y])].InClass[section] = new Array();
				modules[parseInt(mods[y])].NInClass[section] = 0;
			}
		}*/
		//alert(section + " " + this.NumInClass[section])
		this.NumExperiment[section] = 0;
		this.Experiment[section] = new Array();

		
	}
	
	this.NumExperiment = new Array();
	this.NumExperiment["DEFAULT"] = 0;
	
	this.Experiment = new Array();
	this.Experiment["DEFAULT"] = new Array();
	
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.NumExperiment[sectionID] = 0;
		this.Experiment[sectionID] = new Array();
		
		//alert(sectionID);
	}
	
	this.AddExperiment = Compute_AddExperiment;
	this.AddExperiment(section,day,title,module,writeup,datastudio,excel,solution,info);
	this.ClearExperiment = Compute_ClearExperiment;
	return this;
}





// Constructor for InClass class
function ClassInClass(day,title,module,question,solution,info) {
	function Compute_LoadLine() {
		var str = this.title;
		var bq = this.question != "";
		var bsol = this.solution != "";
		if (bq || bsol) {
			str += ": ("
			if (bq) str += '<a href="' + this.question + '">Question</a>';
			//----> TIME RELEASE
			//alert("what is going on here?");
			var URLvars = getVarsFromURL();
			var myDate = ShortStringToWeekDay(this.day,"TRF");
               // Above line modified 10/4/08 by Alan Guth, replacing
               //    sectionToSchedType(URLvars["SEC"]) by "TRF".  The goal
               //    of the change is to time the release of all solutions
               //    from the TRF classes. 
			var theDate = myDate.GetDate();
			var today = new Date();
			//var hourDelay = 4;  // number of hours after 12:00pm of the date of the question
			if (bq && ((bsol && today.getTime() > theDate.getTime() + (1000*60*60*hourDelay)) || URLvars["TA"])) str += ", ";
			var solstring = ((today.getTime() < theDate.getTime() + (1000*60*60*hourDelay)) && URLvars["TA"]) ? "Unposted Solution" : "Solution";
			
			var solPath = this.solution;
			if (URLvars["TA"]) {
				var slash = this.solution.lastIndexOf("/");
				var filename = this.solution.substring(slash+1, this.solution.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name;
				var tapath = this.solution.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				tapath = tapath.replace("http", "https");
				solPath = tapath;
			}
			
			if (bsol && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay) || URLvars["TA"])) str += '<a href="' + solPath + '">' + solstring + '</a>';
			str += ")";
		}
		return str;
	}
	function Compute_WriteupLine() { // For In Class Problem
		var str = "";
		var bq = this.question != "";
		var bsol = this.solution != "";
		if (bq) str += '<a href="' + this.question + '">';
		str += this.title;
		if (bq) str += '</a>';
		//----> TIME RELEASE
			var URLvars = getVarsFromURL();
			var myDate = ShortStringToWeekDay(this.day,"TRF");
               // Above line modified 10/4/08 by Alan Guth, replacing
               //    sectionToSchedType(URLvars["SEC"]) by "TRF".  The goal
               //    of the change is to time the release of all solutions
               //    from the TRF classes. 
			var theDate = myDate.GetDate();
			var today = new Date();
			//var hourDelay = 4;  // number of hours after 12:00pm of the date of the question
			var solstring = ((today.getTime() < theDate.getTime() + (1000*60*60*hourDelay)) && URLvars["TA"]) ? "Unposted Solution" : "Solution";
			
			var solPath = this.solution;
			if (URLvars["TA"]) {
				var slash = this.solution.lastIndexOf("/");
				var filename = this.solution.substring(slash+1, this.solution.length);
				var namesplit = filename.split(".");
				var name = namesplit[0];
				var extension = namesplit[1];
				var newname = name;
				var tapath = this.solution.substring(0, slash);
				tapath += "/Raw/";
				tapath += newname + "." + extension;
				tapath = tapath.replace("http", "https");
				solPath = tapath;
			}
			
		if (bsol && (today.getTime() > theDate.getTime() + (1000*60*60*hourDelay) || URLvars["TA"])) str += ' (<a href="' + solPath + '">' + solstring + '</a>)';
		return str;
	}
	this.day = day;
	this.title = title;
	this.module = module;
	this.question = question;	// http address of question
	this.solution = solution;	// http address of solution
	this.info = info;
	this.LoadLine = Compute_LoadLine;
	this.WriteupLine = Compute_WriteupLine;
	return this;
}


function ClassInClassList(section,day,title,module,question,solution,info) {
	function Compute_AddInClass(section,day,title,module,question,solution,info) {
		this.NumInClass[section]++;
		this.InClass[section][this.NumInClass[section]] = new ClassInClass(day,title,module,question,solution,info);
		
		//alert("ClassInClasList adding to:  " + section + " " + this.InClass[section]);
		//this.InClass[section].push(new ClassInClass(title,module,question,solution,info));
		if (section == "DEFAULT") 
		{
			for (var sections in this.InClass)
			{
				//window.alert("ClassInClassList adding to: " + sections);
				if (sections != "DEFAULT") {
				this.NumInClass[sections]++;
				this.InClass[sections][this.NumInClass[sections]] = new ClassInClass(day,title,module,question,solution,info);
				//this.InClass[sections].push(new ClassInClass(title,module,question,solution,info));
				}
			}
		}
		//else 
		//{
		//	this.NumInClass[section]++;
		//	//this.InClass[section][this.NumInClass[section]] = new ClassInClass(title,module,question,solution,info);
		//	this.InClass[section].push(new ClassInClass(title,module,question,solution,info));
		//}
	}
	
	function Compute_ClearInClass(section) {
		/*for (var x in this.InClass[section]) {
			
			var modstring = this.InClass[section][x].module;
			var mods = splitCommaDelimited(modstring);
			alert("modstring " + section + " " +  modstring);
			for (var y in mods) {
				//alert(modules[parseInt(mods[y])].NInClass[section]);
				modules[parseInt(mods[y])].InClass[section] = new Array();
				modules[parseInt(mods[y])].NInClass[section] = 0;
			}
		}*/
		//alert(section + " " + this.NumInClass[section])
		this.NumInClass[section] = 0;
		this.InClass[section] = new Array();
		
	}
	
	this.NumInClass = new Array();
	this.NumInClass["DEFAULT"] = 0;
	
	this.InClass = new Array();
	this.InClass["DEFAULT"] = new Array();
	
	for (var i = 1;i <= numberOfSections;i++)
	{
		var sectionID = intToSection(i);
		this.NumInClass[sectionID] = 0;
		this.InClass[sectionID] = new Array();
		
		//alert(sectionID);
	}
	
	
	this.AddInClass = Compute_AddInClass;
	this.AddInClass(section,day,title,module,question,solution,info);
	this.ClearInClass = Compute_ClearInClass;
	return this;
}


// Is there a presentation for a given day?
function PresentationExist(day) {
	if (window.presentations[day]) 
		return 1;
	else
		return 0;
}

// How many experiments for a given day?
/*
function NumExperiments(day) {
	if (window.experiments[day]) 
		return experiments[day].NumExperiments;
	else
		return 0;
}
*/
function NumExperiments(section,day) {
	if (window.experiments[day]) 
		return experiments[day].NumExperiment[section];
	else
		return -1;
}

// How many in class problems for a given day?
function NumInClass(section,day) {
	if (window.InClass[day]) 
		return InClass[day].NumInClass[section];
	else
		return -1;
}


//Initializer for sections

function InitializeSection(sectionID,sched) {
	scheduleMap[sectionID] = sched;
	sections[sectionID] = new ClassSection(sectionID, sched);
}

function AddInstructorToSection(sectionID, firstname,lastname,email,contact) {
	sections[sectionID].AddInstructor(firstname,lastname,email,contact);

}

function AddGradTAtoSection(sectionID, firstname,lastname,email,contact) {
	sections[sectionID].AddGradTA(firstname,lastname,email,contact);
}

function AddUGradTAtoSection(sectionID,firstname,lastname,email,contact) {
	sections[sectionID].AddUGradTA(firstname,lastname,email,contact);
}

function AddDemoGroupToSection(sectionID,firstname,lastname,email,contact) {
	sections[sectionID].AddDemoGroup(firstname,lastname,email);
}

function AddRegularOfficeHoursToSection(sectionID,email,officeDay,hoursString) {
	sections[sectionID].AddRegularOfficeHours(email,officeDay,hoursString);
}

function AddSpecialOfficeHoursToSection(sectionID,email,month,date,year,hoursString) {
	sections[sectionID].AddSpecialOfficeHours(email,month,date,year,hoursString);
}

function CancelOfficeHoursInSection(sectionID,email,month,date,year) {
	sections[sectionID].CancelOfficeHours(email,month,date,year);
}

// Initializer for presentations
function InitializePresentation(day,title,ShortTitle,module,PresAvail,PRSAvail,QAAvail,SumAvail,info) {
	//alert("InitPres " + day + title + "Module: " + module);
	presentations[day] = new ClassPresentation(day,title,ShortTitle,module,info,PresAvail,PRSAvail,QAAvail,SumAvail);
	//alert("InitPres " + ShortTitle + " " + module);
	var theModules = splitCommaDelimited(module);
//	alert("There are "+ theModules.length + " modules: " + theModules)
//	alert("First is " + theModules[0])
	for (var i = 0; i < theModules.length;i++) {
		var modNum = parseInt(theModules[i],10)
		if (isNaN(modNum)) continue // in case of empty quotes or an error typing
		//alert("module: " + parseInt(theModules[i],10));
		modules[modNum].AddPresentation(day);
	}
	//modules[module].AddPresentation(day);
}

// Modifier for presentations
function ModifyPresentation(section,day,title,shortTitle,module,PresAvail,PRSAvail,QAAvail,SumAvail,info) {
	// if for whatever reason a presentation doesn't already exist on this day, make one.
	// this shouldn't ever be the case, though.
	//window.alert("ModifyPresentation being called...");
	if (PresentationExist(day) != 1) {
		presentations[day] = new ClassPresentation(day,title,shortTitle,module,info,PresAvail,PRSAvail,QAAvail,SumAvail);
		modules[module].AddPresentation(day);
	}
	else {
		//window.alert("Should by Modifying data...");
		presentations[day].ModifyData(section,day,title,shortTitle,module,info,PresAvail,PRSAvail,QAAvail,SumAvail);
	}
}

function ModifyPresentationForSections(sections,day,title,shortTitle,module,PresAvail,PRSAvail,QAAvail,SumAvail,info) {
	var theSections = splitCommaDelimited(sections);
	for (var i = 0; i < theSections.length;i++) {
		ModifyPresentation(theSections[i],day,title,shortTitle,module,PresAvail,PRSAvail,QAAvail,SumAvail,info);
	}
}

// Initializer for problem sets
function InitializePSet(section,dueTime,dueDate,module,qAvail,sAvail) {
	//problemSets[section][number] = new ClassProblemSet(number,dueDate,module,qAvail,sAvail);
	var number = problemSets[section].length + 1;
	problemSets[section].push(new ClassProblemSet(dueTime,number,dueDate,module,qAvail,sAvail));
	//modules[module].AddPSet(number);
	var theModules = splitCommaDelimited(module);
	for (var i = 0; i < theModules.length;i++) {
		modules[parseInt(theModules[i],10)].AddPSet(section,problemSets[section].length-1);
	}
} 

function InitializePSetForAllSections(dueTime, dueDate, module,qAvail, sAvail) {
	for (var num = 1; num <= numberOfSections;num++) {
		var sectionID = intToSection(num);
		InitializePSet(sectionID,dueTime, dueDate, module,qAvail, sAvail);
	}
}

// Initializer for Mastering Physics problem sets
function InitializeMPPSet(section,dueTime,dueDate,module,qAvail,sAvail) {
	var number = mpProblemSets[section].length + 1;
	mpProblemSets[section].push(new ClassMPProblemSet(dueTime,number,dueDate,module,qAvail,sAvail));
	//modules[module].AddPSet(number);
	var theModules = splitCommaDelimited(module);
	for (var i = 0; i < theModules.length;i++) {
		modules[parseInt(theModules[i],10)].AddMPPSet(section,mpProblemSets[section].length-1);
	}
} 

function InitializeMPPSetForAllSections(dueTime, dueDate, module,qAvail, sAvail) {
	for (var num = 1; num <= numberOfSections;num++) {
		var sectionID = intToSection(num);
		InitializeMPPSet(sectionID,dueTime, dueDate, module,qAvail, sAvail);
	}
}

// Initializer for experiements

function InitializeExperiment(section,day,title,module,writeup,datastudio,excel,solution,info) {
	if (NumExperiments(section,day) != -1)
	{
		experiments[day].AddExperiment(section,day,title,module,writeup,datastudio,excel,solution,info);
	}
	else 
	{
		experiments[day] = new ClassExperimentList(section,day,title,module,writeup,datastudio,excel,solution,info);
	}
	var theModules = splitCommaDelimited(module);
	for (var i = 0; i < theModules.length;i++) {
		modules[parseInt(theModules[i],10)].AddExperiment(section,day,NumExperiments(section,day));
	}
}

function ModifyExperiment(section,day,number,newTitle,newModule,newWriteup,newDatastudio,newExcel,newSolution,newInfo) {
	//alert("ModifyInClass: " + section + " " + day + " " + number + " " + newTitle + " " + newModule + " " + newQuestion + " " + newSolution + " " + newInfo);
	if (!experiments[day]) {
		alert("ModifyExperiment: No Experiments on day " + day);
		return;
	} else {
		if (experiments[day].NumExperiment[section] < number) {
			alert("ModifyExperiment: No Experiment number " + number + " on day " + day + " in section " + section);
			return;
		}
		//alert("ModifyInClass: " + InClass[day].InClass[section][number].title);
		if (newTitle != null) experiments[day].Experiment[section][number].title = newTitle;
		if (newModule != null) experiments[day].Experiment[section][number].module = newModule;
		if (newWriteup != null) experiments[day].Experiment[section][number].writeup = newWriteup;
		if (newDatastudio != null) experiments[day].Experiment[section][number].datastudio = newDatastudio;
		if (newExcel != null) experiments[day].Experiment[section][number].excel = newExcel;
		if (newSolution != null) experiments[day].Experiment[section][number].solution = newSolution;
		if (newInfo != null) experiments[day].Experiment[section][number].info = newInfo;
		//alert("ModifyInClass: " + InClass[day].InClass[section][number].title);
	}
	
}

function InitializeExperimentForSections(sections,day,title,module,writeup,datastudio,excel,solution,info) {
	var theSections = splitCommaDelimited(sections);
	for (var i = 0; i < theSections.length;i++) {
		InitializeExperiment(theSections[i],day,title,module,writeup,datastudio,excel,solution,info)
	}
}

function InitializeExperimentForAllSections(day,title,module,writeup,datastudio,excel,solution,info) {
	for (var num = 1; num <= numberOfSections;num++) {
		var sectionID = intToSection(num);
		InitializeExperiment(sectionID,day,title,module,writeup,datastudio,excel,solution,info)
	}
}




// Initializer for in-class problems
function InitializeInClass(section,day,title,module,question,solution,info) {
	if (NumInClass(section,day) != -1)
	{
		InClass[day].AddInClass(section,day,title,module,question,solution,info);
	}
	else 
	{
		InClass[day] = new ClassInClassList(section,day,title,module,question,solution,info);
	}
	var theModules = splitCommaDelimited(module);
	for (var i = 0; i < theModules.length;i++) {
		modules[parseInt(theModules[i],10)].AddInClass(section,day,NumInClass(section,day));
	}
}

function ModifyInClass(section,day,number,newTitle,newModule,newQuestion,newSolution,newInfo) {
	//alert("ModifyInClass: " + section + " " + day + " " + number + " " + newTitle + " " + newModule + " " + newQuestion + " " + newSolution + " " + newInfo);
	if (!InClass[day]) {
		alert("ModifyInClass: No InClass Problems on day " + day);
		return;
	} else {
		if (InClass[day].NumInClass[section] < number) {
			alert("ModifyInClass: No InClass Problem number " + number + " on day " + day + " in section " + section);
			return;
		}
		//alert("ModifyInClass: " + InClass[day].InClass[section][number].title);
		if (newTitle != null) InClass[day].InClass[section][number].title = newTitle;
		if (newModule != null) InClass[day].InClass[section][number].module = newModule;
		if (newQuestion != null) InClass[day].InClass[section][number].question = newQuestion;
		if (newSolution != null) InClass[day].InClass[section][number].solution = newSolution;
		if (newInfo != null) InClass[day].InClass[section][number].info = newInfo;
		//alert("ModifyInClass: " + InClass[day].InClass[section][number].title);
	}
	
}

function InitializeInClassForSections(sections,day,title,module,question,solution,info) {
	var theSections = splitCommaDelimited(sections);
	for (var i = 0; i < theSections.length;i++) {
		InitializeInClass(theSections[i],day,title,module,question,solution,info)
	}
}

function InitializeInClassForAllSections(day,title,module,question,solution,info) {
	for (var num = 1; num <= numberOfSections;num++) {
		var sectionID = intToSection(num);
		InitializeInClass(sectionID,day,title,module,question,solution,info)
	}
}


function RemoveInClass(section,day){
	//InClass[day].InClass[section] = new Array();
	//InClass[day].NumInClass[section] = 0;
	//alert("arraylength " + modules.length);
	for (var i = 0;i<modules.length;i++) {
		//alert(section + " module: " + modules[i].module);
		for (var classes in modules[i].InClass[section]) {
			//alert(section + " " + modules[i].InClass[section][classes]);
			var theString = modules[i].InClass[section][classes];
			var thesubstr = theString.substr(0,5);
			if (thesubstr == day) {
				modules[i].InClass[section][classes] = null; //"undefined";
				modules[i].NInClass[section]--;
				//alert("removed: " + theString + " in section" + section + " in module: " + i + " new NInClass: " + modules[i].NInClass[section] + " on day: " + day);
			}
		}

	}
	InClass[day].InClass[section] = new Array();
	InClass[day].NumInClass[section] = 0;
	//InClass[day].NumInClass[section]--;
}

function MakePresentationBar(section,theDate)
{
	//window.alert("MakePresentationBar sec: " + section + " date: " + theDate.GetDate());
	var URLvars = getVarsFromURL();
	var IsTA = URLvars["TA"];
	
	if (PresentationExist(theDate.ShortString()))
	{
		p = presentations[theDate.ShortString()]

		document.writeln("<h1>");
		if (p.PresAvail[section] != null)
		{
			if (p.PresAvail[section])
			{
				document.writeln("Today's Presentation: "+p.shortTitle[section]+"</h1>");
				document.writeln("<h1>");		
				//document.write('<a href="javascript:gotoPPT(' + "'" + section + "'" + ')">PPT</a>, ');
				// Take out PPT -- they shouldn't need it any more EWH 9/10/07
				//document.write('<a href="'+linkPPT(section)+'">PPT</a>, ');
				document.write('<a href="'+linkPresentationHTML(section)+'">PDF (View)</a>, ');
				document.write('<a href="'+linkPresentationPDF(section)+'">PDF (Print)</a>');
			}
		}
		else
		{
			//section = "DEFAULT"
			if (p.PresAvail["DEFAULT"])
			{
				document.writeln("Today's Presentation: "+p.shortTitle["DEFAULT"]+"</h1>");
				document.writeln("<h1>");		
				//document.write('<a href="javascript:gotoPPT(' + "'" + "DEFAULT" + "'" + ')">PPT</a>, ');
				// Take out PPT -- they shouldn't need it any more EWH 9/10/07
				// document.write('<a href="'+linkPPT("DEFAULT")+'">PPT</a>, ');
				document.write('<a href="'+linkPresentationHTML("DEFAULT")+'">PDF (View)</a>, ');
				document.write('<a href="'+linkPresentationPDF("DEFAULT")+'">PDF (Print)</a>');
			}
		}
		if (p.QAAvail[section] != null)
		{
			if (p.QAAvail[section])
			{
				if ((p.PresAvail[section]) || (p.PresAvail["DEFAULT"])) { document.write(', '); }
				document.write('<a href="'+linkQA(section)+'">Q&A</a>');
			}
		}
		else 
		{
			if (p.QAAvail["DEFAULT"])
			{
				if ((p.PresAvail[section]) || (p.PresAvail["DEFAULT"])) { document.write(', '); }
				document.write('<a href="'+linkQA("DEFAULT")+'">Q&A</a>');
			}
		}
		if (p.PRSAvail[section] != null)
		{
			if (p.PRSAvail[section])
			{
				//--------> Timed release of PRS
				
				var myDate = theDate.GetDate();
				var today = new Date();
				//alert("HourDelay "+HourDelay);
				//alert(myDate.toString() + " " + today.toString());
				if ((p.PRSAvail[section]==2) || (today.getTime() > myDate.getTime() + (1000*60*60*HourDelay))) {
					if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { document.write(', ') }
					document.write('<a href="'+linkPRS(section)+'">PRS</a>');
				} else if (IsTA) {
					if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { document.write(', ') }
					document.write('<a href="'+linkPRS_TA(section)+'">PRS</a>');
				}
			}
		}
		else
		{
			if (p.PRSAvail["DEFAULT"])
			{
				//--------> Timed release of PRS
				
				var myDate = theDate.GetDate();
				var today = new Date();
				//alert("HourDelay "+HourDelay);
				//alert(myDate.toString() + " " + today.toString());
				if ((p.PRSAvail["DEFAULT"]==2) || (today.getTime() > myDate.getTime() + (1000*60*60*HourDelay))) {
					if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { 
					document.write(', ') }
					document.write('<a href="'+linkPRS("DEFAULT")+'">PRS</a>');
				} else if (IsTA) {
					if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { document.write(', ') }
					document.write('<a href="'+linkPRS_TA("DEFAULT")+'">PRS</a>');
				}
			}

		}
		
		if (p.SumAvail[section] != null)
		{
			if (p.SumAvail[section])
			{
				if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { document.write(', ') }
				document.write('<a href="'+linkPresSummary(section)+'">Summary</a>');
			}
		}
		else
		{
			if (p.SumAvail["DEFAULT"])
			{
				if (p.PresAvail[section] || p.PresAvail["DEFAULT"]) { document.write(', ') }
				document.write('<a href="'+linkPresSummary("DEFAULT")+'">Summary</a>');
			}
		}
		// teacher summary
		//if (IsTA) document.write(', <a href="javascript:gotoTeacherSummary('+"'" + "DEFAULT" + "'" + ')">Teacher Summary</a>');
		
		document.writeln("</h1>");
		document.writeln("<h2>");
		
		var theTitle;
		var theInfo;
		(p.title[section] != null) ? (theTitle = p.title[section]) : (theTitle = p.title["DEFAULT"]);
		(p.info[section] != null) ? (theInfo = p.info[section]) : (theInfo = p.info["DEFAULT"]);
			
		document.writeln(theTitle + ":  " + theInfo);
		document.writeln("</h2>");
		
		
		
	} else {
		document.writeln("<h1>No Presentation Notes Today</h1>");
	}
}

function WriteHiddenDayContent(section, day) {
	// here is the hidden content for instructors
	// should the TA flag be passed as an argument to this function rather than calling getVarsFromURL() from inside?
	var URLVars = getVarsFromURL();
	if (URLVars["TA"]) {
		if (URLVars["TA"] == "1") {
			document.writeln("<br>");
			document.writeln("<div align='left'>Here is what the other section leaders are doing today: <br><br>");
			for (var i = 1; i<=numberOfSections; i++) {
				var sec = intToSection(i);
				if (URLVars["SEC"] != sec) {
					document.writeln(p.InfoString(sec) + "<br>");
					var numExp = NumExperiments(sec,day);
					// check for "deleted" experiments
					var deletedExp = 0;
					for (var x = 1; x <= numExp; x++) {
						if (experiments[day].Experiment[sec][x].title == "") deletedExp++;
					}
					var realNumExp = numExp - deletedExp;
					if (realNumExp > 0) {
						var expText = "They are also doing the following experiment" + ((realNumExp == 1) ? (": ") : ("s: "));
						for (var j = 1; j <= numExp; j++) {
							if (experiments[day].Experiment[sec][j].title != "") expText += experiments[day].Experiment[sec][j].LoadLine() + ((realNumExp == 1) ? (".") : ((realNumExp > 1 && j == realNumExp) ? (".") : (", and ")));
						}
						document.writeln(expText + "<br>");
					}
					var numIC = NumInClass(sec,day);
					// check for "deleted" problems
					var deletedIC = 0;
					for (var x = 1; x <= numIC; x++) {
						if (InClass[day].InClass[sec][x].title == "") deletedIC++;
					}
					var realNumIC = numIC - deletedIC;
					if (realNumIC > 0) {
						var expText = "They are also doing the following in-class problem" + ((realNumIC == 1) ? (": ") : ("s: "));
						for (var j = 1; j <= numIC; j++) {
							if (InClass[day].InClass[sec][j].title != "") expText += InClass[day].InClass[sec][j].LoadLine() + ((realNumIC == 1) ? (".") : ((realNumIC > 1 && j == realNumIC) ? (".") : (", and ")));
						}
						document.writeln(expText);
						document.writeln("<br>");
					}
					
					document.writeln("<br>");
				}
				
			}
			document.writeln("</div><br>");
		}
	}
}


function MakeExperimentBar(section,theDate)
{
	//window.alert("MakingInClassBar sec: " + section + " date: " + theDate);
	var N = NumExperiments(section,theDate.ShortString())
	//window.alert("N = " + N );
	// Annoying hack necessary to remove Experiments that have been modified to have no TITLE (title is "")...
	// I am taking this to mean "Don't show this experiment", since literally deleting experiments seems problematic.
	var deleted = 0;
	for (var j=1; j <= N; j++) {
		if (experiments[theDate.ShortString()].Experiment[section][j].title == "") deleted++;
	}
	var newN = N - deleted;
	if (newN > 0) // only make it if there are some InClass questions
	{
		if (N>1) {
			document.writeln("<h1>Today's Experiments</h1>");
		} else {
			document.writeln("<h1>Today's Experiment</h1>");
		}

		for (var i=1; i<=N; i++) { // count through the experiments in today's class
			//alert("in N loop: " + i);
			expti = experiments[theDate.ShortString()].Experiment[section][i]
			if (expti.title != "") {
				document.writeln("<h1>"+expti.LoadLine()+"</h1>");
				if (expti.info != "") document.writeln("<h2>"+expti.info+"</h2>");
			}
		}
	} 
}


function ListExperimentNames(section,theDate)
{
	var N = NumExperiments(section,theDate.ShortString())
	if (N > 0) // only make it if there are some experiments
	{
		

		for (var i=1; i<=N; i++) { // count through the experiments in today's class
			expti = experiments[theDate.ShortString()].Experiment[section][i];
			document.writeln("<br><a href='" + expti.writeup + "'><small>" + expti.title + "</small></a><br>");
			//document.writeln("<br><a href='" + expti.writeup + "'<font size='10'>" + expti.title + "</font></a><br>");
			//if (expti.info != "") document.writeln("<h2>"+expti.info+"</h2>");
		}
	} 

}

//added this but i'm not sure it's going to be used
function MakeExperimentList(section)
{
	// Iterate through the presentations available to see if the PRS is available
	for (var day in experiments) {
		weekDay = ShortStringToWeekDay(day,getSchedType(section));
		theDate = weekDay.GetDate();
		displayDate = ZeroPad(theDate.getMonth()+ 1) + "/" + ZeroPad(theDate.getDate()) + "/" + theDate.getFullYear();
		var ic = experiments[day];
		var N = ic.NumExperiment;
		for (i=1; i<=N; i++) { // count through the in class problems in this day's class
			expti = ic.experiments[i]
			if (expti.title != "") document.writeln("<h1>"+displayDate+": "+expti.LoadLine()+"</h1>");
		}
	}
}

function MakeInClassBar(section,theDate)
{
	//window.alert("MakingInClassBar sec: " + section + " date: " + theDate);
	var N = NumInClass(section,theDate.ShortString())
	//window.alert("N = " + N );
	// Annoying hack necessary to remove InClass problems that have been modified to have no TITLE (title is "")...
	// I am taking this to mean "Don't show this problem", since literally deleting problems seems problematic.
	var deleted = 0;
	for (var j=1; j <= N; j++) {
		if (InClass[theDate.ShortString()].InClass[section][j].title == "") deleted++;
	}
	var newN = N - deleted;
	if (newN > 0) // only make it if there are some InClass questions
	{
		if (N>1) {
			document.writeln("<h1>Today's In Class Problems</h1>");
		} else {
			document.writeln("<h1>Today's In Class Problem</h1>");
		}

		for (var i=1; i<=N; i++) { // count through the experiments in today's class
			//alert("in N loop: " + i);
			InClassi = InClass[theDate.ShortString()].InClass[section][i]
			if (InClassi.title != "") {
				document.writeln("<h1>"+InClassi.LoadLine()+"</h1>");
				if (InClassi.info != "") document.writeln("<h2>"+InClassi.info+"</h2>");
			}
		}
	} 
}




// MakePRSList creates the content of the PRS page -- a list of the PRS files that are available, with 
// class number and short title of the content (linked to the PRS file)
function MakePRSList(section)
{
	// Iterate through the presentations available to see if the PRS is available
	for (var day in presentations) {
		var p = presentations[day];
		var bPRS;
		(p.PRSAvail[section] != null) ? (bPRS = p.PRSAvail[section]) : (bPRS = p.PRSAvail["DEFAULT"]);
		if (bPRS >= 1) {
			//alert("p.PRSAvail[" + section + "] " + p.PRSAvail[section]);
			weekDay = ShortStringToWeekDay(day,getSchedType(section));
			theDate = weekDay.GetDate();
			displayDate = ZeroPad(theDate.getMonth()+ 1) + "/" + ZeroPad(theDate.getDate()) + "/" + theDate.getFullYear();
			theSection = (p.PRSAvail[section] == null) ? ("DEFAULT") : (section);
			theTitle = (p.title[section] == null) ? (p.title["DEFAULT"]) : (p.title[section]);
			theShortTitle = (p.shortTitle[section] == null) ? ( p.shortTitle["DEFAULT"]) : (p.shortTitle[section]);
			var today = new Date();
			// List them after 5 pm (4 hours after noon on todays date)
			if ((bPRS==2) || (today.getTime() > theDate.getTime() + (1000*60*60*5))) {
				document.writeln('<a href="'+linkSpecificPRS(theSection,day)+'">'+theTitle+' (' + 
								displayDate+')'+': '+theShortTitle+'</a><br>');
			}
		}
	}
}

function ZeroPad(num)
{
	if (num<10) 
		return "0"+num 
	else 
		return num
}

// MakeInClassList creates the content of the Problem Solving page -- a list of the in class files that are available, with 
// class number and short title of the content (linked to the inclass questions and answers)
function MakeInClassList(section)
{
	// Iterate through the presentations available to see if the PRS is available
	for (var day in InClass) {
		weekDay = ShortStringToWeekDay(day,getSchedType(section));
		theDate = weekDay.GetDate();
		displayDate = ZeroPad(theDate.getMonth()+ 1) + "/" + ZeroPad(theDate.getDate()) + "/" + theDate.getFullYear();
		var ic = InClass[day];
		var N = ic.NumInClass;
		for (i=1; i<=N; i++) { // count through the in class problems in this day's class
			InClassi = ic.InClass[i]
			if (InClassi.title != "") document.writeln("<h1>"+displayDate+": "+InClassi.LoadLine()+"</h1>");
		}
	}
}




/*
function InitializeModules()
{
	modules[0] = new ClassModule("Review",0);
	modules[1] = new ClassModule("Fields",1);
	modules[2] = new ClassModule("Coulomb's Law",2);
	modules[3] = new ClassModule("Electric Potential",3);
	modules[4] = new ClassModule("Gauss' Law",4);
	modules[5] = new ClassModule("Capacitors",5);
	modules[6] = new ClassModule("Current and Resistance",6);
	modules[7] = new ClassModule("Direct Current Circuits",7);
	modules[8] = new ClassModule("Magnetic Fields",8); 
	modules[9] = new ClassModule("Sources of Magnetic Fields",9);
	modules[10] = new ClassModule("Faraday's Law",10);
	modules[11] = new ClassModule("Inductance and Energy in Magnetic Fields",11);
	modules[12] = new ClassModule("Alternating Current Circuits",12);
	modules[13] = new ClassModule("Maxwell's Equations and Electromagnetic Waves",13);
	modules[14] = new ClassModule("Interference and Diffraction",14);
}
*/


//InitializeModules();






//////////////////////////////////////////////  CALENDAR RELATED CODE



<!--


	//addKeyDate(endofterm, "END OF TERM");

// function for adding important dates
function addKeyDate(theDate, description){
	//keyDates must be defined above
	//alert("addKeyDate being called?");
	if (keyDates.length > 0)
	{
		for (var i = 0; i < keyDates.length;i++)
		{
			if (keyDates[i][0].getTime() == theDate.getTime())
			{
				alert("More than one key date defined for: " + theDate.toString());
				return false;
			}
		}	
	}
	var myKeyDate = new Array();
	myKeyDate[0] = theDate;
	myKeyDate[1] = description;
	
	keyDates.push(myKeyDate);
	return true;
}
	
function getKeyDateText(theDate){
	//alert(theDate.getTime());
	if (keyDates.length > 0)
	{
		for (var i = 0; i < keyDates.length;i++)
		{
			//alert("theDate = " +theDate.getTime() + " keyDates[i][0] = " + keyDates[i][0].getTime());
			if (keyDates[i][0].getTime() == theDate.getTime())
			{
				return keyDates[i][1];
			}
			
		}
		return false;
	}
	else {return false;}
}

function checkProblemSetDue(section, theDate){
	//alert(theDate.getTime());
	if (problemSets[section].length > 0)
	{
		for (var num in problemSets[section])
		{
			//alert("theDate = " +theDate.getTime() + " keyDates[i][0] = " + keyDates[i][0].getTime());
			if (problemSets[section][num].dueDate.getTime() == theDate.getTime())
			{
				return "Problem Set " + problemSets[section][num].number + " DUE";
			}
			
		}
		return false;
	}
	else {return false;}
}

function checkMPProblemSetDue(section, theDate){
	//alert(theDate.getTime());
	if (mpProblemSets[section].length > 0)
	{
		for (var num in mpProblemSets[section])
		{
			//alert("theDate = " +theDate.getTime() + " keyDates[i][0] = " + keyDates[i][0].getTime());
			if (mpProblemSets[section][num].dueDate.getTime() == theDate.getTime())
			{
				return "Mastering Physics " + mpProblemSets[section][num].number + " DUE";
			}
			
		}
		return false;
	}
	else {return false;}
}
	
function stringDateString(section,wkday){
	//alert("writeDateString(" + section + "," + wkday + ")");
	var wd = ShortStringToWeekDay(wkday,getSchedType(section));
	var myDate = wd.GetDate();
	var theDay = intToDayName(myDate.getDay());
	var theDate = myDate.getDate();
	var theMonth = getMonthFullName(myDate.getMonth());
	var theYear = myDate.getFullYear();
	
	var dateString = theDay + ", " + theMonth + " " + theDate + ", " + theYear;
	return dateString;
}
	
function writeDateString(section,wkday){
	document.writeln(stringDateString(section,wkday));
}
	
// This section tells what day of the week this course is held (TRF or MWF)
var ThisSection = "MWF"

//var testdate = new Date(2004,1,1);
//testdate.setDate(29);
//alert(testdate.toString());

// Introduce the WeekDay class that contains a week and a day and includes methods to create strings, etc for this week and day
function ClassWeekDay(week,day,schedType) {
	function compute_IsValid() {	// Check if valid date
		validWeek = ((this.week >= 0) && (this.week <= this.finalWeekInt));
		validDay = ((this.day >= 0) && (this.day <= this.finalDayInt))
		return ((validWeek) && (validDay));
	}
	function compute_ShortString() { // Calculate a string for filenames
		if (this.week < 10) {
			return "W0" + this.week + "D" + this.day;
		} else {
			return "W" + this.week + "D" + this.day;
		}			
	}
	function compute_MiddleString() { // Calculate a string for filenames (for dailt course page)
		if (this.week < 10) {
			return "Wk0" + this.week + "Dy" + this.day;
		} else {
			return "Wk" + this.week + "Dy" + this.day;
		}			
	}
	function compute_LongString() { // Calculate a string for filepaths
		if (this.week < 10) {
			return "week0" + this.week + "day" + this.day;
		} else {
			return "week" + this.week + "day" + this.day;
		}			
	}
	function compute_GetDate() { // Calculates the date corresponding to this week day combination
		weekdays=new Array();
		switch (this.schedType)
		{
		case "TRF" : 	
			weekdays[1] = 2;	// "Day 1" is Tuesday
			weekdays[2] = 4;	// "Day 2" is Thursday
			weekdays[3] = 5;	// "Day 3" is Friday
			break;
		case "MWF" :
		default :
			weekdays[1] = 1;	// "Day 1" is Monday
			weekdays[2] = 3;	// "Day 2" is Wednesday
			weekdays[3] = 5;	// "Day 3" is Friday
			break;	
		}
		var termday = (this.week-1)*7 + weekdays[this.day];
		var timeFromStart = (termday - startofterm.getDay()) * (1000 * 60 * 60 * 24);
		// Modified 10/4/08 by Alan Guth: "+ 0.5" removed from
		//    (termday - startofterm.getDay() + 0.5); the presence of
		//    this offset caused the Calendar in the TRF sections to have
		//    no entries on Fridays.  The reason is that the date for a
		//    given WxxDx specification was calculated as one day too
		//    early.
		var theDate = new Date(timeFromStart + startofterm.getTime());
		timeFromStart = timeFromStart + (theDate.getTimezoneOffset()-startofterm.getTimezoneOffset()) * (1000 * 60)
		theDate = new Date(timeFromStart + startofterm.getTime());
		// Further modified 10/9/08 by Alan Guth, adding the
		//    two lines above.  These lines compensate for
		//    changes in daylight savings time between
		//    startofterm and the present time.  With this
		//    correction, assuming that startofterm is set in
		//    ContentAvailable.js by something like
		//        var startofterm = new Date(2008,7,31); 
                    //   Beginning date must be the sunday before
		          //    the start of the term
          //    then theDate returns the time corresponding to
		//    00:00 local time on the day of the next class.
		return theDate;	
	}
	this.schedType = schedType
	this.finalWeekInt = 15;
	this.finalDayInt = 3;
	this.week = week;
	this.day = day;
	this.IsValid = compute_IsValid;
	this.ShortString = compute_ShortString;
	this.MiddleString = compute_MiddleString;
	this.LongString = compute_LongString;
	this.GetDate = compute_GetDate;
	return this;
}

// Converts a short string (eg W##D##) to the correct week/day object
function ShortStringToWeekDay(str,schedType)
{	
	w = parseInt(str.substring(1,3),10);
	d = parseInt(str.substring(4,5),10);
	//alert("SStoWeekDay: " + str.substring(1,3) + ", " + str.substr(4,1));
	wd = new ClassWeekDay(w, d,schedType);
	return wd;
}

// Converts a date to the correct week/day object based on whether the class is "MWF" or "TRF"
function DateToWeekDay(theDate, schedType)
{
	var timeFromStart = theDate.getTime() - startofterm.getTime();
	var lengthOfTerm =  endofterm.getTime() - startofterm.getTime();
// Start counting from the Sunday before start of term.
	var termday = Math.floor (timeFromStart / (1000 * 60 * 60 * 24)) + startofterm.getDay();
	// Modified 10/4/08 by Alan Guth: "+ 0.5" removed from
	//    (timeFromStart / (1000 * 60 * 60 * 24)) - 0.5)
	var termweek = Math.floor ((termday + 1) / 7) + 1;  // Start on week "1"

	weekdays=new Array();
	switch (schedType)
	{
	case "TRF" : 	
		weekdays[0] = 1;	// Sunday, begin showing Tuesday's page
		weekdays[1] = 1;	// Monday, show Tuesday's page
		weekdays[2] = 1;	// Tuesday, show Tuesday's page
		weekdays[3] = 2;	// Wednesday, beginning showing showing Thursday's page
		weekdays[4] = 2;	// Thursday, show Thursday's page
		weekdays[5] = 3;    // Friday, show Friday's page
		weekdays[6] = 1;	// Saturday, show NEXT Tuesday's page
		break;
	case "MWF" :
	default :
		weekdays[0] = 1;	// Sunday, begin showing Monday's page
		weekdays[1] = 1;	// Monday, show Monday's page
		weekdays[2] = 2;	// Tuesday, beginning showing showing Wednesday's page
		weekdays[3] = 2;	// Wednesday, show Wednesday's page
		weekdays[4] = 3;	// Thursday, beginning showing showing Friday's page
		weekdays[5] = 3;    // Friday, show Friday's page
		weekdays[6] = 1;	// Saturday, show NEXT Monday's page
		break;	
	}

	termweekday = weekdays[termday % 7];
	wd = new ClassWeekDay(termweek, termweekday,schedType);
	return wd;	
}

function CheckDateForClass(theDate, schedType)
{
	var timeFromStart = theDate.getTime() - startofterm.getTime();
	var lengthOfTerm =  endofterm.getTime() - startofterm.getTime();
// Start counting from the Sunday before start of term.
	var termday = Math.floor (timeFromStart / (1000 * 60 * 60 * 24)) + startofterm.getDay();
	var termweek = Math.floor ((termday + 1) / 7) + 1;  // Start on week "1"

	weekdays=new Array();
	switch (schedType)
	{
	case "TRF" : 	
		weekdays[0] = 0;	// Sunday, begin showing Tuesday's page
		weekdays[1] = 0;	// Monday, show Tuesday's page
		weekdays[2] = 1;	// Tuesday, show Tuesday's page
		weekdays[3] = 0;	// Wednesday, beginning showing showing Thursday's page
		weekdays[4] = 2;	// Thursday, show Thursday's page
		weekdays[5] = 3;    // Friday, show Friday's page
		weekdays[6] = 0;	// Saturday, show NEXT Tuesday's page
		break;
	case "MWF" :
	default :
		weekdays[0] = 0;	// Sunday, begin showing Monday's page
		weekdays[1] = 1;	// Monday, show Monday's page
		weekdays[2] = 0;	// Tuesday, beginning showing showing Wednesday's page
		weekdays[3] = 2;	// Wednesday, show Wednesday's page
		weekdays[4] = 0;	// Thursday, beginning showing showing Friday's page
		weekdays[5] = 3;    // Friday, show Friday's page
		weekdays[6] = 0;	// Saturday, show NEXT Monday's page
		break;	
	}

	termweekday = weekdays[termday % 7];
	if (termweekday != 0)
	{
		wd = new ClassWeekDay(termweek, termweekday,schedType);
		return wd.ShortString();
	}
	else
	{
		return false;
	}	
}



// gotoClassPage will take a section and a WXXDY format string and go to that particular class.
// distinguished from gotoDatePage() which will take a section and a date and determine the specific class from that info
// and gotoCurrentPage() which is the new version of gotoCoursePage()
function gotoClassPage(section,wkday)
{
	var basePath = "../coursematerial/day.htm";
	
	var params = "?" + "SEC=" + section + ";" + "DAY=" + wkday;
	
	var URLvars = getVarsFromURL();
	if (URLvars["TA"]) params += ";TA=" + URLvars["TA"];
	
	var newurl = basePath + params;
	document.location = newurl;
}

function gotoDatePage(section,theDate)
{
	var basePath = "../coursematerial/day.htm";
	var schedType;
	if (section == 'L01' || section == 'L02' || section == 'L03')
	{
		schedType = 'MWF';
	}
	else
	{
		schedType = 'TRF';
	}
	
	var wd = DateToWeekDay(theDate,schedType);
	if (wd.IsValid())
	{
		var params = "?SEC=" + section + ";DAY=" + wd.ShortString();
		var newurl = basePath + params;
		document.location = newurl;
	}
	else
	{
		alert("gotoDatePage(...) :  This is not a valid date!");
	}
}

// This is the same as "gotoCurrentPage" except instead of jumping it produces the text for the link
function linkCurrentPage(section)
{
	var basePath = "../coursematerial/day.htm";
	var schedType = getSchedType(section);
	
	var wd = DateToWeekDay(new Date(),schedType);
	if (wd.IsValid())
	{
		var params = "?SEC=" + section + ";DAY=" + wd.ShortString();
		var newurl = basePath + params;
		var URLvars = getVarsFromURL();
		if (URLvars["TA"]) newurl += ";TA=" + URLvars["TA"];
		return newurl;
	}
	else
	{
		var today = new Date();
		if (today.getTime() < startofterm.getTime()) {
			//alert("The semester hasn't started yet.  Redirecting to first day of classes.");
			var params = "?SEC=" + section + ";DAY=W01D2";
		} 
		else if (today.getTime() > endofterm.getTime()) {
			//alert("The semester has ended.  Redirecting to last day of classes.");
			var params = "?SEC=" + section + ";DAY=W15D2";
		}
		var newurl = basePath + params;
		var URLvars = getVarsFromURL();
		if (URLvars["TA"]) newurl += ";TA=" + URLvars["TA"];
		return newurl;
	}
}

function gotoCurrentPage(section)
{
	var basePath = "../coursematerial/day.htm";
	var schedType = getSchedType(section);
	
	var wd = DateToWeekDay(new Date(),schedType);
	if (wd.IsValid())
	{
		var params = "?SEC=" + section + ";DAY=" + wd.ShortString();
		var newurl = basePath + params;
		var URLvars = getVarsFromURL();
		if (URLvars["TA"]) newurl += ";TA=" + URLvars["TA"];
		document.location = newurl;
	}
	else
	{
		var today = new Date();
		if (today.getTime() < startofterm.getTime()) {
			//alert("The semester hasn't started yet.  Redirecting to first day of classes.");
			var params = "?SEC=" + section + ";DAY=W01D2";
		} 
		else if (today.getTime() > endofterm.getTime()) {
			//alert("The semester has ended.  Redirecting to last day of classes.");
			var params = "?SEC=" + section + ";DAY=W15D2";
		}
		var newurl = basePath + params;
		var URLvars = getVarsFromURL();
		if (URLvars["TA"]) newurl += ";TA=" + URLvars["TA"];
		document.location = newurl;
	}
}

// this is the same as above with a different base path (
function gotoSection(section)
{
	var basePath = "coursedocs/coursematerial/day.htm";
	var schedType = getSchedType(section);
	
	
	var wd = DateToWeekDay(new Date(),schedType);
	if (wd.IsValid())
	{
		var params = "?SEC=" + section + ";DAY=" + wd.ShortString();
		var newurl = basePath + params;
		document.location = newurl;
	}
	else
	{
		var today = new Date();
		if (today.getTime() < startofterm.getTime()) {
			//alert("The semester hasn't started yet.  Redirecting to first day of classes.");
			var params = "?SEC=" + section + ";DAY=W01D1";
		} 
		else if (today.getTime() > endofterm.getTime()) {
			//alert("The semester has ended.  Redirecting to last day of classes.");
			var params = "?SEC=" + section + ";DAY=W15D2";
		}
		var newurl = basePath + params;
		document.location = newurl;
	}
}




// This function looks at the page currently loaded and returns the date that it corresponds to in an object format
function CurrentPageDate() {
	
	var URLvars = getVarsFromURL();
	var wd = ShortStringToWeekDay(URLvars['DAY'],getSchedType(URLvars['SEC']));
	
	return wd;
			
}

/* ======================================================================
FUNCTION:	GetCalendarDay 
 
INPUT: 		none.

RETURN:		the day of the week as a string

DESC:			The method returns the day of the week, e.g. "Monday". This is 
				intended to be used as a method of a Date object.

USAGE:		today = new Date();
				document.write(today.getCalendarDay());

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
			  	Netscape Enterprise Server 3.0,
			  	Microsoft IIS/ASP 3.0.
====================================================================== */
// Make GetCalendarDay a method of all Date objects 
Date.prototype.getCalendarDay = GetCalendarDay;
function GetCalendarDay() { 
	var n = this.getDay();
	var dow = new Array(7);
	
	dow[0] = "Sunday"; 
	dow[1] = "Monday"; 
	dow[2] = "Tuesday"; 
	dow[3] = "Wednesday"; 
	dow[4] = "Thursday"; 
	dow[5] = "Friday"; 
	dow[6] = "Saturday";
	
	return dow[n]; 
} // end GetCalendarDay


/* ======================================================================
FUNCTION:	GetCalendarMonth 
 
INPUT: 		none.

RETURN:		the month as a string

DESC:			The function returns the month, e.g. "February". 
				This is intended to be used as a method of a Date object.

USAGE:		today = new Date();
				document.write(today.getCalendarMonth());

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
			  	Netscape Enterprise Server 3.0,
			  	Microsoft IIS/ASP 3.0.
====================================================================== */
// Make GetCalendarMonth a method of all Date objects
Date.prototype.getCalendarMonth = GetCalendarMonth;
function GetCalendarMonth() { 
	var n = this.getMonth();
	var moy = new Array(12);
	
	moy[0] = "January" 
	moy[1] = "February" 
	moy[2] = "March" 
	moy[3] = "April" 
	moy[4] = "May" 
	moy[5] = "June" 
	moy[6] = "July" 
	moy[7] = "August" 
	moy[8] = "September" 
	moy[9] = "October" 
	moy[10] = "November" 
	moy[11] = "December";
	
	return moy[n];
} // end GetCalendarMonth


/* ======================================================================
FUNCTION:	GetAbbrevCalendarMonth 
 
INPUT: 		none.

RETURN:		the month as am abbreviated string

DESC:			The function returns the month, e.g. "Feb". 
				This is intended to be used as a method of a Date object.

USAGE:		today = new Date();
				document.write(today.getAbbrevCalendarMonth());

PLATFORMS:	Netscape Navigator 3.01 and higher,
			  	Microsoft Internet Explorer 3.02 and higher,
			  	Netscape Enterprise Server 3.0,
			  	Microsoft IIS/ASP 3.0.
====================================================================== */
// Make GetCalendarMonth a method of all Date objects
Date.prototype.getAbbrevCalendarMonth = GetAbbrevCalendarMonth;
function GetAbbrevCalendarMonth() { 
	var n = this.getMonth();
	var moy = new Array(12);
	
	moy[0] = "Jan" 
	moy[1] = "Feb" 
	moy[2] = "Mar" 
	moy[3] = "Apr" 
	moy[4] = "May" 
	moy[5] = "Jun" 
	moy[6] = "Jul" 
	moy[7] = "Aug" 
	moy[8] = "Sept" 
	moy[9] = "Oct" 
	moy[10] = "Nov" 
	moy[11] = "Dec";
	
	return moy[n];
} // end GetCalendarMonth




function writeCalendar(section,month)

{
	// the meat of this thing should be  7x12 table where the top two rows are headers for the month name and day labels
	//var examdate1 = new Date(2004,2,04);
	//var examdate2 = new Date(2004,3,08);
	//var examdate3 = new Date(2004,3,29);
	var startdate = new Date(startofterm.getFullYear(),month,1);
	var startday = startdate.getDay();
	var currentdate = new Date(startofterm.getFullYear(),month,1);
	document.writeln("<table border=1 cellpadding='2' cellspacing='0'  width='98%'  align='right' bordercolor='#666666'>");
	document.writeln("<tr>");
	document.writeln("<th colspan='7' height='25' class='weekhead' valign='bottom'><h1>" + '<a href="javascript:stepMonth(-1)"><<</a> ' + getMonthFullName(month) + ' <a href="javascript:stepMonth(1)">>></a>' + "</h1></td>");
	document.writeln("</tr>");
	document.writeln("<tr>");
	document.writeln("<th class='weekhead' width='14%'>Sunday</th>");
	document.writeln("<th class='weekhead' width='14%'>Monday</th>");
	document.writeln("<th class='weekhead' width='14%'>Tuesday</th>");
	document.writeln("<th class='weekhead' width='14%'>Wednesday</th>");
	document.writeln("<th class='weekhead' width='14%'>Thursday</th>");
	document.writeln("<th class='weekhead' width='14%'>Friday</th>");
	document.writeln("<th class='weekhead' width='14%'>Saturday</th>");
	document.writeln("</tr>");
	//alert(startday);
	for ( var week = 1; week < 7; week++)
	{
	
		// DAY HEADER ROWS
		
		document.writeln("<tr>");
		for ( var day = 0; day < 7; day++)
		{
			
			if ( week == 1 && day < startday) 
			{
				document.writeln("<td valign='top' bgcolor='#666666'>&nbsp</td>");
			}
			else
			{
				var theday = ((week-1)*7 + day+1) - startday
				currentdate.setDate(theday);
				//alert(((week-1)*7 + day+1) - startday);
				//if (currentdate.getMonth() != month) 
				if (theday > getDaysInMonth(month))
				{
					document.writeln("<td valign='top' bgcolor='#666666'>&nbsp</td>");
				}
				else
				{
					/*if (currentdate.getTime() == examdate1.getTime() || currentdate.getTime() == examdate2.getTime() || currentdate.getTime() == examdate3.getTime()) 
					{
						document.writeln("<th valign='top'>" + currentdate.getDate() + "&nbsp;&nbsp;&nbsp; EXAM 7:30pm</th>");
					}*/
					checkdate = getKeyDateText(currentdate);
					//alert("checkdate = " + checkdate);
					if (checkdate != false)
					{
						//alert("checkdate = " + checkdate);
						document.writeln("<th valign='top'>" + currentdate.getDate() + "&nbsp;&nbsp;&nbsp; " + checkdate + "</th>");
					}
					//else if (currentdate.getTime() == endofterm.getTime())
					//{
					//	document.writeln("<th valign='top'>" + currentdate.getDate() + "<small>&nbsp;Last day of classes</small></th>");
					//}
					else
					{
						document.writeln("<th valign='top'>" + currentdate.getDate() + "</th>");
					}
					
				}
			}
			
		} 
		document.writeln("</tr>");
		
		
		
		
		// CONTENT ROWS
		currentdate = new Date(startofterm.getFullYear(),month,1);
		document.writeln("<tr>");
		for ( var day = 0; day < 7; day++)
		{
			var theday = ((week-1)*7 + day+1) - startday;
			
			if ( week == 1 && day < startday) 
			{
				document.writeln("<td valign='top' height='70' bgcolor='#666666'>&nbsp</td>");
			}
			else
			{
				
				currentdate.setDate(theday);

				classtoday = DateToWeekDay(currentdate,getSchedType(section));
				//alert(((week-1)*7 + day+1) - startday);
				//alert("theday = " + theday + " getDaysInMonth() = " + getDaysInMonth(month));
				if (theday > getDaysInMonth(month))
				{
					document.writeln("<td valign='top' bgcolor='#666666'>&nbsp</td>");
				}
				else
				{
					
					
					//alert(currentdate.toString() + " " + classtoday.GetDate().toString());
					//if (classtoday != false && presentations[classtoday] != null) 
					//alert("Class " + classtoday.GetDate().getDate() + " " + currentdate.getDate());
					if (classtoday.GetDate().getDate() == currentdate.getDate() && presentations[classtoday.ShortString()] != null) 
					{
						dayinfo =  (presentations[classtoday.ShortString()].shortTitle[section] == null) ? (presentations[classtoday.ShortString()].shortTitle['DEFAULT']) : (presentations[classtoday.ShortString()].shortTitle[section])
						//alert("Class " + classtoday.ShortString() + " " + dayinfo);
						linkstring = '<a href="javascript:gotoClassPage(' + "'" + section + "','" + classtoday.ShortString() + "'" + ')">';
						document.writeln("<td valign='top' height='70'><font color='#000000'>" + linkstring + dayinfo + "</a><br>"); //+ "</td>");
						//ListExperimentNames(classtoday);
						ListExperimentNames(section,classtoday);
						if (checkProblemSetDue(section,currentdate) != false) document.writeln("<br><font color='red' size='-1'>" + checkProblemSetDue(section,currentdate) + "</font><br>");
						if (checkMPProblemSetDue(section,currentdate) != false) document.writeln("<br><font color='red' size='-1'>" + checkMPProblemSetDue(section,currentdate) + "</font><br>");
						
						document.writeln("</font></td>");
					}
					else
					{
						if (day == 0  && classtoday.week <= classtoday.finalWeekInt) 
						{
							//alert("SUNDAY: " + currentdate.toString());
							document.writeln("<td valign='top' height='70'>");
							document.writeln("<small><b>Week " + classtoday.week + "</b></small><br>");
							if (checkProblemSetDue(section,currentdate) != false) document.writeln("<br><font color='red' size='-1'>" + checkProblemSetDue(section,currentdate) + "</font><br>");
							if (checkMPProblemSetDue(section,currentdate) != false) document.writeln("<br><font color='red' size='-1'>" + checkMPProblemSetDue(section,currentdate) + "</font><br>");
						
							document.writeln("</td>");
						}
						else
						{
							//document.writeln("<td valign='top'>&nbsp</td>");
							document.writeln("<td valign='top'>");
							if (checkProblemSetDue(section,currentdate) != false && checkMPProblemSetDue(section,currentdate) == false) {
								document.writeln("<font color='red' size='-1'>" + checkProblemSetDue(section,currentdate) + "</font></td>");
							} else if (checkProblemSetDue(section,currentdate) == false && checkMPProblemSetDue(section,currentdate) != false) {
								document.writeln("<font color='red' size='-1'>" + checkMPProblemSetDue(section,currentdate) + "</font></td>");
							} else if (checkProblemSetDue(section,currentdate) != false && checkMPProblemSetDue(section,currentdate) != false) {
								document.writeln("<font color='red' size='-1'>" + checkProblemSetDue(section,currentdate) + "</font><br><br>");
								document.writeln("<font color='red' size='-1'>" + checkMPProblemSetDue(section,currentdate) + "</font></td>");
							} else {
								document.writeln("&nbsp</td>");
							}
						}
					}
				}
			}
			
		} 
		document.writeln("</tr>");
	}
	document.writeln("</table>");
}


// OFFICE HOURS CALENDAR
// Amended by Eric Hudson 11-29-05 to put in days before beginning of month and after end of month so that people can see what is coming up
function writeOfficeHoursCalendar(section,month)
{
	// the meat of this thing should be  7x12 table where the top two rows are headers for the month name and day labels
	//var examdate1 = new Date(2004,2,04);
	//var examdate2 = new Date(2004,3,08);
	//var examdate3 = new Date(2004,3,29);
	var startdate = new Date(startofterm.getFullYear(),month,1);
	var startday = startdate.getDay();
	var currentdate = new Date(startofterm.getFullYear(),month,1);
	document.writeln("<table border=1 cellpadding='2' cellspacing='0'  width='98%'  align='right' bordercolor='#666666'>");
	document.writeln("<tr>");
	document.writeln("<th colspan='7' height='25' class='weekhead' valign='bottom'><h1>" + '<a href="javascript:stepOfficeHourMonth(-1)"><<</a> ' + getMonthFullName(month) + ' <a href="javascript:stepOfficeHourMonth(1)">>></a>' + "</h1></td>");
	document.writeln("</tr>");
	document.writeln("<tr>");
	document.writeln("<th class='weekhead' width='14%'>Sunday</th>");
	document.writeln("<th class='weekhead' width='14%'>Monday</th>");
	document.writeln("<th class='weekhead' width='14%'>Tuesday</th>");
	document.writeln("<th class='weekhead' width='14%'>Wednesday</th>");
	document.writeln("<th class='weekhead' width='14%'>Thursday</th>");
	document.writeln("<th class='weekhead' width='14%'>Friday</th>");
	document.writeln("<th class='weekhead' width='14%'>Saturday</th>");
	document.writeln("</tr>");
	//alert(startday);
	for ( var week = 1; week < 7; week++)
	{
	
		// DAY HEADER ROWS
		document.writeln("<tr>");
		for ( var day = 0; day < 7; day++)
		{
			var theday = ((week-1)*7 + day+1) - startday
			var year = startofterm.getFullYear();
			if (theday < 1) // DAYS FROM END OF LAST MONTH
			{
				var lastMonth = parseInt(month) - 1;
				if (lastMonth < 0) 
				{
					lastMonth = 11;
					year -= 1;
				}
				theday += (getDaysInMonth(lastMonth));
				currentdate.setFullYear(year,lastMonth,theday);
			}
			else if (theday > getDaysInMonth(month))	// past the end of this month, try wrapping to next
			{
				if (day==0) 
				{	
					day = 7; 
					continue;	// don't put in the last line if we are already in the next month
				}
				var nextMonth = 1 + parseInt(month);
				var year = startofterm.getFullYear();
				if (nextMonth > 11) 
				{
					nextMonth = 0;
					year += 1;
				}
				theday -= (getDaysInMonth(month));
				currentdate.setFullYear(year,nextMonth,theday);
			}
			else // Normal day this month
			{
				currentdate.setFullYear(year,month,theday);
			}	

			checkdate = getKeyDateText(currentdate);
			if (checkdate != false)
			{
				document.writeln("<th valign='top'>" + currentdate.getDate() + "&nbsp;&nbsp;&nbsp; " + checkdate + "</th>");
			}
			else if (currentdate.getTime() == endofterm.getTime())
			{
				document.writeln("<th valign='top'>" + currentdate.getDate() + "<small>&nbsp;Last day of classes</small></th>");
			}
			else
			{
				document.writeln("<th valign='top'>" + currentdate.getDate() + "</th>");
			}
		} 
		document.writeln("</tr>");
		
		
		
		
		// CONTENT ROWS
		currentdate = new Date(startofterm.getFullYear(),month,1);
		document.writeln("<tr>");
		for ( var day = 0; day < 7; day++)
		{
			var theday = ((week-1)*7 + day+1) - startday
			var year = startofterm.getFullYear();
			if (theday < 1) // DAYS FROM END OF LAST MONTH
			{
				var lastMonth = parseInt(month) - 1;
				if (lastMonth < 0) 
				{
					lastMonth = 11;
					year -= 1;
				}
				theday += (getDaysInMonth(lastMonth));
				currentdate.setFullYear(year,lastMonth,theday);
			}
			else if (theday > getDaysInMonth(month))	// past the end of this month, try wrapping to next
			{
				if (day==0) 
				{	
					day = 7; 
					continue;	// don't put in the last line if we are already in the next month
				}
				var nextMonth = 1 + parseInt(month);
				var year = startofterm.getFullYear();
				if (nextMonth > 11) 
				{
					nextMonth = 0;
					year += 1;
				}
				theday -= (getDaysInMonth(month));
				currentdate.setFullYear(year,nextMonth,theday);
			}
			else // Normal day this month
			{
				currentdate.setFullYear(year,month,theday);
			}	
			document.writeln("<td valign='top' height='70'><small><font color='#000000'>"); //+ "</td>");
			if (currentdate.getTime() <= endofterm.getTime()) {
				for (var blah in sections) {
					sections[blah].WriteRegularOfficeHours(currentdate);
				}
			}
			for (var blah in sections) {
				sections[blah].WriteSpecialOfficeHours(currentdate);
			}
			document.writeln("</font></small>&nbsp;</td>");
		} 
		document.writeln("</tr>");
	}
	document.writeln("</table>");
}


function isLeapYear(year)
{
return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 1 : 0;
}

function isLeap()
{
var d = new Date();
return isLeapYear(d.getFullYear());
}

function getDaysInMonth(month)
{
	
	var moy = new Array(12);
	
	moy[0] = 31 
	if (isLeap()) {
		moy[1] = 29; 
	} else {
		moy[1] = 28;
	}
	moy[2] = 31
	moy[3] = 30
	moy[4] = 31 
	moy[5] = "Jun" 
	moy[6] = "Jul" 
	moy[7] = "Aug" 
	moy[8] = 30 
	moy[9] = 31 
	moy[10] = 30 
	moy[11] = 31;
	
	return moy[month];
}

function getMonthFullName(month) { 
	
	var moy = new Array(12);
	
	moy[0] = "January" 
	moy[1] = "February" 
	moy[2] = "March" 
	moy[3] = "April" 
	moy[4] = "May" 
	moy[5] = "June" 
	moy[6] = "July" 
	moy[7] = "August" 
	moy[8] = "September" 
	moy[9] = "October" 
	moy[10] = "November" 
	moy[11] = "December";
	
	return moy[month];
} 


function getSchedType(section)
{
	var schedType;
	schedType = scheduleMap[section];
	
	return schedType;
}


function intToDayName(myInt){
	var days = new Array(7);
	days[0] = "Sunday";
	days[1] = "Monday";
	days[2] = "Tuesday";
	days[3] = "Wednesday";
	days[4] = "Thursday";
	days[5] = "Friday";
	days[6] = "Saturday";
	
	return days[myInt];
}

function writeCalendarLink(section, theSemester, monthnum){

	if (theSemester == "FALL")
	{
		document.writeln('<a href="../calendar/calendar.htm' + '?SEC=' + section + ';MON=' +(7+monthnum) + '">' + getMonthFullName((7+monthnum)) + '</a>');
	}
	else
	{
		document.writeln('<a href="../calendar/calendar.htm' + '?SEC=' + section + ';MON=' +(monthnum) + '">' + getMonthFullName((monthnum)) + '</a>');
	}
}

function stepMonth(direction) {
	var URLvars = getVarsFromURL();
	var thisMonth = parseInt(URLvars["MON"],10);
	var nextMonth;
	
	var maxMonth = (semester == "FALL") ? (11) : (4);
	var minMonth = (semester == "FALL") ? (8) : (1);
	//alert("semester = " + semester + " max = " + maxMonth + " min = " + minMonth);
	nextMonth = thisMonth + direction;
	//alert("thisMonth = " + thisMonth + " nextMonth = " + nextMonth);
	if (nextMonth > maxMonth) 
	{
		nextMonth = maxMonth;
	}
	if (nextMonth < minMonth)
	{	
		nextMonth = minMonth;
	}
	
	var newUrl = "calendar.htm?SEC=" + URLvars['SEC'] + ";MON=" + nextMonth;
	if (URLvars["TA"]) newUrl += ";TA=" + URLvars["TA"];
	document.location = newUrl;
}
	

function stepOfficeHourMonth(direction) {
	var URLvars = getVarsFromURL();
	var thisMonth = parseInt(URLvars["MON"],10);
	var nextMonth;
	
	var maxMonth = (semester == "FALL") ? (11) : (4);
	var minMonth = (semester == "FALL") ? (8) : (1);
	//alert("semester = " + semester + " max = " + maxMonth + " min = " + minMonth);
	nextMonth = thisMonth + direction;
	//alert("thisMonth = " + thisMonth + " nextMonth = " + nextMonth);
	if (nextMonth > maxMonth) 
	{
		nextMonth = maxMonth;
	}
	if (nextMonth < minMonth)
	{	
		nextMonth = minMonth;
	}
	
	var newUrl = "office.htm?SEC=" + URLvars['SEC'] + ";MON=" + nextMonth;
	if (URLvars["TA"]) newUrl += ";TA=" + URLvars["TA"];
	document.location = newUrl;
}
	


<!--
function gotoNextDay()
{
	//this function is for buttons on the "outline" pages that will allow you to move forward and backwards through the days.
	var weekString;
	var dayString;
	var weekInt;
	var dayInt;
	var newWeekInt;
	var newDayInt;
	//var thisPath = document.location.href;
	//var thisPage = thisPath.substring((1 + thisPath.lastIndexOf("/")));
	var finalWeekInt = 15;
	var finalDayInt = 2;
		
	var URLvars = getVarsFromURL();
	var wd = URLvars["DAY"];
	
	weekString = wd.substr(1,2);
	dayString = wd.substr(4,4);
	
	weekInt = parseInt(weekString,10);
	dayInt = parseInt(dayString,10);
	
	if (dayInt < 3) 
	{
		newDayInt = dayInt + 1;
		newWeekInt = weekInt;
	}
	else
	{
		newDayInt = 1;
		newWeekInt = weekInt + 1;
	}
	
	if ((newWeekInt == finalWeekInt))
	{
		//if it goes beyond the final week of class, sit on the last day.
		//newPath = final week path.... or
		//window.alert("newWeekInt < 1 !!!!");
		if (newDayInt > finalDayInt) 
		{
			newDayInt = finalDayInt;
			window.alert("This is the last day of class this semester.");
		}
		//return 0;
	}
	
	wkday = new ClassWeekDay(newWeekInt,newDayInt,getSchedType(URLvars["SEC"]))
	
	var locString = "day.htm" + "?SEC=" + URLvars["SEC"] + ";DAY=" + wkday.ShortString();
	if (URLvars["TA"]) locString += ";TA=" + URLvars["TA"];
	
	document.location.href = locString;
}
	


function gotoPrevDay()
{
	//this function is for buttons on the "outline" pages that will allow you to move forward and backwards through the days.
	var weekString;
	var dayString;
	var weekInt;
	var dayInt;
	var newWeekInt;
	var newDayInt;
	var thisPath = document.location.href;
	var thisPage = thisPath.substring((1 + thisPath.lastIndexOf("/")));
	
	
	var URLvars = getVarsFromURL();
	var wd = URLvars["DAY"];
	
	weekString = wd.substr(1,2);
	dayString = wd.substr(4,4);
	
	weekInt = parseInt(weekString,10);
	dayInt = parseInt(dayString,10);
	
	if (dayInt > 1) 
	{
		newDayInt = dayInt - 1;
		newWeekInt = weekInt;
	}
	else
	{
		newDayInt = 3;
		newWeekInt = weekInt - 1;
	}
	
	// Now construct new pathname using these new days
	if ((newWeekInt < 1))
	{
		//if it goes beyond the final week of class, sit on the last day.
		//newPath = final week path.... or
		//window.alert("newWeekInt < 1 !!!!");
		newWeekInt = 1;
		newDayInt = 1;
		window.alert("This is the first day of class this semester.");
	}
	
	wkday = new ClassWeekDay(newWeekInt,newDayInt,getSchedType(URLvars["SEC"]))
	
	var locString = "day.htm" + "?SEC=" + URLvars["SEC"] + ";DAY=" + wkday.ShortString();
	
	if (URLvars["TA"]) locString += ";TA=" + URLvars["TA"];
	document.location.href = locString;
}
// -->



<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->
<!-- Begin
function monthPage(section) {
//alert("monthPage AM I BEING CALLED?");
var today = new Date();

var m = new Array(1,1,2,3,4,8,8,8,8,9,10,11);
var locString = ("../calendar/calendar.htm" + "?SEC=" + section + ";MON=" + m[today.getMonth()]); 
//alert(locString);
var URLvars = getVarsFromURL();
if (URLvars["TA"]) locString += ";TA=" + URLvars["TA"];
window.location = locString;
<!-- window.location = "http://" + window.location.hostname + m[today.getMonth()]; -->
}

function monthPageOffice(section) {
//alert("monthPage AM I BEING CALLED?");
var today = new Date();

var m = new Array(1,1,2,3,4,8,8,8,8,9,10,11);
/* Modified 11/11/08 by Alan Guth.  Previously it was
        var m = new Array(1,1,2,3,4,4,4,8,8,9,1,1);
   The array is designed to remap months to skip months when there
   are no classes, so Jan shows page for Feb, and June, July, and
   Aug show pages for Sept.  I have changed m[] to match that of
   monthPage().  The previous m[] mapped Nov and Dec to Feb, which
   made no sense at all. */
var locString = ("../resources/office.htm" + "?SEC=" + section + ";MON=" + m[today.getMonth()]); 
//alert(locString);
var URLvars = getVarsFromURL();
if (URLvars["TA"]) locString += ";TA=" + URLvars["TA"];
window.location = locString;
<!-- window.location = "http://" + window.location.hostname + m[today.getMonth()]; -->
}

//////////////////////////////////////////////////////  URL LINKING CODE


<!--
// The "gotoSpecific" routines are called both from the "goto Today's" functions and from routines that want to list
// materials from other days
function linkSpecificPPT(section,wdss)
{
	// the basePath should be something up above the section folders
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		//newPath = basePath + "materials/presentations/" + "PPT_" + wdss + "/" + "PPT_" + wdss + ".ppt";
		newPath = basePath + "materials/Presentations/" + "PPT_" + wdss + "/";
	}
	else
	{
		//newPath = basePath + section + "/materials/presentations/" + "PPT_" + wdss + "/" + "PPT_" + wdss + ".ppt";
		newPath = basePath + section + "/materials/Presentations/" + "PPT_" + wdss + "/";
	}
	return newPath;
	//newPath = basePath + wdss;
}

function gotoSpecificPPT(section,wdss)
{
	// the basePath should be something up above the section folders
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		//newPath = basePath + "materials/presentations/" + "PPT_" + wdss + "/" + "PPT_" + wdss + ".ppt";
		newPath = basePath + "materials/Presentations/" + "PPT_" + wdss + "/";
	}
	else
	{
		//newPath = basePath + section + "/materials/presentations/" + "PPT_" + wdss + "/" + "PPT_" + wdss + ".ppt";
		newPath = basePath + section + "/materials/Presentations/" + "PPT_" + wdss + "/";
	}
	
}


function linkSpecificPRS(section,wdss)
{
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/PRS/PRS_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/PRS/PRS_" + wdss + ".pdf";
	}
	return newPath;
}


function gotoSpecificPRS(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/materials/PRS/PRS_"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/PRS/PRS_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/PRS/PRS_" + wdss + ".pdf";
	}
	
	//newPath = basePath + wdss + ".pdf";
	document.location.href = newPath;
}


function linkSpecificPRS_TA(section,wdss)
{
	var loc = String(document.location);
	var basePath = loc.substring(0, loc.lastIndexOf("/"));
	basePath = basePath.substring(0, basePath.lastIndexOf("/"));
	basePath = basePath.substring(0, basePath.lastIndexOf("/"));
	basePath = basePath + "/";

	basePath = basePath.replace("http","https");

	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/PRS/Raw/PRS_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/PRS/Raw/PRS_" + wdss + ".pdf";
	}
	
	return newPath;
}


function gotoSpecificPRS_TA(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/materials/PRS/PRS_"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	//var basePath = "../../";
	var loc = String(document.location);
				//alert(loc + " " + String(loc).lastIndexOf("/"));
	var basePath = loc.substring(0, loc.lastIndexOf("/"));
	basePath = basePath.substring(0, basePath.lastIndexOf("/"));
	basePath = basePath.substring(0, basePath.lastIndexOf("/"));
	basePath = basePath + "/";

	basePath = basePath.replace("http","https");

	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/PRS/Raw/PRS_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/PRS/Raw/PRS_" + wdss + ".pdf";
	}
	
	//newPath = basePath + wdss + ".pdf";
	document.location.href = newPath;
}

function linkSpecificQA(section,wdss)
{
	var basePath = "../../";
	var newPath;
	var wd = wdss.substr(0,3);	// strip out the day since we will only have one QA a week
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/QA/QA_" + wd + ".htm";
	}
	else
	{
		newPath = basePath +  section + "/materials/QA/QA_" + wd + ".htm";
	}
	return newPath;
}


function gotoSpecificQA(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/materials/QA/QA_"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	var wd = wdss.substr(0,3);	// strip out the day since we will only have one QA a week
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/QA/QA_" + wd + ".htm";
	}
	else
	{
		newPath = basePath +  section + "/materials/QA/QA_" + wd + ".htm";
	}
	
	//newPath = basePath + wdss + ".htm";
	document.location.href = newPath;
}

// September 4, 2007 (EWH):  Changed from HTML to whole file PDF, which allows embedded video and actually works now
function linkSpecificPresentationHTML(section,wdss)
{
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Presentations/Presentation_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Presentations/Presentation_" + wdss + ".pdf";
	}
	return newPath;
}

// September 4, 2007 (EWH):  Changed from HTML to whole file PDF, which allows embedded video and actually works now
function gotoSpecificPresentationHTML(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/presentations/"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Presentations/Presentation_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Presentations/Presentation_" + wdss + ".pdf";
	}
	
	//newPath = basePath + "Presentation_" + wdss + ".htm";
	document.location.href =  newPath;
}

function linkSpecificPresentationPDF(section,wdss)
{
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Presentations/SelectPresentation_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Presentations/SelectPresentation_" + wdss + ".pdf";
	}
	return newPath;
}

function gotoSpecificPresentationPDF(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/presentations/"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Presentations/SelectPresentation_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Presentations/SelectPresentation_" + wdss + ".pdf";
	}
	
	//newPath = basePath + "Presentation_" + wdss + ".pdf";
	document.location.href = newPath;
}


function linkSpecificPresSummary(section,wdss)
{
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Summaries/Summary_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Summaries/Summary_" + wdss + ".pdf";
	}
	
	return newPath;
}

function gotoSpecificPresSummary(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/presentations/"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	var basePath = "../../";
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = basePath + "materials/Summaries/Summary_" + wdss + ".pdf";
	}
	else
	{
		newPath = basePath + section + "/materials/Summaries/Summary_" + wdss + ".pdf";
	}
	
	//newPath = basePath + "Presentation_" + wdss + ".pdf";
	document.location.href = newPath;
}

function gotoSpecificTeacherSummary(section,wdss)
{
	//var basePath = "http://web.mit.edu/8.02t/www/L01/presentations/"
	//var basePath = "http://web.mit.edu/8.02t/www/";
	//var basePath = "../../";
	var loc = String(document.location);
				//alert(loc + " " + String(loc).lastIndexOf("/"));
				var taPath = loc.substring(0, loc.lastIndexOf("/"));
				taPath = taPath.substring(0, taPath.lastIndexOf("/"));
				taPath = taPath.substring(0, taPath.lastIndexOf("/"));
				taPath = taPath.replace("http","https");
	var newPath;
	if (section == "DEFAULT")
	{
		newPath = taPath + "/materials/TeacherSummaries/TeacherSummary_" + wdss + ".pdf";
	}
	else
	{
		newPath = taPath + section + "/materials/TeacherSummaries/TeacherSummary_" + wdss + ".pdf";
	}
	
	//newPath = basePath + "Presentation_" + wdss + ".pdf";
	//alert(newPath);
	document.location.href = newPath;
}

function linkPPT(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate ppt files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	return	linkSpecificPPT(section,weekDay.ShortString());
}

function linkPRS(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate prs files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	// alert("The week day is "+weekDay.week+","+weekDay.day+" and is valid? "+weekDay.IsValid());
	return linkSpecificPRS(section,weekDay.ShortString());
}

function linkPRS_TA(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate prs files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	// alert("The week day is "+weekDay.week+","+weekDay.day+" and is valid? "+weekDay.IsValid());
	return linkSpecificPRS_TA(section,weekDay.ShortString());
}

function linkQA(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate prs files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	return linkSpecificQA(section,weekDay.ShortString());
}

function linkPresentationHTML(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate ppt files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	return linkSpecificPresentationHTML(section,weekDay.ShortString());	
}	

function linkPresentationPDF(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate ppt files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	return linkSpecificPresentationPDF(section,weekDay.ShortString());
}	

function linkPresSummary(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate ppt files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	return linkSpecificPresSummary(section,weekDay.ShortString());
}	

function gotoTeacherSummary(section)
{
	//this function is for buttons on the "outline" pages that will allow you to get the appropriate ppt files
	var weekDay = CurrentPageDate();	// get the weeek and day of this page
	if (weekDay.IsValid())
	{
		gotoSpecificTeacherSummary(section,weekDay.ShortString());
	}
	else
	{
		window.alert("To view a presentation select a day within the semester");
	}
}	



//for (var secs in InClass['W01D2'].InClass)
//{
//	alert("sections: " + secs + " InClass[secs]: " + InClass['W01D2'].InClass[secs]);
//}
-->
