/**
 * update.js - keep lines in sync using linefeed
 */

var xmlh = null;
var timestamp = null;
var reqNo = 0;
var lineNo = 0;
var grouping = null;
var isFeedStop = false;
var ident = 0;

/**
 * Handle the success of the HTTP request.
 */
function stateChanged() {

    if(xmlh.readyState == 2) {
        // notify send window
        // window.status += "sent req...";
    }

    if(xmlh.readyState != 4) {
        return;
    }

    // must be successful
    if(xmlh.status == 200) {

        try {

            // notify receive window
            // window.status += "recvd data: " + xmlh.responseText.length + " bytes...";

            // parse xml of response
            var xmlDoc=xmlh.responseXML.documentElement;

            // first get the timestamp and display to status window
            timeElements = xmlDoc.getElementsByTagName("t");

            if(timeElements.length != 1) return;
            if(timeElements[0].childNodes.length != 1) return;

            var currStamp = timeElements[0].childNodes[0].nodeValue;

            // display timestamp
            // window.status += "ts of response: " + currStamp + "...";

            //
            // now iterate over every prop and update lines as we go
            //
            var idElements = xmlDoc.getElementsByTagName("l");

            for(var i=0; i < idElements.length; i++) {

                var result = getLines(idElements[i]);

                if(!result) break;
            }

            //
            //  now check for contests to remove
            //
            var hideElements = xmlDoc.getElementsByTagName("c");

            for(var i=0; i < hideElements.length; i++) {
                hide(hideElements[i]);
            }

			// since successful, now set global timestamp
			timestamp = currStamp;

            // window.status += "info[reqnum=" + reqNo + ", numprop=" + lineNo + "]";
            lineNo = 0;

        } catch(e) {
		    // failure caught so polling will continue
        }
	}

    //
    // finally once successfully complete parsing, poll again
    //

    if(!isFeedStop) {
        setTimeout("loadFeed()", 1000 * 30);
    }
}

/**
 * Given an XML element who has attribute of id which is
 * the id of a TBODY element, hide each TR element within
 * the TBODY.
 */
function hide(hideElement) {

    if(hideElement == null) return;

    var contestStr = hideElement.getAttribute("i");

    var tbodyEl = document.getElementById(contestStr);

    if(tbodyEl == null) return;

    var trEls = tbodyEl.getElementsByTagName("tr");

    // iterate over tr elements and then delete all cells
    for(var i=0; i < trEls.length; i++) {

        // tbodyEl.removeChild(trEls[i]);
        trEls[i].style.display = "none";
    }

	// now change the id attribute of span tags
	// this means if we receive a line later because
	// this contest was put back up, a refresh will
	// be triggered
	var spanEls = tbodyEl.getElementsByTagName("span");
	
	// iterate over spans and set ids to empty string
	for(var i=0; i < spanEls.length; i++) {
		spanEls[i].setAttribute("id", "");
	}
}

/**
 * Parse the XML line element and then invoke function to
 * update the line.
 */
function getLines(idElement) {

    // ensure we have something here
    if(idElement == null) return true;

    lineNo++;

    var propStr = idElement.getAttribute("p");
    var statStr = idElement.getAttribute("s");
    var lineStr = idElement.lastChild.nodeValue;

    // now update the lines page HTML
    try {
        return updateLine(propStr, statStr, lineStr);

    } catch(e) {
        // isFeedStop = true;
        // reloadPage();
        return false;
    }
}

/**
 * Given an id, line, and status... update the HTML.
 */
function updateLine(propAcro, statStr, line) {

    lineNode = document.getElementById(propAcro);

    if(lineNode == null) {

        // we have found a prop acro in the linefeed which
        // does not exist on the lines page - this is error
        isFeedStop = true;

        reloadPage();

        return false;
    }

    // clean up
    updateStatus(propAcro, "");

    var statusDescr = null;
    if(statStr != null) {
        // get status string
        var statusDescr = statusMap(propAcro, statStr);
    }

    // is this a spread and money
    var splitNum = line.indexOf(" ");

    if(splitNum != null && splitNum > 0) {

        var spreadLine = line.substring(0, splitNum);
        var moneyLine = line.substring(splitNum, line.length);

        if(statusDescr != null) {
            moneyLine = statusDescr;
        } else {
            moneyLine = cleanLine(propAcro, moneyLine);
        }

        // now search for the run line
        lineNodeSpread = document.getElementById(propAcro + "xlx");

        if(lineNodeSpread == null) return;

		if(spreadLine == "0.0") {
			spreadLine = "PICK";
		}

        lineNodeSpread.innerHTML = spreadLine;
        lineNode.innerHTML = moneyLine;

    } else {

        if(statusDescr != null) {
            line = statusDescr;
        } else {
            line = cleanLine(propAcro, line);
        }

        lineNode.innerHTML = line;
    }

    return true;
}

/**
 * Handle formatting of line before display.
 */
function cleanLine(propAcro, line) {

    if(line == 100) line="EVEN";

    line = "<a href=/cgi/straight_form?propacro=" +
        propAcro + " class=lines-wager-link target=action>" +
        line + "</a>";

    return line;
}

/**
 * Map status codes to description.
 */
function statusMap(propAcro, statusStr) {

    if(statusStr == "X") return "Closed";
    else if(statusStr == "T") return "O.T.B.";
    else if(statusStr == "C") {
        updateStatus(propAcro, "Circled");
    }

    return null;
}

/**
 * Update the status field of the HTML with value.
 */
function updateStatus(propAcro, val) {
    var statusElement = document.getElementById(propAcro + "sts");
    if(statusElement == null) return;
    statusElement.innerHTML = val;
}

/**
 * Reload the HTML document in 5-15 seconds.
 */
function reloadPage() {

    // generate random number between 0 and 10
    var reloadSeconds = Math.floor(Math.random() * 120) + 5;

    // alert("reloading page in " + reloadSeconds + " seconds...");
    // window.status = "reloading page in " + reloadSeconds + " seconds...";

    setTimeout("window.location.reload()", 1000 * reloadSeconds);
}

/**
 * Start the process. This function is the "main" one
 * invoked by the HTML doc.
 */
function initUpdate(grp) {

	try {
		// generate id of this browser
		var tmpNum = (new Date()).getTime() + "" +
			Math.floor(Math.random() * 1000000);
		ident = tmpNum.substr(0,18);

	} catch(e) {}

    // window.status = "will start in 5 seconds...";

    if(grp != null) {
        grouping = grp;
    }

    setTimeout("loadFeed()", 1000 * 10);
}

/**
 * Do some setup work and make the HTTP request.
 */
function loadFeed() {

    // increment request number
    reqNo++;

    // use the start time from the lines page
    if(timestamp == null) {
        if(startTime != null && startTime > 0) {
            timestamp = startTime;
        }
    }

    if(timestamp == null) {
        // window.status = "prep reqno " + reqNo + " with no ts...";
    } else {
        // window.status = "prep reqno " + reqNo + " with " + timestamp + "...";
    }

    xmlh = getXmlHttpObject();

    if(xmlh == null) {
        // alert("browser requirement error!");
        isFeedStop = true;
    	setTimeout("window.location.reload()", 1000 * 60 * 3);
        return;
    }

    //
    // additional cache prevention
    //
    var rand = Math.floor(Math.random() * 10000001)

    // use the protocol of the page which we are loaded
    var thisUrl = document.URL;
    var idx = thisUrl.indexOf(":");
    var proto = thisUrl.substring(0, idx);

	if(proto == "https") return;

    var furl = proto + "://www.wsex.com/credits/wse/linefeed?slim=y&random=" +
		escape(rand) + "&id=" + escape(ident);

    if(grouping != null) {
        furl += "&grp=" + escape(grouping);
    }

    if(timestamp != null) {
        furl += "&since=" + escape(timestamp);
    }

    xmlh.onreadystatechange=stateChanged;
    xmlh.open("GET", furl, true);
    xmlh.send(null);
}

/**
 * Get an xml request object in a browser safe way.
 */
function getXmlHttpObject() {
    var xmlHttp = null;

    try {
        // Firefox, Opera 8.0+, Safari
        xmlHttp=new XMLHttpRequest();
    } catch (e) {}

    // The various MS flavors
    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("MSXML2.XMLHTTP");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("microsoft.XMLHTTP");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP.4.0");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.4.0");
        } catch (e) {}
    } else return xmlHttp;

    if(xmlHttp == null) {
        try {
            xmlHttp=new ASVRequest();
        } catch (e) {}
    } else return xmlHttp;

    return xmlHttp;
}

