/**
 * Tooltip Manager.
 * Replaces the whole text in the document
 * with a linked version for some tooltip
 * magic
 *
 * @param replacements the replacement object
 */
function TooltipManager(replacements, lang) {
    this._replacements   = replacements;
    this._target         = null;
    this._tooltip        = null;
    this._lang           = lang;
    this._playerIDs      = new Array;
    this._playerURL      = '/' + lang + '/profis/team/spieler/';
    this._playerImageURL = '/pics/players/tooltip_';
    this._translations   = {
        "Profile"     : {"de" : "Profil",       "en" : "Profile"},
        "Position"    : {"de" : "Position",     "en" : "Position"},
        "Goals"       : {"de" : "Tore",         "en" : "Goals"},
        "Assists"     : {"de" : "Assists",      "en" : "Assists"},
        "Shots"       : {"de" : "Torschüsse",   "en" : "Shots on Target"},
        "Appearances" : {"de" : "Einsätze",     "en" : "Appearances"},
        "Defender"    : {"de" : "Abwehr",       "en" : "Defense"},
        "Midfielder"  : {"de" : "Mittelfeld",   "en" : "Midfield"},
        "Goalkeeper"  : {"de" : "Tor",          "en" : "Goal"},
        "Forward"     : {"de" : "Sturm",        "en" : "Forward"}
    }

    
    this._key_delim = ' ';
    this._max_buf_length = 2;
    this._createLookupTable = function(players) {
        var out = {}, key = null;

        for (var id in players) {
            key = players[id]['k_name'] != '' ? players[id]['k_name'].toLowerCase() : players[id]['l_name'].toLowerCase();
            out[key] = id; 
            key = players[id]['f_name'].toLowerCase() + this._key_delim + players[id]['l_name'].toLowerCase();
            out[key] = id;
            this._playerIDs.push(id);
        };

        return out;
    };

    this._lookupTable = this._createLookupTable(replacements);
    var _that = this;

    this.getPlayerIDs = function(){
        return this._playerIDs;
    }

    /**
     * Replaces some text with
     * links
     */
    this.replace = function() {
        $('.artikelbox, .artikelbox *').each(function () {
            // Compare node against black list
            if (this.className.indexOf('tooltipIgnore') == -1 && 
                this.className.indexOf('unterschrift') == -1 && 
                this.nodeName != 'H3') {
                for (var i = 0; i < this.childNodes.length; i++) {
                    var child = this.childNodes[i];
                    if (child.nodeType == 3) {
                        this.replaceChild(_that._replace($(child).text()), child);
                    } 
                }
            }
        });
        //add some mouse action
        $('.tooltipManager').mouseenter(jQuery.proxy(_that._hovered, _that));
        $('.tooltipManager').mouseleave(jQuery.proxy(_that._hideTooltip, _that));
    };

    /**
     * Replace player names with player links, by matching words against the
     * lookup table
     *
     * @param the string within which the names shoudl be replaced
     */
    this._replace = function(str) {
        var reg       = new RegExp('[\\w\\xA0-\\xFF]+', 'g');
        var out       = document.createElement('span');
        var m         = null;
        var player_id = null;
        var buffer    = [];
        var idx       = 0;
        var tok_idx   = 0;

        $(out).css('display', 'inline');
        while (m = reg.exec(str)) {
            buffer.push(m);
            tok_idx = buffer[0].index;

            if (player_id = _that._matchbuf(buffer)) {
                out.appendChild(document.createTextNode(str.substring(idx, tok_idx)));
                var lnk = document.createElement('span');
                lnk.innerHTML = 
                    '<a href="' + this._playerURL + player_id + 
                    '.php" id="' + player_id + 
                    '" class="tooltipManager">' + buffer.join(_that._key_delim) + 
                    '</a>';

                out.appendChild(lnk);
                idx = reg.lastIndex;
                buffer  = [];
            }
            // If lookup has failed at max lookup length. Remove oldest token
            // and try again.
            if (buffer.length == _that._max_buf_length) {
                buffer.shift();
                tok_idx = buffer[0].index;

                if (player_id = _that._matchbuf(buffer)) {
                    out.appendChild(document.createTextNode(str.substring(idx, tok_idx)));
                    var lnk = document.createElement('span');
                    lnk.innerHTML = 
                        '<a href="' + this._playerURL + player_id + 
                        '.php" id="' + player_id + 
                        '" class="tooltipManager">' + buffer.join(_that._key_delim) + 
                        '</a>';

                    out.appendChild(lnk);
                    idx = reg.lastIndex;
                    buffer  = [];
                }
            }    
        }
        if (out.childNodes.length == 0) {
            $(out).text(str.substring(idx));
        } else {
            out.appendChild(document.createTextNode(str.substring(idx)));
        }

        return out;
    };

    /*
    *   Match the token buffer array against the player lookup table
    */
    this._matchbuf = function(buf) {
        var out = null;

        if ((buf != null) && (buf.length > 0)) {
            var key = buf.join(_that._key_delim).toLowerCase();
            out = _that._lookupTable[key];
        }

        return out;
    };

    /**
     * Display tooltip
     */
    this._hovered = function(ev) {
        var position=$(ev.target).offset();

        //find the correct value
        var obj = this._replacements[$(ev.target).attr('id')];

        //show or create the tooltip
        if (this._tooltip == null) {
            this._buildTooltip();
        } else {
            this._tooltip.show();
        }

        //compute positions
        var top = position.top- this._tooltip.height()-12;
        var left = position.left-150;
    
        if (top < 0) top = 0;
        if (left < 0) left = 0;
    
        //set positions
        this._tooltip.css({
            'top'  : top + "px",
            'left' : left + "px"
        });

        //fill it
        _that._fillTooltip(obj, $(ev.target).attr('id'));
    };

    /**
     * Creates the tooltip with various text fields
     */
    this._buildTooltip = function() {
        this._tooltip = $('<div id="tooltipManagerWindow"></div>');
        $("body").append(this._tooltip);
        var tt = '<div class="ttmBody">' +
            '<img src="" class="profileImg" alt="" />' +
            '<h3 class="font12b DarkGreen"></h3>' +
            '<table class="info" cellspacing="0" cellpadding="0">' +
            '<tr><td class="grey font12b">' + this._translate("Position") + '</td><td class="grey position"></td></tr>' +
            '<tr><td class="font12b">' + this._translate("Appearances") + '</td><td class="appearances"></td></tr>' +
            '<tr><td class="grey font12b">' + this._translate("Goals") + '</td><td class="grey goals"></td></tr>' +
            '<tr><td class="font12b">' + this._translate("Assists") + '</td><td class="assists"></td></tr>' +
            '<tr><td class="grey font12b">' + this._translate("Shots") + '</td><td class="grey shots"></td></tr>' +
            '</table>' +
            '</div>' +
            '</div>';
        this._tooltip.html(tt);
        this._tooltip.find('.close').click(jQuery.proxy(this._hideTooltip, this));
    };

    /**
     * Hides the tooltip, when x was clicked
     */
    this._hideTooltip = function(ev) {
        this._tooltip.hide();
    };

    /**
     * Fill in the data into the tooltip
     *
     * @param obj the player to fill in
     * @param key the players key
     */
    this._fillTooltip = function(obj, key) {
        this._tooltip.find("h3").text(obj.name + " (" + obj.jersey + ")");
        this._tooltip.find(".button a").attr("href", this._playerURL + key + ".php");
        this._tooltip.find(".profileImg").attr("src", this._playerImageURL + key + ".jpg");
        this._tooltip.find(".position").text(this._translate(obj.position));
        this._tooltip.find(".appearances").text(obj.stat.games);
        this._tooltip.find(".goals").text(obj.stat.goals);
        this._tooltip.find(".assists").text(obj.stat.assists);
        this._tooltip.find(".shots").text(obj.stat.shots);
    };

    /**
     * Translates the given text
     *
     * @param t string the text to translate
     * @return translation
     */
    this._translate = function(t) {
        return this._translations[t][this._lang];
    }
}

