﻿/// <reference name="MicrosoftAjax.js"/>

var themeFolder = "App_Themes/Portal";

var controls;

var clock;
var stateManager;
var getDataTID = null;
var localId;
var activeMatchIndex = null;
var matchResultsIndex = null;
var selectedMatchIndex = null;
var innerCompareSkaterId = null;
var outerCompareSkaterId = null;
var currentStartMode = null;
var currentLapTimesId = null;

function pageLoad() {
    localId = Math.floor(Math.random() * 10000000);

    var getRaceControls = function(colors) {
        return {
            raceContainer: $get(colors + "_CurrentRace"),
            lapsContainer: $get(colors + "_Laps"),
            pair: $get(colors + "_Pair"),
            pairCount: $get(colors + "_PairCount"),
            competitors: [
                {
                    container: $get(colors + "_InnerCompetitor"),
                    startNumber: $get(colors + "_InnerCompetitorStartNumber"),
                    name: $get(colors + "_InnerCompetitorName"),
                    lapColumnHeader: $get(colors + "_InnerLapColumnHeader")
                },
                {
                    container: $get(colors + "_OuterCompetitor"),
                    startNumber: $get(colors + "_OuterCompetitorStartNumber"),
                    name: $get(colors + "_OuterCompetitorName"),
                    lapColumnHeader: $get(colors + "_OuterLapColumnHeader")
                }
            ],
            lapsTableBody: $get(colors + "_LapsTableBody"),
            lapsTableFields: [[], []],
            distanceColumnHeader: $get(colors + "_DistanceColumnHeader"),
            clock: $get(colors + "_Clock"),
            raceStatus: $get(colors + "_RaceStatus")
        };
    };

    controls = {
        delayDropdown: $get("DelayDropdown"),
        video: $get("Video"),
        races: [getRaceControls(LiveWeb.PairColors.WhiteRed), getRaceControls(LiveWeb.PairColors.YellowBlue)],
        message: $get("Message"),
        matchDropdown: $get("MatchDropdown"),
        autoSwitchMatchResults: $get("AutoSwitchMatchResults"),
        innerCompareColumnHeader: $get("InnerCompareColumnHeader"),
        outerCompareColumnHeader: $get("OuterCompareColumnHeader"),
        innerComparableSkaters: $get("InnerComparableSkaters"),
        outerComparableSkaters: $get("OuterComparableSkaters"),
        tabs: [{ link: $get("DrawTabLink"), tab: $get("DrawTab") },
               { link: $get("MatchResultTabLink"), tab: $get("MatchResultTab") },
               { link: $get("RankingTabLink"), tab: $get("RankingTab") }],
        drawTableBody: $get("DrawTableBody"),
        matchResultTableBody: $get("MatchResultTableBody"),
        rankingTableBody: $get("RankingTableBody"),
        lapTimes: $get("LapTimes"),
        lapTimesBody: $get("LapTimesBody")
    };

    controls.video.style.display = "none";
    controls.races[LiveWeb.PairColors.WhiteRed].clock.innerHTML = LiveWeb.Utils.formatTime(0, 1);
    controls.races[LiveWeb.PairColors.WhiteRed].raceStatus.style.display = "none";
    controls.races[LiveWeb.PairColors.YellowBlue].clock.innerHTML = LiveWeb.Utils.formatTime(0, 1);
    controls.races[LiveWeb.PairColors.YellowBlue].raceStatus.style.display = "none";
    controls.message.style.display = "none";
    controls.autoSwitchMatchResults.checked = matchResultsMode == LiveWeb.MatchResultsMode.AutoSwitch;
    controls.lapTimes.style.display = "none";

    $addHandler(controls.innerComparableSkaters, "change", innerCompareSkaterSelected);
    $addHandler(controls.outerComparableSkaters, "change", outerCompareSkaterSelected);
    $addHandler(controls.matchDropdown, "change", matchSelected);
    $addHandler(controls.delayDropdown, "change", delaySelected);
    $addHandler(controls.autoSwitchMatchResults, "click", autoSwitchMatchResultsChange);
    $addHandler(controls.tabs[0].link, "click", function() { switchTab(controls.tabs[0]); });
    $addHandler(controls.tabs[1].link, "click", function() { switchTab(controls.tabs[1]); });
    $addHandler(controls.tabs[2].link, "click", function() { switchTab(controls.tabs[2]); });
    $addHandler(controls.lapTimes, "blur", hideLapTimes);

    stateManager = $create(LiveWeb.ClientStateManager, { delay: delay }, { matchesUpdate: matchesUpdate, comparableSkatersUpdate: comparableSkatersUpdate, matchResultsUpdate: matchResultsUpdate, messageUpdate: messageUpdate, videoUpdate: videoUpdate });
    var raceStateManagers = stateManager.get_raceStateManagers();
    for (var i = 0; i < raceStateManagers.length; i++) {
        var raceStateManager = raceStateManagers[i];
        raceStateManager.add_raceSwitch(raceSwitch);
        raceStateManager.add_racePrepare(racePrepare);
        raceStateManager.add_raceStart(raceStart);
        raceStateManager.add_raceComplete(raceComplete);
        raceStateManager.add_passage(passage);
        raceStateManager.add_lapsUpdate(lapsUpdate);
        raceStateManager.add_clockUpdate(clockUpdate);
    }

    switchLayout(LiveWeb.StartMode.Duo);
    switchTab(controls.tabs[0]);

    updateDelayDropdown();

    LiveWeb.DataService.set_timeout(dataServiceTimeout);
    LiveWeb.DataService.Reset();
    getData(false, false);
}

function switchLayout(startMode) {
    if (startMode == LiveWeb.StartMode.Duo || stateManager.get_raceStateManager(LiveWeb.PairColors.YellowBlue).get_uiRace() == null) {
        controls.races[LiveWeb.PairColors.WhiteRed].lapsContainer.className = "DuoContainer";
        controls.races[LiveWeb.PairColors.YellowBlue].raceContainer.style.display = "none";
        controls.races[LiveWeb.PairColors.YellowBlue].lapsContainer.style.display = "none";
    }
    else {
        controls.races[LiveWeb.PairColors.WhiteRed].lapsContainer.className = "QuartetContainer";
        controls.races[LiveWeb.PairColors.YellowBlue].raceContainer.style.display = "";
        controls.races[LiveWeb.PairColors.YellowBlue].lapsContainer.style.display = "";
    }
    if (currentStartMode != startMode) {
        removeChildNodes(controls.races[LiveWeb.PairColors.WhiteRed].lapsTableBody);
        removeChildNodes(controls.races[LiveWeb.PairColors.YellowBlue].lapsTableBody);
        if (startMode == LiveWeb.StartMode.Duo) {
            controls.innerCompareColumnHeader.style.display = "";
            controls.outerCompareColumnHeader.style.display = "";
        }
        else {
            controls.innerCompareColumnHeader.style.display = "none";
            controls.outerCompareColumnHeader.style.display = "none";
        }
        currentStartMode = startMode;
    }
}

function switchTab(tab) {
    tab.link.className = "Active";
    tab.tab.style.display = "block";
    for (var i = 0; i < controls.tabs.length; i++) {
        if (controls.tabs[i] != tab) {
            controls.tabs[i].link.className = "Inactive";
            controls.tabs[i].tab.style.display = "none";
        }
    }
}

function hideLapTimes() {
    currentLapTimesId = null;
    controls.lapTimes.style.display = "none";
}

function getData(delayRace, delayMatchResults) {
    LiveWeb.DataService.GetData(localId, innerCompareSkaterId, outerCompareSkaterId, matchResultsIndex, matchResultsMode, getDataCompleted, getDataFailed, { delayRace: delayRace, delayMatchResults: delayMatchResults });
}

function getDataCompleted(result, context) {
    if (result == null) {
        getDataTID = setTimeout(function() { resetAndGetData(true, true); }, getDataInterval * 1000);
        return;
    }
    if (result.activeMatchIndex != activeMatchIndex) {
        innerCompareSkaterId = null;
        outerCompareSkaterId = null;
        activeMatchIndex = result.activeMatchIndex;
    }
    matchResultsIndex = result.matchResults.index;
    try {
        stateManager.queueData(result, context.delayRace, context.delayMatchResults);
        getDataTID = setTimeout(function() { getData(true, true); }, getDataInterval * 1000);
    }
    catch (e) {
        Sys.Debug.traceDump(e);
        getDataTID = setTimeout(function() { resetAndGetData(true, true); }, getDataInterval * 1000);
    }
}

function resetAndGetData(delayRace, delayMatchResults) {
    LiveWeb.DataService.Reset();
    getData(delayRace, delayMatchResults);
}

function getDataFailed(error, context) {
    Sys.Debug.traceDump(error);
    LiveWeb.DataService.Reset();
    getDataTID = setTimeout(function() { getData(true, true); }, getDataInterval * 1000);
}

function clockUpdate(sender, e) {
    controls.races[sender.get_colors()].clock.innerHTML = LiveWeb.Utils.formatTime(sender.get_clock().get_seconds(), 1);
}

function cancelGetData() {
    if (getDataTID != null) {
        Sys.Debug.trace("Cancelling scheduled getData().");
        clearTimeout(getDataTID);
        getDataTID = null;
    }
}

function innerCompareSkaterSelected(e) {
    if (e.target[e.target.selectedIndex].disabled) {
        e.target.selectedIndex = 0;
    }
    cancelGetData();
    innerCompareSkaterId = e.target.value;
    getData(true, true);
}

function outerCompareSkaterSelected(e) {
    if (e.target[e.target.selectedIndex].disabled) {
        e.target.selectedIndex = 0;
    }
    cancelGetData();
    outerCompareSkaterId = e.target.value;
    getData(true, true);
}

function removeChildNodes(parent) {
    while (parent.hasChildNodes()) {
        parent.removeChild(parent.firstChild);
    }
}

function comparableSkatersUpdate(sender, e) {
    refreshComparableSkaters(controls.innerComparableSkaters, e.fastestRaceSkater, e.raceSkaters, e.recordHolders);
    refreshComparableSkaters(controls.outerComparableSkaters, e.fastestRaceSkater, e.raceSkaters, e.recordHolders);
}

function refreshComparableSkaters(dropdown, fastestRaceSkater, raceSkaters, recordHolders) {
    selectedValue = dropdown.value;
    removeChildNodes(dropdown);
    var createOption = function(content, value, isHeader) {
        var result = document.createElement("option");
        if (isHeader) {
            result.className = "Header";
            result.disabled = true;
        }
        result.innerHTML = content;
        result.value = value;
        return result;
    };
    dropdown.appendChild(createOption("(Vergelijk)", ""));
    if (recordHolders.length > 0) {
        dropdown.appendChild(createOption("Records", "", true));
        for (var i = 0; i < recordHolders.length; i++) {
            var recordHolder = recordHolders[i];
            var recordType;
            switch (recordHolder.recordType) {
                case LiveWeb.RecordType.Personal:
                    recordType = "PR";
                    break;
                case LiveWeb.RecordType.Track:
                    recordType = "BR";
                    break;
                case LiveWeb.RecordType.National:
                    recordType = "NR";
                    break;
                case LiveWeb.RecordType.Continental:
                    recordType = "ER";
                    break;
                case LiveWeb.RecordType.Global:
                    recordType = "WR";
                    break;
                case LiveWeb.RecordType.Olympic:
                    recordType = "OR";
                    break;
                default:
                    recordType = "??";
                    break;
            }
            var option = createOption(recordType + ": " + recordHolder.name + " (" + LiveWeb.Utils.formatTime(recordHolder.endTime, 2) + ")", recordHolder.id);
            option.selected = option.value == selectedValue;
            dropdown.appendChild(option);
        }
    }
    dropdown.appendChild(createOption("Huidige wedstrijd", "", true));
    if (fastestRaceSkater != null) {
        option = createOption("Snelste tijd (" + LiveWeb.Utils.formatTime(fastestRaceSkater.endTime, 2) + ")", fastestRaceSkater.id);
        option.selected = option.value == selectedValue;
        dropdown.appendChild(option);
    }
    for (var i = 0; i < raceSkaters.length; i++) {
        var raceSkater = raceSkaters[i];
        var option;
        if (raceSkater.endTime != null) {
            option = createOption((i + 1) + ". " + raceSkater.name + " (" + LiveWeb.Utils.formatTime(raceSkater.endTime, 2) + ")", raceSkater.id);
        }
        else if ((Sys.Debug.isDebug || raceSkater.info == "") && isRaceLive(raceSkater.raceId)) {
            option = createOption("Live: " + raceSkater.name, raceSkater.id, false);
        }
        else {
            option = createOption(raceSkater.info + ": " + raceSkater.name, raceSkater.id, false);
        }
        option.selected = option.value == selectedValue;
        dropdown.appendChild(option);
    }
}

function isRaceLive(raceId) {
    var whiteRedRace = stateManager.get_raceStateManager(LiveWeb.PairColors.WhiteRed).get_uiRace();
    var yellowBlueRace = stateManager.get_raceStateManager(LiveWeb.PairColors.YellowBlue).get_uiRace();
    return (whiteRedRace != null && whiteRedRace.id == raceId) || (yellowBlueRace != null && yellowBlueRace.id == raceId);
}

function matchSelected(e) {
    cancelGetData();
    matchResultsIndex = controls.matchDropdown.value * 1;
    selectedMatchIndex = matchResultsIndex;
    getData(true, false);
}

function delaySelected(e) {
    cancelGetData();
    stateManager.reset();
    delay = controls.delayDropdown.value * 1;
    updateDelayDropdown(); 
    stateManager.set_delay(delay);
    LiveWeb.DataService.Reset();
    getData(false, false);
}

function updateDelayDropdown() {
    for (var i = 0; i < controls.delayDropdown.length; i++) {
        var option = controls.delayDropdown[i];
        var offset = option.value - delay;
        option.innerHTML = (offset >= 0 ? "+" + offset : offset) + " (" + option.value + " seconden)";
        option.selected = option.value == delay;
    }
}

function autoSwitchMatchResultsChange(e) {
    matchResultsMode = controls.autoSwitchMatchResults.checked ? LiveWeb.MatchResultsMode.AutoSwitch : LiveWeb.MatchResultsMode.NoSwitch;
}

function matchesUpdate(sender, e) {
    var selectedValue = controls.matchDropdown.value * 1;
    removeChildNodes(controls.matchDropdown);
    for (var i = 0; i < e.matches.length; i++) {
        var match = e.matches[i];
        var option = document.createElement("option");
        option.innerHTML = match.date + ": " + match.title;
        option.value = match.index;
        option.selected = option.value == selectedValue;
        controls.matchDropdown.appendChild(option);
    }
}

function getWindowSize() {
    var width = 0, height = 0;
    if (typeof(window.innerWidth) == 'number') {
        width = window.innerWidth;
        height = window.innerHeight;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        width = document.documentElement.clientWidth;
        height = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        width = document.body.clientWidth;
        height = document.body.clientHeight;
    }
    return { width: width, height: height };
}

function loadLapTimes(distance, id, x, y) {
    controls.lapTimes.style.display = "";
    controls.lapTimes.style.left = x + "px";
    controls.lapTimes.style.top = y + "px";
    controls.lapTimes.focus();
    if (currentLapTimesId != id) {
        currentLapTimesId = id;
        removeChildNodes(controls.lapTimesBody);
        var row = document.createElement("tr");
        var cell = document.createElement("td");
        cell.innerHTML = "Laden...";
        row.appendChild(cell);
        controls.lapTimesBody.appendChild(row);
        LiveWeb.DataService.GetLaps(localId, id, getLapsCompleted, getLapsFailed, { distance: distance, id: id });
    }
}

function getLapsCompleted(result, context) {
    if (context.id == currentLapTimesId) {
        removeChildNodes(controls.lapTimesBody);
        for (var i = 0; i < result.length; i++) {
            var lapTime = result[i];
            var row = document.createElement("tr");
            row.appendChild(createCell("Distance", LiveWeb.Utils.lapDistance(i, context.distance) + " m"));
            row.appendChild(createCell("TotalTime", LiveWeb.Utils.formatTime(lapTime.totalTime, 2)));
            row.appendChild(createCell("LapTime", lapTime.lapTime.toFixed(1)));
            controls.lapTimesBody.appendChild(row);
        }
    }
    setTimeout(function() {
        if (currentLapTimesId == context.id) {
            hideLapTimes();
        }
    }, 10000);
    var windowSize = getWindowSize();
    controls.lapTimes.style.top = Math.min(controls.lapTimes.offsetTop, windowSize.height - controls.lapTimes.clientHeight - 4) + "px";
}

function getLapsFailed(e, context) {
    Sys.Debug.traceDump(error);
    if (context.id == currentLapTimesId) {
        removeChildNodes(controls.lapTimesBody);
        var row = document.createElement("tr");
        var cell = document.createElement("td");
        cell.innerHTML = "Tijden ophalen mislukt";
        row.appendChild(cell);
        controls.lapTimesBody.appendChild(row);
    }
}

function raceSwitch(sender, e) {
    refreshCurrentRace(e.race, sender.get_colors());
}

function racePrepare(sender, e) {
    refreshCurrentRace(e.race, sender.get_colors());
}

function raceStart(sender, e) {
    refreshCurrentRace(e.race, sender.get_colors());
}

function raceComplete(sender, e) {
    refreshCurrentRace(e.race, sender.get_colors());
}

function passage(sender, e) {
    showPassage(e.index, sender.get_colors(), e.track, e.totalTime, e.lapTime, e.compareTotalTime, e.compareLapTime);
}

function showPassage(index, colors, track, totalTime, lapTime, compareTotalTime, compareLapTime) {
    var rowControls = controls.races[colors].lapsTableFields[track][index];
    rowControls.TotalTime.innerHTML = totalTime != null ? LiveWeb.Utils.formatTime(totalTime, 2) : "";
    rowControls.LapTime.innerHTML = lapTime != null ? lapTime.toFixed(1) : "";
    if (currentStartMode == LiveWeb.StartMode.Duo) {
        rowControls.ComparedTotalTime.innerHTML = compareTotalTime != null ? LiveWeb.Utils.formatTime(compareTotalTime, 2) : "";
        rowControls.ComparedLapTime.innerHTML = compareLapTime != null ? compareLapTime.toFixed(1) : "";
        if (totalTime != null && compareTotalTime != null) {
            var difference = totalTime - compareTotalTime;
            difference = difference.toFixed(2);
            rowControls.Difference.innerHTML = difference > 0 ? "+" + difference : difference;
            rowControls.Difference.style.color = difference == 0 ? "" : (difference > 0 ? "Red" : "Green");
        }
        else {
            rowControls.Difference.innerHTML = "";
        }
    }
}

function lapsUpdate(sender, e) {
    refreshRaceStatus(e.race, sender.get_colors());
    refreshLapsTable(e.race.match, sender.get_colors());
}

function createCell(className, innerHTML) {
    var result = document.createElement("td");
    result.className = className;
    result.innerHTML = innerHTML != null ? innerHTML : "";
    return result;
}

function createInfoImage(info) {
    if (info == null) {
        return null;
    }
    var image = document.createElement("img");
    switch (info) {
        case "DQ":
            image.src = themeFolder + "/dq.png";
            image.alt = "Gediskwalificeerd";
            break;
        case "NF":
            image.src = themeFolder + "/nf.png";
            image.alt = "Niet gefinished";
            break;
        case "NS":
            image.src = themeFolder + "/ns.png";
            image.alt = "Niet gestart";
            break;
        case "OC":
            image.src = themeFolder + "/oc.png";
            image.alt = "Buiten competitie";
            break;
        case "WD":
            image.src = themeFolder + "/wd.png";
            image.alt = "Teruggetrokken";
            break;
        case "FL":
            image.src = themeFolder + "/fl.png";
            image.alt = "Gevallen";
            break;
        case "NR":
            image.src = themeFolder + "/nr.png";
            image.alt = "Nederlands record";
            break;
        case "PB":
            image.src = themeFolder + "/pr.png";
            image.alt = "Persoonlijk record";
            break;
        case "WR":
            image.src = themeFolder + "/wr.png";
            image.alt = "Wereldrecord";
            break;
        case "TR":
            image.src = themeFolder + "/br.png";
            image.alt = "Baanrecord";
            break;
        default:
            return null;
    }
    return image;
}

function createViewLapTimesLink(match, raceSkaterId) {
    var viewLapTimesLink = document.createElement("a");
    viewLapTimesLink.innerHTML = "Tussentijden";
    viewLapTimesLink.className = "Link";
    viewLapTimesLink.raceSkaterId = raceSkaterId;
    $addHandler(viewLapTimesLink, "click", function(e) { loadLapTimes(match.distance, this.raceSkaterId, e.clientX, e.clientY); });
    return viewLapTimesLink;
}

function matchResultsUpdate(sender, e) {
    selectedMatchIndex = e.match.index;
    if (controls.matchDropdown.value != selectedMatchIndex) {
        var count = controls.matchDropdown.options.length;
        for (var i = 0; i < count; i++) {
            if (controls.matchDropdown.options[i].value == selectedMatchIndex) {
                controls.matchDropdown.selectedIndex = i;
                break;
            }
        }
    }
    if (e.draw != null) {
        removeChildNodes(controls.drawTableBody);
        if (e.draw.length == 0) {
            var cell = createCell(null, "De loting is nog niet bekend.");
            cell.colSpan = 9;
            var row = document.createElement("tr");
            row.className = "Even";
            row.appendChild(cell);
            controls.drawTableBody.appendChild(row);
        }
        else {
            var lastPair = null;
            for (var i = 0; i < e.draw.length; i++) {
                var drawLine = e.draw[i];
                var row = document.createElement("tr");
                row.className = i % 2 == 1 ? "Odd" : "Even";
                row.appendChild(createCell("Pair", lastPair != drawLine.pair ? drawLine.pair : ""));
                row.appendChild(createCell("Track", drawLine.track == 0 ? "I" : "O"));
                row.appendChild(createCell("StartNumber", drawLine.startNumber));
                row.appendChild(createCell("Name", drawLine.name));
                row.appendChild(createCell("From", drawLine.from));
                row.appendChild(createCell("PersonalBest", drawLine.personalBest != null ? LiveWeb.Utils.formatTime(drawLine.personalBest, 2) : ""));
                row.appendChild(createCell("EndTime", drawLine.time != null ? LiveWeb.Utils.formatTime(drawLine.time, 2) : ""));
                var infoCell = createCell("Info");
                var infoImage = createInfoImage(drawLine.info);
                if (infoImage != null) {
                    infoCell.appendChild(infoImage);
                }
                row.appendChild(infoCell);
                var viewLapTimesCell = createCell("ViewLapTimes");
                if (drawLine.info != "") {
                    viewLapTimesCell.appendChild(createViewLapTimesLink(e.match, drawLine.raceSkaterId));
                }
                row.appendChild(viewLapTimesCell);

                controls.drawTableBody.appendChild(row);
                lastPair = drawLine.pair;
            }
        }
    }
    if (e.matchResult != null) {
        removeChildNodes(controls.matchResultTableBody);
        if (e.matchResult.length == 0) {
            var cell = createCell(null, "Er zijn nog geen ritten voltooid.");
            cell.colSpan = 9;
            var row = document.createElement("tr");
            row.className = "Even";
            row.appendChild(cell);
            controls.matchResultTableBody.appendChild(row);
        }
        else {
            var previousTime = null;
            for (var i = 0; i < e.matchResult.length; i++) {
                var matchResultLine = e.matchResult[i];
                var row = document.createElement("tr");
                row.className = i % 2 == 1 ? "Odd" : "Even";
                row.appendChild(createCell("Position", i + 1));
                row.appendChild(createCell("StartNumber", matchResultLine.startNumber));
                row.appendChild(createCell("Name", matchResultLine.name));
                row.appendChild(createCell("From", matchResultLine.from));
                row.appendChild(createCell("EndTime", matchResultLine.endTime != null ? LiveWeb.Utils.formatTime(matchResultLine.endTime, 2) : ""));
                row.appendChild(createCell("Behind", matchResultLine.behind != null && matchResultLine.behind > 0 ? "+" + matchResultLine.behind.toFixed(2) : ""));
                var infoCell = createCell("Info");
                var infoImage = createInfoImage(matchResultLine.info);
                if (infoImage != null) {
                    infoCell.appendChild(infoImage);
                }
                row.appendChild(infoCell);
                var viewLapTimesCell = createCell("ViewLapTimes");
                viewLapTimesCell.appendChild(createViewLapTimesLink(e.match, matchResultLine.raceSkaterId));
                row.appendChild(viewLapTimesCell);

                controls.matchResultTableBody.appendChild(row);
                previousTime = matchResultLine.endTime;
            }
        }
    }
    if (e.ranking != null) {
        removeChildNodes(controls.rankingTableBody);
        if (e.ranking.length == 0) {
            var cell = createCell(null, "Er zijn nog geen ritten voltooid.");
            cell.colSpan = 6;
            var row = document.createElement("tr");
            row.className = "Even";
            row.appendChild(cell);
            controls.rankingTableBody.appendChild(row);
        }
        else {
            var previousPoints = null;
            for (var i = 0; i < e.ranking.length; i++) {
                var rankingLine = e.ranking[i];
                var row = document.createElement("tr");
                row.className = i % 2 == 1 ? "Odd" : "Even";
                row.appendChild(createCell("Position", rankingLine.points != null && previousPoints != rankingLine.points ? i + 1 : ""));
                row.appendChild(createCell("StartNumber", rankingLine.startNumber));
                row.appendChild(createCell("Name", rankingLine.name));
                row.appendChild(createCell("From", rankingLine.from));
                row.appendChild(createCell("Points", rankingLine.points != null ? rankingLine.points.toFixed(3) : ""));
                row.appendChild(createCell("Behind", rankingLine.behind != null && rankingLine.behind > 0 ? "+" + rankingLine.behind.toFixed(3) : ""));
                controls.rankingTableBody.appendChild(row);
                previousPoints = rankingLine.points;
            }
        }
    }
}

function messageUpdate(sender, e) {
    if (e.text != "") {
        controls.message.style.display = "block";
        controls.message.innerHTML = e.text;
    }
    else {
        controls.message.style.display = "none";
        controls.message.innerHTML = "";
    }
}

function videoUpdate(sender, e) {
    controls.video.style.display = e.enabled ? "block" : "none";
    controls.video.innerHTML = e.html;
}

function refreshCurrentRace(race, colors) {
    switchLayout(race.match.startMode);
    var raceControls = controls.races[colors];
    raceControls.pair.innerHTML = race.pair;
    raceControls.pairCount.innerHTML = race.match.pairCount;
    refreshCompetitor(race.innerSkater, raceControls.competitors[LiveWeb.Track.Inner]);
    refreshCompetitor(race.outerSkater, raceControls.competitors[LiveWeb.Track.Outer]);
    refreshRaceStatus(race, colors);
    refreshLapsTables(race.match);
}

function refreshLapsTables(match) {
    refreshLapsTable(match, LiveWeb.PairColors.WhiteRed);
    refreshLapsTable(match, LiveWeb.PairColors.YellowBlue);
}

function refreshLapsTable(match, colors) {
    removeChildNodes(controls.races[colors].lapsTableBody);
    controls.races[colors].lapsTableFields = [[], []];
    var createLapsCell = function(id, className, track, index, innerHTML) {
        var cell = createCell(className, innerHTML);
        controls.races[colors].lapsTableFields[track][index][id] = cell;
        return cell;
    };
    for (var i = 0; i < match.lapCount; i++) {
        var row = document.createElement("tr");
        var odd = i % 2 == 1;
        row.className = odd ? "Odd" : "Even";
        controls.races[colors].lapsTableFields[LiveWeb.Track.Inner][i] = [];
        controls.races[colors].lapsTableFields[LiveWeb.Track.Outer][i] = [];
        if (currentStartMode == LiveWeb.StartMode.Duo && colors == LiveWeb.PairColors.WhiteRed) {
            row.appendChild(createLapsCell("ComparedTotalTime", "TotalTime", LiveWeb.Track.Inner, i));
            row.appendChild(createLapsCell("ComparedLapTime", "LapTime", LiveWeb.Track.Inner, i));
            row.appendChild(createLapsCell("Difference", "Difference", LiveWeb.Track.Inner, i));
        }
        row.appendChild(createLapsCell("TotalTime", "TotalTime " + (odd ? "Odd" : "Even"), LiveWeb.Track.Inner, i));
        row.appendChild(createLapsCell("LapTime", "LapTime " + (odd ? "Odd" : "Even"), LiveWeb.Track.Inner, i));
        row.appendChild(createCell("Distance", match.lapDistances[i]));
        row.appendChild(createLapsCell("TotalTime", "TotalTime " + (odd ? "Odd" : "Even"), LiveWeb.Track.Outer, i));
        row.appendChild(createLapsCell("LapTime", "LapTime " + (odd ? "Odd" : "Even"), LiveWeb.Track.Outer, i));
        if (currentStartMode == LiveWeb.StartMode.Duo && colors == LiveWeb.PairColors.WhiteRed) {
            row.appendChild(createLapsCell("Difference", "Difference", LiveWeb.Track.Outer, i));
            row.appendChild(createLapsCell("ComparedTotalTime", "TotalTime", LiveWeb.Track.Outer, i));
            row.appendChild(createLapsCell("ComparedLapTime", "LapTime", LiveWeb.Track.Outer, i));
        }
        controls.races[colors].lapsTableBody.appendChild(row);
    }
    setSelectedCompareSkater(controls.innerComparableSkaters, innerCompareSkaterId);
    setSelectedCompareSkater(controls.outerComparableSkaters, outerCompareSkaterId);
    var raceStateManager = stateManager.get_raceStateManager(colors);
    raceStateManager.resetAllLaps();
    raceStateManager.showAllLaps();
}

function setSelectedCompareSkater(dropdown, id) {
    for (var i = 0; i < dropdown.length; i++) {
        var option = dropdown[i];
        option.selected = option.value == id;
        if (option.selected) {
            return;
        }
    }
    dropdown.selectedIndex = 0;
}

function refreshRaceStatus(race, colors) {
    var raceControls = controls.races[colors];
    raceControls.raceStatus.style.color = "";
    switch (race.uiState) {
        case LiveWeb.RaceState.Preparing:
            raceControls.raceStatus.innerHTML = "Wachten op start";
            raceControls.raceStatus.style.display = "block";
            break;
        case LiveWeb.RaceState.Completed:
            if (race.falseStart || (race.laps[LiveWeb.Track.Inner].length == 0 && race.laps[LiveWeb.Track.Outer].length == 0)) {
                race.falseStart = true;
                raceControls.raceStatus.innerHTML = "Valse start";
                raceControls.raceStatus.style.color = "Red";
            }
            else {
                raceControls.raceStatus.innerHTML = "Rit afgelopen";
            }
            raceControls.raceStatus.style.display = "block";
            break;
        default:
            raceControls.raceStatus.innerHTML = "";
            raceControls.raceStatus.style.display = "none";
            break;
    }
}

function refreshCompetitor(competitor, controls) {
    if (competitor != null) {
        controls.container.style.display = "block";
        controls.startNumber.innerHTML = competitor.startNumber;
        controls.name.innerHTML = competitor.name;
        controls.lapColumnHeader.innerHTML = competitor.name;
    }
    else {
        controls.container.style.display = "none";
        controls.lapColumnHeader.innerHTML = "";
    }
}