//*****************************************************************************
// Live scoreboard code.
//*****************************************************************************

//=============================================================================
// Module: scoreboard
//
// Maintains the live scoreboard using data retrieved from the NFL.com web
// site.
//=============================================================================
var scoreboard = function () {

	// Display elements.
	var scoreboardEl;
	var arrowEl;

	// Determine the correct URL to use for retrieving scoreboard data.
	var isPlayoffs = true;
	var scoresUrl = "http://www.nfl.com/liveupdate/scorestrip/ss.xml";
	if (isPlayoffs)
		scoresUrl = "http://www.nfl.com/liveupdate/scorestrip/postseason/ss.xml";

	// Define the game center URL.
	var gameCenterUrl = "http://www.nfl.com/gamecenter";

	// Create an XMLHttpRequest object for loading the scoreboard data.
	var xhr = new XHR();
	xhr.url = "getRequest.asp";
	xhr.queryString = "url=" + escape(scoresUrl + "?random=" + Math.floor(Math.random() * 10000000));
	xhr.successCallback = getScoresSuccess;

	// Define an interval timer and time for updating the scoreboard.
	var updateInterval      = null;
	var updateIntervalTime  = 30000; // 30 seconds.

	// Used to throttle update requests. If no active games are found on an
	// update, this will hold the time that it was made. We will then wait for
	// a minimum period of time to pass before making a new request.
	var lastInactiveUpdate  = null;
	var inactiveMinWaitTime = 300000; // 5 minutes.

	// Used to hold the parsed scoreboard game data.
	var gamesList = [];

	//-------------------------------------------------------------------------
	// Initializes the scoreboard.
	//-------------------------------------------------------------------------
	function init() {

		// Get the scoreboard and arrow elements, exit if not found.
		scoreboardEl = document.getElementById("scoreboard");
		arrowEl      = document.getElementById("scoreboardArrow");
		if (scoreboardEl == null || arrowEl == null)
			return;

		// Get the scoreboard tab element, exit if not found.
		var tabEl = document.getElementById("scoreboardTab");
		if (tabEl == null)
			return;

		// Make the scoreboard tab visible.
		tabEl.style.visibility = "visible";

		// If we have saved scoreboard data, us it to build the display. This
		// will prevent it from being empty while we wait for the first update
		// request to complete.
		var lastData = domUtils.getCookie("scoreboardData");
		try {
			if (lastData != "") {
				var parser = new DOMParser();
				var xmlDoc = parser.parseFromString(lastData, "text/xml");
				processScores(xmlDoc);
			}
		}
		catch (ex) {}

		// Check the cookie to see if the user had the scoreboard visible on
		// the previous page.
		if (domUtils.getCookie("scoreboardOn") == "1") {

			// Yes, make it visible now.
			toggleDisplay();
		}
		else if (lastData == "") {
			// No, and we have no saved data so go ahead and do an update
			// request.
			getScores();
		}
	}

	//-------------------------------------------------------------------------
	// Shows or hides the scoreboard.
	//-------------------------------------------------------------------------
	function toggleDisplay() {

		if (scoreboardEl.style.display == "none") {

			// Begin an update request.
			lastInactiveUpdate = null;
			getScores();

			// Show the scoreboard.
			scoreboardEl.style.display = "";
			arrowEl.firstChild.nodeValue = "\u25bc";

			// Set the scoreboard display cookie.
			domUtils.setCookie("scoreboardOn", "1");

			// Set the interval timer for 30 second updates.
			if (updateInterval == null)
				updateInterval = setInterval(getScores, updateIntervalTime);
		}
		else {

			// Hide the scoreboard.
			scoreboardEl.style.display = "none";
			arrowEl.firstChild.nodeValue = "\u25b2";

			// Stop the interval timer.
			if (updateInterval != null) {
				clearInterval(updateInterval);
				updateInterval = null;
			}

			// Set the scoreboard display cookie.
			domUtils.setCookie("scoreboardOn", "0");
		}
	}

	//-------------------------------------------------------------------------
	// Called by the interval timer to update the scoreboard.
	//-------------------------------------------------------------------------
	function getScores() {

		// If no active games were found on the last update, we will skip
		// making a request until the minimum wait time has passed.
		if (lastInactiveUpdate != null) {
			var currentTime = new Date();
			if (currentTime.valueOf() - lastInactiveUpdate.valueOf() < inactiveMinWaitTime)
				return;
		}

		// Initiate the request.
		try {
			xhr.get();
		}
		catch (ex) {}
	}

	//-------------------------------------------------------------------------
	// Callback for the get scores request.
	//-------------------------------------------------------------------------
	function getScoresSuccess(reqObj) {

		try {

			// Save the current time.
			lastInactiveUpdate = new Date();

			// Process the data.
			processScores(reqObj.responseXML);
		}
		catch (ex)
		{}
	}

	//-------------------------------------------------------------------------
	// Processes the scoreboard data.
	//-------------------------------------------------------------------------
	function processScores(xmlDoc) {

		// Save the scoreboard data in a cookie.
		try {
			var serializer = new XMLSerializer();
			var xml = serializer.serializeToString(xmlDoc);
			domUtils.setCookie("scoreboardData", xml);
		}
		catch (ex) {}

		// Get general game information (needed to build game center links).
		var infoEls = xmlDoc.getElementsByTagName("gms");
		var urlPath = "";
		if (infoEls.length > 0) {
			var week = infoEls[0].getAttribute("w");
			var year = infoEls[0].getAttribute("y");
			var type = infoEls[0].getAttribute("t");
			if (type == "R")
				week = "REG" + week;
			else
				week = "PRE" + week;
			urlPath = year + "/" + week;
		}

		// Build the array of game objects.
		gamesList = [];

		// For each game element in the document, create a new game object and
		// add it to the array.
		var gameEls = xmlDoc.getElementsByTagName("g");
		for (var i = 0; i < gameEls.length; i++) {
			var game = gameObj(gameEls[i], urlPath);
			gamesList.push(game);
		}

		// For the playoffs games, alter the list to drop game 11 (the Pro
		// Bowl) and put game 12 (the Super Bowl) in the middle.
		if (isPlayoffs) {
			var tempList = gamesList.pop();
			gamesList.pop();
			gamesList.splice(5, 0, tempList);
		}

		// Build the display.
		buildDisplay();
	}

	//-------------------------------------------------------------------------
	// Creates the scoreboard display.
	//-------------------------------------------------------------------------
	function buildDisplay() {

		// Build the scoreboard HTML.
		var html = "<table cellpadding=\"0\" cellspacing=\"0\"><tr valign=\"top\">";
		for (var i = 0; i < gamesList.length; i++) {

			// Add the HTML for the individual game.
			html += "<td" + (i > 0 ? " class=\"leftEdge\"" : "") + ">" + gamesList[i].toHtml() + "<\/td>";

			// If a game is active, clear the last update time.
			if (gamesList[i].isActive)
				lastInactiveUpdate = null;
		}

		// Handle the case where no game data was found.
		if (gamesList.length == 0)
			html += "<td>&nbsp;<br />No scores available.<br />&nbsp;</td>";

		html += "<\/tr><\/table>";

		// Clear any current content.
		while (scoreboardEl.firstChild != null)
			scoreboardEl.removeChild(scoreboardEl.firstChild);

		// Insert the new HTML.
		var divEl = document.createElement("DIV");
		divEl.innerHTML = html;
		scoreboardEl.appendChild(divEl);
	}

	//-------------------------------------------------------------------------
	// Returns an object representing a single game.
	//-------------------------------------------------------------------------
	function gameObj(gameEl, urlPath) {

		// Extract data from the game element.
		var gameDate = gameEl.getAttribute("eid");  // Game date.
		var gameDay  = gameEl.getAttribute("d");    // Game day.
		var gameTime = gameEl.getAttribute("t");    // Kickoff time.
		var status   = gameEl.getAttribute("q");    // Status = "P", "H", "F", "FO", "1" - "8".
		var timeLeft = gameEl.getAttribute("k");    // Time left in quarter/overtime.
		var vid      = gameEl.getAttribute("v");    // Visitor team ID.
		var vname    = gameEl.getAttribute("hnn");  // Visitor team name.
		var vscore   = gameEl.getAttribute("vs");   // Visitor score.
		var hid      = gameEl.getAttribute("h");    // Home team ID.
		var hname    = gameEl.getAttribute("vnn");  // Home team name.
		var hscore   = gameEl.getAttribute("hs");   // Home score.
		var pid      = gameEl.getAttribute("p");    // ID of team with possession.
		var redZone  = gameEl.getAttribute("rz");   // redZone flag = "0" or "1".

		// Build the game center link.
		var url = "";
		if (urlPath != "")
			url = gameCenterUrl + "/" + gameDate + "/" + urlPath + "/" + vname + "@" + hname;

		// For Jacksonville, use "JAX" instead of "JAC".
		vid = vid.replace("JAC", "JAX");
		hid = hid.replace("JAC", "JAX");

		// Handle unknown IDs (this occurs in the postseason).
		if (vid == "TBD")
			vid = "[<em>TBD</em>]";
		if (hid == "TBD")
			hid = "[<em>TBD</em>]";

		// Game state.
		var isActive = false;
		var isOver   = false;

		// Determine the game status.
		switch(status.toUpperCase()) {
			case "P":
				status = gameDay + " " + gameTime;
				break;
			case "H":
				status = "Half";
				isActive = true;
				break;
			case "F":
				status = "Final";
				isOver = true;
				break;
			case "FO":
				status = "Final-OT";
				isOver = true;
				break;
			default:
				var quarter;
				switch(status.toUpperCase()) {
					case "1":
						quarter = "1st";
						break;
					case "2":
						quarter = "2nd";
						break;
					case "3":
						quarter = "3rd";
						break;
					case "4":
						quarter = "4th";
						break;
					default:
						quarter = "OT";
						break;
				}
				status = timeLeft + " " + quarter;
				isActive = true;
				break;
		}

		// Create the object, setting all properties and methods.
		return {
			url      : url,
			vid      : vid,
			hid      : hid,
			vscore   : vscore,
			hscore   : hscore,
			status   : status,
			pid      : pid,
			redZone  : redZone,
			isActive : isActive,
			isOver   : isOver,
			toHtml   : gameHtml // See function below.
		}
	}

	//-------------------------------------------------------------------------
	// Creates HTML from a game object.
	//-------------------------------------------------------------------------
	function gameHtml() {

		var vid    = this.vid;
		var hid    = this.hid;
		var vscore = "&nbsp;";
		var hscore = "&nbsp;";
		var vclass = "";
		var hclass = "";
		var status = this.status;

		// Get the scores, if available.
		if (this.isActive || this.isOver)
		{
			vscore = parseInt(this.vscore);
			hscore = parseInt(this.hscore);
		}

		// For a completed game, highlight the winner.
		if (this.isOver) {
			if (vscore > hscore) {
				vid    = highlightText(vid);
				vscore = highlightText(vscore);
			}
			if (hscore > vscore) {
				hid    = highlightText(hid);
				hscore = highlightText(hscore);
			}
		}

		// For an active game, mark the team with possession (if any) and
		// highlight a team if it is in the read zone.
		if (this.isActive && !this.isOver) {
			if (this.vid == this.pid) {
				vid += highlightText("&#9642;");
				if (this.redZone == "1")
					vclass = " class=\"redZone\"";
			}
			if (this.hid == this.pid) {
				hid += highlightText("&#9642;");
				if (this.redZone == "1")
					hclass = " class=\"redZone\"";
			}
		}

		// Build the HTML.
		var html = "<table cellpadding=\"0\" cellspacing=\"0\">"
			+ "<tr" + vclass + " valign=\"top\"><td>" + vid + "<\/td><td align=\"right\">" + vscore + "<\/td><\/tr>"
			+ "<tr" + hclass + " valign=\"top\"><td>" + hid + "<\/td><td align=\"right\">" + hscore + "<\/td><\/tr>"
			+ "<tr valign=\"top\"><td align=\"center\" colspan=\"2\">" + status + "<\/td><\/tr>"
			+ "<\/table>";

		// Link it to the game center page for it.
		if (this.url != "")
			html = "<div style=\"cursor: pointer;\" onclick=\"window.open('" + this.url + "'); return false;\">" + html + "</div>";

		// Return it.
		return html;
	}

	//-------------------------------------------------------------------------
	// Wraps the given text in a span with the highlight class.
	//-------------------------------------------------------------------------
	function highlightText(s) {

		return "<span class=\"highlight\">" + s + "<\/span>";
	}

	//=========================================================================
	// Initialization code.
	//=========================================================================

	// Initialize on page load.
	domUtils.onready(init);

	//=========================================================================
	// Public properties and methods.
	//=========================================================================
	return {

		//---------------------------------------------------------------------
		// Toggles the scoreboard display.
		//---------------------------------------------------------------------
		toggle : function () {

			toggleDisplay();
		}
	}
}();

