/*
(c) CopyLeft 2003, 2004 Benn Herrera benn@bennherrera.com
Permission granted to copy, use, and modify this code so long as this notice is left intact.
If this code is used in any commercial product, appropriate attribution is required.
Full terms at http://www.gnu.org/copyleft/gpl.html
*/

//
// This file contains the code that implements the high score table
// class.
//

function setNameAndScore( str ) {
    var nameAndScore = str.split( this.seper );
    this.name        = decodeURI( nameAndScore[0] );
    this.score       = nameAndScore[1];
}

function getNameAndScore() {
    return encodeURI( this.name ) + this.seper + this.score;
}

function genRow( idx ) {
    idx = idx & 1;
    return "<tr class=\"highScoreRow" + idx + "\">"                        +
           "<td class=\"highScoreNameCell\">"       + this.name  + "</td>" +
           "<td class=\"highScoreCell\">"           + this.score + "</td>" +
           "</tr>";
}

function HighScoreEntry() {    
    var nameAndScore = 0;
    var name         = 0;
    var score        = -1;
        
    switch ( arguments.length ) {
        case 1:
            nameAndScore = arguments[0];
            break;
        case 2:
            name = arguments[0];
            score = arguments[1];
            break;
    }
    
    this.seper           = "+";
    this.setNameAndScore = setNameAndScore;
    this.getNameAndScore = getNameAndScore;
    this.genRow          = genRow;
    this.prev            = 0;
    this.next            = 0;
    this.score           = 0;
    this.name            = "player";
    
    if ( nameAndScore ) {
        this.setNameAndScore( nameAndScore );
    } else if ( name ) {
        this.name  = name;
        this.score = score;
    }
}

function unpackScoresCookie() {
    var cookieStr  = document.cookie; 
    var varVal     = 0;
    var entryStrs  = 0;
    var i;
           
    if ( cookieStr != "" ) {
        var vars = cookieStr.split( this.varsSeper );
        
        for ( i = 0; i < vars.length; i++ ) {
            varVal = vars[i].split( this.varValSeper );
            
            if ( varVal[0].indexOf("packedScores") >= 0 && varVal[1] != "0" ) {
                entryStrs = varVal[1].split( this.entrySeper );
            } else if ( varVal[0].indexOf( "expires" ) >= 0 ){
                continue;
            } else {
                eval( "this." + varVal[0] + " = \"" + varVal[1] + "\";" );
            } 
        }
    }
    
    if ( entryStrs ) {
        for ( i = 0; i < entryStrs.length; i++ ) {
            this.appendScore( entryStrs[i] );
        }
    }
}

function packScoresCookie() {
    document.cookie = "lastPlayer=" + this.lastPlayer;
    
    var packedScores = 0;
    
    for ( var entry = this.entries; entry; entry = entry.next ) {
        if ( packedScores )
            packedScores += this.entrySeper + entry.getNameAndScore();
        else
            packedScores = entry.getNameAndScore();
    }
    
    var cookieStr      = "packedScores=" + packedScores;
    var expirationDate = new Date( 2999, 1, 1 );
    var expiration     = "expires=" + expirationDate.toGMTString();
     
    document.cookie = cookieStr + this.varsSeper + expiration;
}

function displayScores() {
    var scoreRows = "";
    var i = 0;
    
    for ( var entry = this.entries; entry; scoreRows += entry.genRow( i++ ), entry = entry.next );

    for ( ; i < this.maxEntries; scoreRows += new HighScoreEntry( "nobody", 0 ).genRow( i++ ) );
     
    HighScoreRows.innerHTML = "<table class=\"highScoreEntriesTable\">" + scoreRows + "</table>";
}

function insertScore( name, score ) {
    this.lastPlayer = name;
    
    // highest score?
    if ( !this.entries || score >= this.entries.score ) {
        this.prependScore( name, score );
    // lowest score?
    } else if ( score < this.lastEntry.score ) {
        if ( this.numEntries >= this.maxEntries )
            return false;
        
        this.appendScore( name, score );
    // we have to actually insert
    } else {
        var newEntry = new HighScoreEntry( name, score );
            
        for ( var entry = this.entries; score < entry.score; entry = entry.next );
        
        newEntry.next      = entry;
        newEntry.prev      = entry.prev;      
        newEntry.prev.next = newEntry;     
        entry.prev         = newEntry;
        
        this.numEntries++;
    }
    
    while ( this.numEntries > this.maxEntries ) {
        this.removeLowestScore();
    }
      
    return true;
}

function prependScore() {
    var entry = (arguments.length > 1) ? new HighScoreEntry( arguments[0], arguments[1] ) : new HighScoreEntry( arguments[0] );
   
    if ( this.entries ) {
        this.entries.prev = entry;
        entry.next        = this.entries;
        this.entries      = entry;
    } else {
        this.entries = this.lastEntry = entry;
    }
    
    this.numEntries++;
}

function appendScore() {
    var entry = (arguments.length > 1) ? new HighScoreEntry( arguments[0], arguments[1] ) : new HighScoreEntry( arguments[0] );
    
    if ( this.entries ) {
        this.lastEntry.next = entry;
        entry.prev          = this.lastEntry;
        this.lastEntry      = entry;
    } else {
        this.entries = this.lastEntry = entry;
    }
    
    this.numEntries++;
}

function removeLowestScore() {
    if ( this.numEntries == 0 )
        return;
    
    this.numEntries--;
    
    if ( this.numEntries == 0 ) {
        this.entries = this.lastEntry = 0;
        return;
    }
    
    this.lastEntry = this.lastEntry.prev;
    this.lastEntry.next = 0;
}

function clearScores() {
    this.entries    = 0;
    this.lastEntry  = 0;
    this.numEntries = 0;
    this.packScoresCookie();
    this.displayScores();
}

function HighScoreTable() {
    this.entrySeper         = ":";
    this.varsSeper          = ";";
    this.varValSeper        = "=";
    this.maxEntries         = 5;
    this.numEntries         = 0;
    this.appendScore        = appendScore;
    this.prependScore       = prependScore;
    this.insertScore        = insertScore;
    this.unpackScoresCookie = unpackScoresCookie;
    this.packScoresCookie   = packScoresCookie;
    this.displayScores      = displayScores;
    this.removeLowestScore  = removeLowestScore;
    this.clearScores        = clearScores;
    this.entries            = 0;
    this.lastEntry          = 0;
    this.lastPlayer         = "player";
    
    this.unpackScoresCookie();
    this.displayScores();
    
    getCtl( "playerNameEdt" ).value = this.lastPlayer;
}


