var browserIsIE = navigator.appName == "Microsoft Internet Explorer";
var domClassName = browserIsIE ? "className" : "class"; // problems with IE

var beforeElemId = "schedule-source",
 newElemId = "schedule-live",
 sourceElemId = "schedule-source",
 liveHour = [], liveMin = [],
 liveTimeMins = [],
 liveTitle = [],
 liveLink = [],
 titleText = "Show information at ",
 hourOffset = 0,
 liveOffset = 0,
 liveOffsetLast = -Math.Infinity,
 lastMinute = -1;

var liveElemName = ["dt", "dd"],
 liveMissing = "information missing",
 liveElemIndex = [0, 1],
 liveElemClass = ["show-now", "show-next"],
 liveElemText = ["Now playing", "Next show"];

// Returns int date, hour, minute based on user's browser
function liveCurrentTime()
{
	var pcDate = new Date();
	var pcHours = pcDate.getHours();
	var pcMins = pcDate.getMinutes();
	return [timeMins(pcHours, pcMins), pcHours, pcMins];
}

function twoZero(intNum)
{
	return (intNum < 10 ? "0" : "") + String(intNum);
}
function timeStr(hours, minutes)
{
	return twoZero(hours) + ":" + twoZero(minutes);
}
function timeMins(hours, minutes)
{
	return hours * 60 + minutes;
}

function liveUpdate()
{
	var divElem = document.getElementById(newElemId);

	var currentTime = liveCurrentTime();

	// Update header date
	if (lastMinute != currentTime[2]) {
		var divElemHead = divElem.getElementsByTagName("h2");
		divElemHead[0].firstChild.nodeValue = titleText +
		 timeStr(currentTime[1], currentTime[2]);
        lastMinute = currentTime[2];
	}

	// Find current time position
	while (liveOffset < liveTimeMins.length) {
	    if (liveTimeMins[liveOffset] > currentTime[0]) {
	        --liveOffset;
	        break;
	    }
	    ++liveOffset;
	}

	// Only update if something has changed
	if (liveOffset == liveOffsetLast) {
		setTimeout(liveUpdate, 500);
		return;
	}
	liveOffsetLast = liveOffset;

	// Reload page if schedule reaches the end
	if (liveTimeMins.length > 1 && liveOffset == (liveTimeMins.length - 1)) {
		location.reload();
		return;
	}

	// Update definition elements
	var divDt = divElem.getElementsByTagName(liveElemName[0]);
	var divDd = divElem.getElementsByTagName(liveElemName[1]);
	for (var liveIndex = 0; liveIndex < liveElemIndex.length; ++liveIndex) {
	    var tryPos = liveElemIndex[liveIndex] + liveOffset;
	    var infoMissing = !liveHour[tryPos];

		divDt[liveIndex].firstChild.nodeValue = liveElemText[liveIndex] ?
		 liveElemText[liveIndex] : liveMissing;

		divDd[liveIndex].removeChild(divDd[liveIndex].firstChild);
		var divText = document.createTextNode(infoMissing ? liveMissing :
		 (timeStr(liveHour[tryPos], liveMin[tryPos]) + " " + liveTitle[tryPos]));

		if (!infoMissing && liveLink[tryPos]) {
		    var divA = document.createElement("a");
		    divA.setAttribute("href", liveLink[tryPos]);
		    divA.setAttribute("target", "_blank"); // Ensure they open up in a new window
		    divA.appendChild(divText);
		    divDd[liveIndex].appendChild(divA);
		} else {
		    divDd[liveIndex].appendChild(divText);
		}
	}

	setTimeout(liveUpdate, 500);
}

function fixNatural(number, base)
{
	number = number % base;
	return number < 0 ? (base + number) : number;
}

function parseDate(dateText)
{
	var dateMatch = dateText.match(/(\d{1,2}):(\d{1,2})/i);
	if (dateMatch.length != 3) {
	    return null;
	}
	return [parseInt(dateMatch[1]), parseInt(dateMatch[2])];
}

function liveSetup()
{
	var sourceElem = document.getElementById(sourceElemId);
	if (!sourceElem) {
	    return;
	}

	var headerElem = sourceElem.getElementsByTagName("h2");
	var dlElemList = sourceElem.getElementsByTagName("dl");
	if (!(headerElem[0] && dlElemList[0])) {
	    return;
	}

	// Find difference between server and client
	var currentTime = liveCurrentTime();
	var serverTime = parseDate(headerElem[0].firstChild.nodeValue);
	hourOffset = Math.round((currentTime[0] -
	 timeMins(serverTime[0], serverTime[1])) / 60);

	var childElem = dlElemList[0].firstChild;
	do {
	    if (childElem.nodeType != 1) {
	        continue;
	    }
	    switch (childElem.nodeName) {
	        // Convert text into integers and change time to local
	        case "DT":
				var dateMatch = parseDate(childElem.firstChild.nodeValue);
				if (dateMatch == null) {
				    continue;
				}

				var newDateId = liveHour.length;
				liveHour[newDateId] = fixNatural(dateMatch[0] + hourOffset, 24);
				liveMin[newDateId] = dateMatch[1];
				liveTimeMins[newDateId] =  timeMins(liveHour[newDateId], liveMin[newDateId]);
	            break;

	        case "DD":
	            var aChild = childElem.getElementsByTagName("a");
	            if (aChild[0]) {
	                liveTitle[liveTitle.length] = aChild[0].firstChild.nodeValue;
	                liveLink[liveLink.length] = aChild[0].getAttribute("href");
	            } else {
	                liveTitle[liveTitle.length] = childElem.firstChild.nodeValue;
	                liveLink[liveLink.length] = "";
	            }
	            break;
	    }
	} while ((childElem = childElem.nextSibling) != null);

	// Something has gone wrong with the passing
	if (!(liveTitle.length == liveLink.length &&
	     liveTitle.length == liveMin.length)) {
	    return;
	}

	var beforeElem = document.getElementById(beforeElemId);
	if (!beforeElem) {
	    return;
	}

	var divDetail = document.createElement("div");
	divDetail.setAttribute("id", newElemId);

	var divTitle = document.createElement("h2");
	var divTitleText = document.createTextNode(titleText);
	divTitle.appendChild(divTitleText);
	divDetail.appendChild(divTitle);

	var divDl = document.createElement("dl");
	// Create all the sub-elements
	for (var classIndex = 0; classIndex < liveElemClass.length; ++classIndex) {
		for (var elemIndex = 0; elemIndex < liveElemName.length; ++elemIndex) {
			var dlChild = document.createElement(liveElemName[elemIndex]);
			dlChild.setAttribute(domClassName, liveElemClass[classIndex]);
			var dlChildText = document.createTextNode(elemIndex == 0 ?
			 liveElemText[classIndex] : liveMissing);
			dlChild.appendChild(dlChildText);
			divDl.appendChild(dlChild);
		}
	}
	divDetail.appendChild(divDl);

	// Add the element in
	beforeElem.parentNode.insertBefore(divDetail, beforeElem);

	// Hide the source element
	sourceElem.setAttribute("style", "display: none;");
	sourceElem.style.cssText = "display: none;"; // for IE

	liveUpdate();
}


window.onload = function()
{
	liveSetup();	
	luSetup();
}

