var scoreBoard;

/**
 * Updates the stored rankings whenever a respective call from the server is received.
 * @param {object} rnk the ranking received from the server
 */
function updateRanking(rnk) {
    scoreBoard.update(rnk.scoreType, rnk);
}

/**
 * Sets up the main score board of the application.
 */
function setupScoreBoard() {
    scoreBoard = new ScoreBoard("scores");
    
    scoreBoard.add("day", "img/icon16-day-02", "scores1.image", "Täglich");
    scoreBoard.add("week", "img/icon16-week-02", "scores2.image", "Wöchentlich");
    scoreBoard.add("month", "img/icon16-month-02", "scores3.image", "Monatlich");
    scoreBoard.add("overall", "img/icon16-sum-01", "scores4.image", "Insgesamt");
    scoreBoard.add("userquestions", "img/icon16-addquestion-01", "scores5.image", "User-Fragen");
    scoreBoard.add("userreferals", "img/icon16-adduser-01", "scores6.image", "User-Werbung");
   
    scoreBoard.show(document.getElementById("body.ranking"));
    
}

/**
 * Tabbed score board implementation.
 * @param {string} boardname the unique name of the score board to create
 */
function ScoreBoard(boardname) {
    var tabs = new Array();
    var currentlyShownTab;
    var rankingDiv;

    /**
     * Adds a score tab to the score board.
     * @param {string} id the id of the score type represented by this tab
     * @param {string} imgsrc the prefix of the image to use for this tab, .gif or -inactive.gif will be appended
     * @param {string} imgid the id of the image to use for this tab, can be used for dynamic language updates
     * @param {string} imgalt the initial alt text of the tab image
     */
    this.add = function(id, imgsrc, imgid, imgalt) {
        tabs.push(new ScoreTab(id, imgsrc, imgid, imgalt));
    }
    
    /**
     * Displays the score board within a given DOM component.
     * @param {object} parent the DOM element to append the score board to
     */
    this.show = function(parent) {
        // create tab headers
        for (var i=0; i<tabs.length; i++) {
            var img = document.createElement("img");
            img.id = tabs[i].getImageId();
            img.src = (i==0) ? tabs[i].getActiveImageSource() : tabs[i].getInactiveImageSource();
            img.alt = tabs[i].getImageAlt();
            img.title = tabs[i].getImageAlt();
        
            var div = document.createElement("div");
            div.id = boardname + ".tab1";
            div.className = (i==0) ? "tab-active" : "tab-inactive";
            div.style.left = (i * 20) + "px";
            div.onclick = function() { switchTo(this); }
            div.appendChild(img);

            parent.appendChild(div);
            tabs[i].setImage(img);
            tabs[i].setDiv(div);
            if (i==0) currentlyShownTab = tabs[i];

        }
        // score board body
        rankingDiv = document.createElement("div");
        rankingDiv.id = "ranking";
        rankingDiv.className = "ranking";
        parent.appendChild(rankingDiv);
    }
    
    /**
     * Called upon a score tab click. Updates tab and score display.
     * @param {object} root the DOM element on which the click occurred
     */
    var switchTo = function(root) {
        for (var i=0; i<tabs.length; i++) {
            var active = (tabs[i].getDiv() == root);
            tabs[i].getDiv().className = (active) ? "tab-active" : "tab-inactive";
            tabs[i].getImage().src = (active) ? tabs[i].getActiveImageSource() : tabs[i].getInactiveImageSource();
            if (active) currentlyShownTab = tabs[i];
        }
        updateDisplay();
    }
    
    /**
     * Returns a score tab for a given type of scores.
     * @param {string} id the type of score of interest
     * @return {object} the tab associated with the given id
     */
    var getTab = function(id) {
        for (var i=0; i<tabs.length; i++)
            if (tabs[i].getId() == id)
                return tabs[i];
        return null;
    }
    
    /**
     * Updates the stored rankings.
     * @param {string} id the type of score to update
     * @param {object} ranking the new ranking to store
     */
    this.update = function(id, ranking) {
        var tab = getTab(id);
        if (tab) tab.setRanking(ranking);
        if (tab == currentlyShownTab) updateDisplay();
    }
    
    /**
     * Updates the ranking display.
     */
    var updateDisplay = function() {
        rankingDiv.innerHTML = "";
        if (currentlyShownTab && currentlyShownTab.getRanking())
            rankingDiv.appendChild(getRankingTable(currentlyShownTab.getRanking()));
    }
    
    /**
     * Gets a HTML table representation for a given ranking.
     * @param {object} rnk the ranking to generate a table for
     * @return {object} the DOM table describing the scores
     */
    var getRankingTable = function(rnk) {
        var type = rnk.scoreType;
        var tbody = document.createElement("tbody");
        for(i = 0; i < rnk.ranks.length; i++) {
            // prepare elements
            var crank = document.createElement("td");
            var cnick = document.createElement("td");
            var cscore = document.createElement("td");
            var row = document.createElement("tr");
            
            // position
            if (rnk.ranks[i] > 0) crank.appendChild(document.createTextNode(rnk.ranks[i] + "."));
            else crank.appendChild(document.createTextNode(" "));

            // name                        
            var namelength = 10;
            if (type == "day") namelength = namelength + 2;
            var tnick = rnk.nicks[i];
            if (tnick.length > namelength) 
                tnick = tnick.substring(0, namelength - 2) + "...";
            cnick.appendChild(document.createTextNode(tnick));
            
            // score
            cscore.appendChild(document.createTextNode(rnk.scores[i]));
            cscore.style.textAlign = "right";

            // bold row for current user                
            if(rnk.nicks[i] == username) {
                cnick.title = rnk.nicks[i];
                crank.style.fontWeight="bold";
                cnick.style.fontWeight="bold";
                cscore.style.fontWeight="bold";
            }
            
            // finalize/add row
            row.appendChild(crank);
            row.appendChild(cnick);
            row.appendChild(cscore);
            tbody.appendChild(row);
        }                       
        var tbl = document.createElement("table");
        tbl.appendChild(tbody);
        tbl.style.width = "100%";
        return tbl;
    }
}

/**
 * Tab for tabbed score board.
 * @param {string} id the type of score represented by this tab
 * @param {string} imgsrc the prefix of the image to use for this tab, .gif or -inactive.gif will be appended
 * @param {string} imgid the id of the image to use for this tab, can be used for dynamic language updates
 * @param {string} imgalt the initial alt text of the tab image
 */
function ScoreTab(id, imgsrc, imgid, imgalt) {
    var ranking, div, image;

    this.getId = function() {
        return id;
    }
    
    this.getActiveImageSource = function() {
        return imgsrc + ".gif";
    }
    
    this.getInactiveImageSource = function() {
        return imgsrc + "-inactive.gif";
    }
    
    this.getImageId = function() {
        return imgid;
    }
    
    this.getImageAlt = function() {
        return imgalt;
    }
    
    this.setRanking = function(r) {
        ranking = r;
    }
    
    this.getRanking = function() {
        return ranking;
    }

    this.setDiv = function(d) {
        div = d;
    }
    
    this.getDiv = function() {
        return div;
    }

    this.setImage = function(i) {
        image = i;
    }
    
    this.getImage = function() {
        return image;
    }
}