//Initialize the visual elements: 'Drawing' the search result table and the course table
var header = buildHeader();
var schedHeader = buildSchedHeader();

var courses;

//Defining the color cycle for the course view
var clor = new Array("00f","0f0","f00","0ff","f0f","ff0","ccc");

//Setting up the XML Structure to hold the schedule
if (document.implementation && document.implementation.createDocument)	{
	schedXML = document.implementation.createDocument("", "", null);
} else if (window.ActiveXObject) {
	schedXML = new ActiveXObject("Microsoft.XMLDOM");
}
var root = schedXML.createElement("schedule");
schedXML.appendChild(root);

//A little visual effect here. Shows and hides the spinning loading animation appropriately...
var myGlobalHandlers = {
	onCreate: function(){
		Element.show('systemWorking');
	},
	onComplete: function() {
		if(Ajax.activeRequestCount == 0){
			Element.hide('systemWorking');
		}
	}
};

Ajax.Responders.register(myGlobalHandlers);

/*
Function: buildScale()
Purpose: 'Draws' the series of lines used to delimit the schedule grid.
Arguments: none
Returns: (String) the HTML markup of the schedule grid
*/
function buildScale(){
	var holder2 = document.createElement('div');
	var holder = document.createElement('div');
	holder.setAttribute('id', 'sTable');
	var range = (procTime("11:30PM")-procTime("7:30AM"));
	for (i=0; i<range; i+=15) {
		var sunit = document.createElement('div');
		var mins = i+procTime("7:30AM");
		sunit.className = 'scalecell';
		if (mins % 60 == 0){
			var timep = Math.floor(mins / 60);
			tod = "AM";
			if (timep >= 12) {tod = "PM"}
			if (timep > 12) {timep -= 12;}
			var timestamp = document.createTextNode(timep);
			
			sunit.appendChild(timestamp);
			sunit.appendChild(document.createElement("br"));
			var todtag = document.createElement("span");
			todtag.className = "tod";
			todtag.appendChild(document.createTextNode(tod));
			sunit.appendChild(todtag);
			
			sunit.className = 'timestamp';
		}
		var stp = Math.round(i / range * 1000)/10;
		var meep = stp + "%";
		sunit.setAttribute('left', meep);
		holder.appendChild(sunit);
	}
	holder2.appendChild(holder);
	return holder2;
}

/*
Function: buildHeader()
Purpose: Creates the table header for the course Search Results
Arguments: none
Returns: (String) HTML markup of the table header
*/
function buildHeader(){
	var header = document.createElement('tr');
	var n1 = document.createElement("th");
	n1.className = 'cid';
	n1.appendChild(document.createTextNode("Course Number"));
	var n2 = document.createElement("th");
	n2.appendChild(document.createTextNode("Course Title"));
	var n3 = document.createElement("th");
	n3.appendChild(document.createTextNode("Open Seats"));
	var n4 = document.createElement("th");
	n4.appendChild(document.createTextNode("Credits"));
	var n5 = document.createElement("th");
	n5.appendChild(document.createTextNode("Time"));
	var n6 = document.createElement("th");
	n6.appendChild(document.createTextNode("Instructor"));
	var n7 = document.createElement("th");
	n7.appendChild(document.createTextNode(" "));
	header.appendChild(n1);
	header.appendChild(n2);
	header.appendChild(n3);
	header.appendChild(n4);
	header.appendChild(n6);
	header.appendChild(n5);
	header.appendChild(n7);
	return header;
}

/*
Function: buildSchedHeader()
Purpose: Creates the table header for the user's schedule listing
Arguments: none
Returns: (String) HTML markup of the table header
*/
function buildSchedHeader(){
	var header = document.createElement('tr');
	var n1 = document.createElement("th");
	n1.appendChild(document.createTextNode("Course Number"));
	var n2 = document.createElement("th");
	n2.appendChild(document.createTextNode("Course Title"));
	var n3 = document.createElement("th");
	n3.appendChild(document.createTextNode("Color"));
	var n4 = document.createElement("th");
	n4.appendChild(document.createTextNode("Options"));
	header.appendChild(n1);
	header.appendChild(n2);
	header.appendChild(n3);
	header.appendChild(n4);
	return header;
}

/*
Function: searchCourses()
Purpose: Parses Form data and submits a search to the course retrieval system
Arguments: none
Returns: nothing
*/
function searchCourses()	{
	var query = $F('cquery');
	var t = $F('lstTerms');
	var url = 'getCourse.php';
	var pars = 'course=' + query + '&term=' + t;
	var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: showResponse , onFailure:failFunc});
}

/*
Function: showResponse()
Purpose: process the results of a course search, and write them to the results table
Arguments:
	req (Object): Automatically passed by the Ajax Request initialized in searchCourses()
Returns: nothing
*/
function showResponse(req)	{
	var response = req.responseXML;
	courses = response.getElementsByTagName("course");
	blob = document.createElement('table');
	blob.className = 'course';
	blob.appendChild(header);
	
	for (var i=0; i<courses.length; i++){
		var x = document.createElement('tr');
		x.setAttribute("onclick", "previewTimes(" + i + ");" );
		var kids = courses[i].childNodes;
		for (var j=0; j<5; j++){
			var z = document.createElement('td');
			var y = document.createTextNode(kids[j].firstChild.nodeValue);
			z.appendChild(y);
			x.appendChild(z);
		}
		var z = document.createElement('td');
		var y = document.createElement('a');
		var w = document.createTextNode('view times');
		y.appendChild(w);
		y.setAttribute("href", "#");
		y.setAttribute("onclick", "previewTimes(" + i + ");" );
		//z.appendChild(y);
		var y = document.createElement('a');
		var w = document.createTextNode('preview');
		y.appendChild(w);
		y.setAttribute("href", "#");
		y.setAttribute("onclick", "previewTimes(" + i + ");" );
		z.appendChild(y);
		var y = document.createElement('a');
		var w = document.createTextNode('add');
		y.appendChild(w);
		y.setAttribute("href", "#");
		y.setAttribute("onclick", "addCourse(" + i + ");" );
		z.appendChild(y);
		x.appendChild(z);
		blob.appendChild(x);
	}
	show = $('searchResults');
	//show.removeChild(show.firstChild);
	//show.appendChild(blob);
	holder = document.createElement("div");
	holder.appendChild(blob);
	show.innerHTML=holder.innerHTML;
	$('cquery').select();
	
}

/*
Function:
Purpose:
Arguments:
Returns:
*/
function failFunc(originalRequest) {
}

/*
Function: displayLogin
Purpose: makes the Login Panel appear, and masks out the rest of the document
Arguments: none
Returns: nothing
*/
function displayLogin(){
	Element.show('loginScreen');
	//Element.setStyle('loginScreen', $H({display:'block'}) );
	Effect.Appear('loginPanel');
	$('login_email').focus();
}

/*
Function: closeLogin
Purpose: hides the Login Panel
Arguments: none
Returns: nothing
*/
function closeLogin(){
	//Element.show('loginScreen');
	bleh = document.getElementsByClassName('loginform');
	bleh.each( function(item){
		item.reset();
	});
	Element.setStyle('loginScreen', $H({display:'none'}) );
}

/*
Function: doLogin
Purpose:  creates a request to the login script
Arguments: none
Returns: false, for no clear reason
*/
function doLogin(){
	var email = $F('login_email');
	var url = 'dologin.php';
	var pars = 'email=' + email + '&pass=' + $F('login_pass');
	var myAjax = new Ajax.Request( url, { method: 'post', parameters: pars, onComplete: doneLogin, onFailure:failFunc});
	$('loginStatus').innerHTML = "Verifying User...";
	return false;
}

/*
Function: loadUser
Purpose: retrieves a user's schedule information
Arguments: 
	req (Object): automatically provided by the request initialized in doLogin()
Returns: nothing
*/
function loadUser(req){
	$('rawout').innerHTML = req.responseText;
}

/*
Function: doneLogin
Purpose: Checks to see if login was valid
Arguments:
	req (Object): automatically provided by the request intialized in doLogin()
Returns: nothing
*/
function doneLogin(req){
	//$('rawout').innerHTML = "<xmp>" + req.responseText + "</xmp>";
	var response = req.responseXML;
	errors = response.getElementsByTagName("error");
	if (errors.length) {
		$('loginStatus').innerHTML = "<span class='negative'>" + errors[0].firstChild.nodeValue + "</span>";
	}
	success = response.getElementsByTagName("success");
	if (success.length) {
		$('loginStatus').innerHTML = success[0].firstChild.nodeValue;
		$('mainstatus').innerHTML = "Logged In As " + $F('login_email');
	}
}

/*
Function: doneSignUp
Purpose: Notifies user whether or not they were successfully registered
Arguments:
	req (Object): automatically provided by the request intialized in doSignUp()
Returns: nothing
*/
function doneSignUp(req){
	//$('rawout').innerHTML = "<xmp>" + req.responseText + "</xmp>";
	var response = req.responseXML;
	errors = response.getElementsByTagName("error");
	if (errors.length) {
		$('loginStatus').innerHTML = "<span class='negative'>" + errors[0].firstChild.nodeValue + "</span>";
	}
}

/*
Function: doSignUp
Purpose: Submits the signup form and intializes the Request to the registration service
Arguments: none
Returns: nothing
*/
function doSignUp(){
	if ($F('signup_pass') != $F('signup_pass2')){
		$('loginStatus').innerHTML = "<span class='negative'>Passwords must match!</span>";
		$('signup_pass').value = "";
		$('signup_pass2').value = "";
		$('signup_pass').focus();
	} else {
		var email = $F('signup_email');
		var url = 'dosignup.php';
		var pars = 'email=' + email + '&pass=' + $F('signup_pass');
		var myAjax = new Ajax.Request( url, { method: 'post', parameters: pars, onComplete: doneSignUp, onFailure:failFunc});
		$('loginStatus').innerHTML = "Registering User...";
	}
	return false;
}

/*
Function: dayCode
Purpose: convert the day of the week to a usable number for schedule block positioning
Arguments: 
	day (String): String representing the day of the week
Returns: number code for the day of the week
*/
function dayCode(day) {
	//all this needs to become a switch or an array. Weekend Support?
	if (day=="M") {return 0;}
	else if (day=="T") {return 1;}
	else if (day=="W") {return 2;}
	else if (day=="R") {return 3;}
	else if (day=="F") {return 4;}
	return 5;
}

/*
Function: addCourse
Purpose: Adds a course to the user's current schedule
Arguments:
	which (Integer): array index of the course in the search result array
Returns: nothing
*/
function addCourse(which) {
	var bleh = courses[which];
	var toAdd = bleh.cloneNode(true);
	schedXML.documentElement.appendChild(toAdd);
	renderSchedule();
	
}

/*
Function: removeCourse
Purpose: Removes a course from the user's current schedule
Arguments:
	which (Integer): array index of the course in the user's course array
Returns: nothing
*/
function removeCourse(which) {
	var bleh = schedXML.firstChild.childNodes[which];
	schedXML.firstChild.removeChild(bleh);
	renderSchedule();
}

/*
Function: renderSchedule
Purpose: generates HTML information for the visual schedule blocks
Arguments: none
Returns: nothing
*/
function renderSchedule() {
					
	schedCourses = schedXML.getElementsByTagName("course");

	blob = document.createElement('table');
	blob.className = 'sched';
	blob.appendChild(schedHeader);
	
	for (var i=0; i<schedCourses.length; i++){
		var x = document.createElement('tr');
		//x.setAttribute("onmouseover", "previewTimes(" + i + ");" );
		var kids = schedCourses[i].childNodes;
		for (var j=0; j<2; j++){
			var z = document.createElement('td');
			var y = document.createTextNode(kids[j].firstChild.nodeValue);
			z.appendChild(y);
			x.appendChild(z);
		}
		var y = document.createElement('td');
		y.setAttribute("style", "width:56px;background:#" + clor[i % 7] + ";border:1px solid black;");
		//y.setAttribute("onclick", "previewTimes(" + i + ");" );
		x.appendChild(y);
		
		var z = document.createElement('td');
		var y = document.createElement('a');
		var w = document.createTextNode('remove');
		y.appendChild(w);
		y.setAttribute("href", "#");
		y.setAttribute("onclick", "removeCourse(" + i + ");" );
		z.appendChild(y);
		x.appendChild(z);

		blob.appendChild(x);
	}
	show = $('yourSchedule');
	//show.removeChild(show.firstChild);
	//show.appendChild(blob);
	holder = document.createElement("div");
	holder.appendChild(blob);
	show.innerHTML=holder.innerHTML;
	
	var schedHTML = "\n";
	for (var i=0; i<schedCourses.length; i++){
		schedHTML += viewTimes((schedCourses[i].childNodes)[5], "acourse", "background:#"+clor[i % 7]+";");
	}
	$('scheduleInfo').innerHTML = schedHTML;
	adjustScale();
	previewTimes(-1);

}

/*
Function: previewTimes
Purpose: Show a shaded preview of how a course block would appear in the user's current schedule
Arguments:
	which (Integer): The index of the course in the search result array
Returns: nothing
*/
function previewTimes(which) {
	if(which==-1) {
		$('timeInfo').innerHTML = "nothing";
	}else{
		var bleh = (courses[which].childNodes)[5];
		$('timeInfo').innerHTML = viewTimes(bleh, "previewcourse");
	}
}

/*
Function: viewTimes
Purpose: generate the HTML div for each course on the visual schedule
Arguments:
	which (Integer): The index of the course in the search result array
Returns: (String) the HTML 
*/
function viewTimes(which, classtype, addStyle) {
	var blocks = which.childNodes;
	respHTML = "<div class='" + classtype + "'>\n";
	for (j=0; j<blocks.length; j++){
		var data = blocks[j].childNodes;
		//alert(data[2].firstChild);
		//respHTML += data[0].firstChild.nodeValue + " " + data[2].firstChild.nodeValue + "-" + data[3].firstChild.nodeValue + "<br/>\n";
		var dow = dayCode(data[0].firstChild.nodeValue);
		var d = data[2].firstChild.nodeValue;
		var d2 = data[3].firstChild.nodeValue;
		var len = (procTime(d2) - procTime(d));
		var st = procTime(d) - procTime("7:30AM");
		var range = (procTime("11:30PM")-procTime("7:30AM"));
		
		var lenp = Math.round(len / range * 1000)/10;
		var stp = Math.round(st / range * 1000)/10;
		respHTML += "<div style='position:absolute;height:38px;width:" + lenp + "%;top:" + (dow * 40 + 70 + Element.getHeight('content')) + "px;left:" + stp + "%;border:1px solid black;" + addStyle + "'>" + data[1].firstChild.nodeValue + "</div>\n";
	}
	respHTML += "</div>";
	return respHTML;
}

/*
Function: procTime
Purpose: processes time string into the minutes since midnight
Arguments:
	what (String): time in string form, hours and minutes
Returns: (Integer) Number of minutes since midnight
*/
function procTime(what) {
	t = new String(what);
	var spot = 1;
	if (t.length == 6) {
		spot = 0;
	}
	hrs = parseInt(t.substr(0,2)) % 12;
	mins = parseInt(t.substr(2+spot,2));
	if (t.indexOf("PM")>0) {
		hrs += 12;
	}
	return hrs*60+mins;
}

/*
Function: adjustScale
Purpose: repositions the scale lines on resize on redraw
Arguments: none
Returns: nothing
*/
function adjustScale(){
	var scaleTop = (30 + Element.getHeight('content'));
	var aruler = $('sTable').childNodes;
	for(i=0; i<aruler.length; i++){
		if (aruler[i].className=="timestamp"){
			var blurp = scaleTop+"px";
		} else {
			var blurp = scaleTop+20+"px";
		}
		nleft = aruler[i].getAttribute('left');
		Element.setStyle(aruler[i], $H({top:blurp,left:nleft}));
		//$('rawout').innerHTML += Element.getStyle(aruler[i], 'left') + " <br/>\n";
	}
}

/*
Function: toggleSearch
Purpose: shows or hides the search pane
Arguments: none
Returns: nothing
*/
function toggleSearch(){
	if (Element.getStyle('searchResults', 'display') != 'none') {
		Element.hide('searchResults');
	} else {
		Element.show('searchResults');
	}
	renderSchedule();
}

/*
Function: loadprocedures
Purpose: sets the function calls upon page loading
Arguments: none
Returns: nothing
*/
function loadprocedures(){
	Element.hide('systemWorking'); //Hide the working animation, since we're not working
	$('scheduleInfo').innerHTML = " ";
	var scaleTable = buildScale(); //Build the schedule header
	$('scaleContainer').innerHTML = scaleTable.innerHTML; //Attatch it to the result listing
	adjustScale(); //Render the scale to the user's window size
}

