var jsReady = false;
var noClicks = true;
var levelsPerPage=40;
var sveLvlDisp="none";
// state 0 : level by level; 1 : play for highscores; 2 : edit level
var state=0;
function debug(txt) {
    //var debugdiv=document.getElementById("debug");
    //if (debugdiv) debugdiv.innerHTML+=txt+"<br>";
}
function dispError(txt) {
    debug('dispError ['+txt+']')
    var errordiv=document.getElementById("error");
    if (errordiv) {
        if (txt!='') errordiv.style.display=""; else  errordiv.style.display="none";
        errordiv.innerHTML=txt;
    }
}
function xajax_asynchError(sFunction,errorString) {
    if (sFunction!='rate') asynchError(errorString);
}
var flash;
function flashReady() {
    debug("flashReady");
    if(navigator.appName.indexOf("Microsoft") != -1) {
        flash = window.flashObject;
    }else {
        flash = window.document.flashObject
    }
    noClicks=false;
    updateButtons();
    var jsObj=document.getElementById('jsneed');
    jsObj.style.display="none";
    if (startLvl) levelPlay(startLvl);
    //display buttons for playing and managing levels
}
function isReady() {
    debug("isReady="+jsReady);
    return jsReady;
}

var playerid=-1;
var authoriz=0; // 0 for visitor , 1 for member , 2 for validate new level, 4 for offical levels, 5 for game author, 10 for super admin
var ubase="../";
var lang=1;
function pageInit(a,pid,l,base) {
    lang=l;
    ubase=base;
    authoriz=a;
    if (authoriz<1) {
        offPlayedLoaded=1;
        var apdata=readCookie('peperegame'+gaid);
        if (apdata) offPlayedData(apdata);
    }
    if (pid!='') playerid=parseInt(pid);
    debug("authoriz "+a+" playerid "+pid);
    jsReady = true;
    debug("pageInit");
}


var mtxt=Array(Array(),Array());
function setMultiLang(c,id,txt) {
    mtxt[c][id]=txt;
}



//IHM
var currentMn=-1;

//official, popular, new, yours, unrated
var pageLevels = new Array(new Array(),new Array(),new Array(),new Array(),new Array(),new Array());
var levelsInfo = new Array();  // Nominal info (name, rnk etc.) index = id from database
var favInfo = new Array();  // favorites yes or no
var keepData=100;  // number of cached datas
var levelsData = new Array(keepData);  // Binary data index = id from database
var currentPages = new Array(0,0,0,0,0,0);
var currentNbItems = new Array(-1,-1,-1,-1,-1,-1);
var offPlayed=new Array();
var offPlayedLoaded=-1;
var lvlDataCursor=0;
var userNames=new Array();

function setUsers(u) {
    debug("setUsers("+u+")");
    for (var i in u) {
        if (parseInt(i)==i) {
            userNames.push(u[i]);
        }
    }
    noClicks=false;
}
function getUserName(usid) {
    var ret=new Array(usid.length);
    for (var j=0;j<usid.length;j++) {
        ret[j]=false;
    }
    var countmax=usid.length;
    var count=0;
    
    for (var i in userNames) {
        if (parseInt(i)==i) {
            var udidx=usid.indexOf(userNames[i][0]);
            if (udidx>=0) {
                for (var j=0;j<countmax;j++) {
                    if (parseInt(j)==j) {
                        if (userNames[i][0]==usid[j]) {
                            ret[j]=userNames[i][1];
                            count++;
                            if (count>=countmax) break;
                        }
                    }
                }
                if (count>=countmax) break;
            }
        }
    }
    return ret;
}

function offPlayedData(data) {
    debug("offPlayedData "+data);
    var arrdata=data.split("#");
    var  lvlid=-1;
    for (var i in arrdata) {
        if (parseInt(i)==i) {
            if (arrdata[i]=="null") arrdata[i]=0;
            debug(i+" "+arrdata[i]);
            if (parseInt(arrdata[i])==arrdata[i]) {
                if (lvlid==-1) {
                    lvlid=parseInt(arrdata[i]);
                } else { //score
                    offPlayed[lvlid]=parseInt(arrdata[i]);
                    debug("offPlayed["+lvlid+"]= "+arrdata[i]);
                    lvlid=-1;
                }
            }
        }
    }
    offPlayedLoaded=1;
    globalscore=alreadyGlobScore();
    if (globalscore>bestScore) bestScore=globalscore;
    showGlobScore();
}
function allPlayedData() {
    var ret=new Array();
    debug("allPlayedData "+offPlayed.length);
    for (var i in offPlayed) {
        if (parseInt(i)==i) {
            ret.push(i+"#"+offPlayed[i]);
        }
    }
    debug(ret.join("#"));
    return ret.join("#");
}
function allOffLoaded() {
    if (currentNbItems[0]<0) return false;
    var count=0;
    for (var i in pageLevels[0]) {
        if (parseInt(i)==i) {
            if (pageLevels[0][i]!==false) count++;
        }
    }
    debug("allOffLoaded "+count+">="+currentNbItems[0]);
    return (count>=currentNbItems[0]);
}
function alreadyGlobScore() {
    var correct=allOffLoaded();
    debug("alreadyGlobScore("+correct+")");
    debug ("before "+offPlayed);
    var debuglevels='';
    var ret=0;
    for (var i in offPlayed) {
        if (parseInt(i)==i) {
            if (correct) {
                if ((levelsInfo[i])&&(levelsInfo[i][4]>=2)&&(parseInt(offPlayed[i])==offPlayed[i])) {
                    ret+=parseInt(offPlayed[i]);
                    debuglevels+=" "+i+"=("+parseInt(offPlayed[i])+")";
                } else {
                    //debug("splice("+i+")");
                    //offPlayed.splice(i,1);
                    offPlayed[i]=null;
                }
            } else {
                if (parseInt(offPlayed[i])==offPlayed[i]) {
                    ret+=parseInt(offPlayed[i]);
                    debuglevels+=" "+i+"=("+parseInt(offPlayed[i])+")";
                }
            }
        }
    }
    debug ("after "+debuglevels);
    return ret;
}
function alreadyPlayed(lvlid) {
    var ret=false;
    if (offPlayed[lvlid]) return offPlayed[lvlid]; else return false;
    return ret;
}
function getLevelData(id) {
    var ret=false;
    debug("getLevelData("+id+") length ["+levelsData.length+"]");
    for (var n = 0; n < levelsData.length; n++) {
        if ((levelsData[n])&&(levelsData[n][0])) {
            debug("["+id+"] == ["+levelsData[n][0]+"]");
            if (id==levelsData[n][0]) {
                ret=levelsData[n][1];
                break;
            }
        }
    }
    return ret;
}
//DATA UPDATE

function setPageLevels(t,la) {
    debug("setPageLevels("+t+","+la.length+")");
    //pageLevels[t][pg]=new Array(levelsPerPage);
    for (var n in la) {
        if (n == parseInt(n)) {
            debug("pageLevels["+t+"]["+n+"]="+la[n]+";");
            pageLevels[t][n]=la[n][0];
            setLevelInfo(la[n][0],la[n]);
            if (t==3) {
                favInfo[la[n][0]]=1;
            }
        }
    }
}
function setLevelInfo(lvlid,ar) {
    debug("setLevelInfo("+lvlid+","+ar+")");
    levelsInfo[lvlid]=ar;
}
function setLevelData(lvlid,dt) {
    debug("setLevelData("+lvlid+","+dt+")");
    
    for (var n = 0; n < levelsData.length; n++) {
        if ((levelsData[n])&&(levelsData[n][0])) {
            //debug("["+id+"] == ["+levelsData[n][0]+"]");
            if (lvlid==levelsData[n][0]) {
                levelsData[n][1]=dt;
                return;
            }
        }
    }
    
    lvlDataCursor++; if (lvlDataCursor>=keepData) lvlDataCursor=0;
    levelsData[lvlDataCursor]=new Array(lvlid,dt);
    debug("levelsData["+lvlDataCursor+"]=("+lvlid+","+dt+");");
}
function setItems(t,nitms) {
    currentNbItems[t]=nitms;
}
Array.prototype.indexOf = function(v) {
    for (var i in this) {
        if(this[i]==v) { return i; }
    }
    return -1;
};
function rmvLvl(l,lvlid) {
    debug("rmvLvl("+l+","+lvlid+")");
    if (currentNbItems[l]>0) {
        var il = (pageLevels[l]).indexOf(lvlid);
        if (il>-1) {
            debug("found("+il+","+lvlid+")");
            pageLevels[l].splice(il,1);
            currentNbItems[l]--;
        }
        
    }
}
function addLvlByDateDesc(l,lvlid) {
    if (currentNbItems[l]>-1) {
        if (levelsInfo[lvlid]) {
            var tm=levelsInfo[lvlid][12];
            var ii=0;
            for (var i in pageLevels[l]) {
                var id=pageLevels[l][i];
                if (levelsInfo[id]) {
                    debug(tm+" > "+levelsInfo[id][12]+" ?");
                    if (tm>levelsInfo[id][12]) {break;}
                    else ii=parseInt(i)+1;
                }
            }
            debug("insert "+ii);
            pageLevels[l].splice(ii,0,lvlid);
            currentNbItems[l]++;
        } else currentNbItems[l]=-1;
    }
}



// EVENTS
function click() {
    dispError('');
    noClicks=true;
    
}

var successCks=new Array(0,0,0,0,0,0,0,0,0,0,0);
function incSess(sess) {
    successCks[sess]++;
    if (successCks[sess]>10) return false;  //not allowed to call more tan 10 times
    else return true;
}
function cleanSess(sess) {
    successCks[sess]=0;
}
function pageSel(l,pg) {
    if (!noClicks) {
        currentPages[l]=pg;
        display(l,true);
    }
}
function menuSel(l) {
    if (!noClicks) menuSelInner(l);
}
function levelPlay(id) {
    if (!noClicks) levelPlayInner(id);
}
function levelEdit(id) {
    if (!noClicks) {
        hideLvls();
        state=2;
        updateButtons();
        levelEditInner(id);
    }
}
function save() {
    debug("save");
    if (!noClicks) {
        if (state==2) saveInner();
    }
}

function startPlaying() {
    if (!noClicks) gPlay();
}
var globalscore=0;
var rk=-1;
function gPlay() {
    //launch highscore play
    //debug("gPlay()");
    hideLvls();
    //debug("gPlay 1");
    globalscore=alreadyGlobScore(); showGlobScore();
    rk=0;
    state=1;
    dispCacheLevel(-1);
    //debug("gPlay 2");
    updateButtons();
    //debug("gPlay 3");
    playNextOffLevel();
}

function playNextOffLevel() {
    debug("playNextOffLevel("+rk+")");
    if (state!=1) return;
    var cload=false;
    var citems=false;
    if (currentNbItems[0]<0) {
        cload=true;
        citems=true;
    } else {
        if (rk>=currentNbItems[0]) {
            cleanSess(2);
            dispError(mtxt[1][30]);
            saveGlobalScore(globalscore);
            return;
        }
        cload=true;
        while ((pageLevels[0][rk])&&(pageLevels[0][rk]!==false)) {
            if (alreadyPlayed(pageLevels[0][rk])===false) {
                cload=false;
                break;
            }
            rk++;
            if (rk>=currentNbItems[0]) {
                cleanSess(2);
                dispError(mtxt[1][30]);
                saveGlobalScore(globalscore);
                return;
            }
        }
    }
    debug("load needed ? ("+cload+")");
    if (cload) {
        var nblit=80;
        if (!citems) if (rk+nblit>currentNbItems[0]) nblit=currentNbItems[0]-rk;
        
        if (incSess(2)) {
            xajax_loadLevelsAndPlay(0,new Array(new Array(rk,nblit)),citems,offPlayedLoaded);
        } else {
            cleanSess(2);
            dispError("Too many 'load official levels' requests!");
        }
        return;
    } else {
        cleanSess(2);
        levelPlayInner(pageLevels[0][rk]);
    }
}
var bestScore=0;
function saveGlobalScore(s) {
    debug("load saveGlobalScore("+s+" "+bestScore+")");
    if (authoriz>0) {
        if (s>bestScore) {
            xajax_saveGlobalScore(playerid,s,allPlayedData());
        }
    } else {
        dispError("Score saved on your local storage.");
        createCookie('peperegame'+gaid,allPlayedData(),365);
    }
}
function saveScore(id,s) {
    showLvlScore(id,s);
    if (authoriz>0) {
        if (levelsInfo[id]) {
            if (s>levelsInfo[id][10]) {
                xajax_saveScore(id,playerid,s);
            }
        } else xajax_saveScore(id,playerid,s);
    } else {
        dispError("You must be logged in to save your score.");
    }
}
var curEditedLvl=-1;
function levelEditInner(id) {
    if (state!=2) return;
    //edit level (id=-1 for new level)
    debug("levelEditInner("+id+")");
    click();
    
    curEditedLvl=id;
    //get data
    
    var lvldata='';
    if (id>=0) {
        lvldata=getLevelData(id);    
    }
    //debug("getLevelData="+lvldata);
    if (lvldata!==false) {
        dispCacheLevel(id);
        var tf=document.getElementById("lvlname");
        if (tf) {
            if (id<0) tf.value='';
            else tf.value=levelsInfo[id][1];
        }
        debug("flash("+flash+").editLevel("+id+",'"+lvldata+"')");
        flash.editLevel(id,lvldata);
    } else {
        debug("xajax_lvlDataAndEdit");
        xajax_lvlDataAndEdit(id);
    }
}
function levelPlayInner(id) {
    debug("levelPlayInner("+id+")");
    click();
    //get data
    var lvldata=getLevelData(id);
    //debug("getLevelData="+lvldata);
    if (lvldata!=false) {
        dispCacheLevel(id);
        debug("flash("+flash+").playLevel("+id+","+levelsInfo[id][1]+","+lvldata+")");
        flash.playLevel(id,levelsInfo[id][1],lvldata);
    } else {
        debug("xajax_lvlDataAndPlay");
        xajax_lvlDataAndPlay(id);
    }
}
//RETURN FROM FLASH
function levelEdited(id,ack,err) {
    debug("levelEdited("+id+","+ack+","+err+")");
    if (ack<1) {
        dispError(err);
        nominal();
    } else {
        noClicks=false;
    }
}
//RETURN FROM FLASH
function levelPlayed(id,ack,err) {
    debug("levelPlayed("+id+","+ack+","+err+")");
    if (ack<1) {
        dispError(err);
        nominal();
    } else {
        if (alreadyPlayed(id)) {
            globalscore=alreadyGlobScore(); showGlobScore();
        }
        noClicks=false;
    }
}
//RETURN FROM FLASH
function levelCompleted(id,score,over) {
    debug("levelCompleted("+id+","+score+","+over+")");
    saveScore(id,score);
    if (state==1) {
        if (levelsInfo[id]) {
            if (levelsInfo[id][4]>1) {
                offPlayed[id]=score;
                //globalscore+=score;
                globalscore=alreadyGlobScore();
                showGlobScore();
                if (!over) {
                    rk++;
                    playNextOffLevel();
                } else {
                    saveGlobalScore(globalscore);
                }
            }
        }
    } else {
        var alS=0;
        if (levelsInfo[id]) {
            if (levelsInfo[id][4]>1) {
                alS=alreadyPlayed(id);
                if (alS===false) {
                    alS=0;
                }
                if (score>alS) {
                    offPlayed[id]=score;  //new score
                    globalscore=alreadyGlobScore(); showGlobScore();
                    saveGlobalScore(globalscore);
                }
            }
        }
    }
    dispCacheLevel(id);
    if (lasttabdisp>=0) display(lasttabdisp,false);
}
function saveInner() {
    //save new level
    //curEditedLvl
    click();
    flash.getLevelData(curEditedLvl);
}

var pendingData='';
function levelData(id,lvlData,ack,err) {
    if (ack<1) {
        asynchError("Not saved! "+err);
    } else {
        if ((lvlData!='')&&(lvlData!='undefined')&&(lvlData!='null')) {
            var tf=document.getElementById("lvlname");
            if (tf) {
                if (tf.value) {
                    pendingData=lvlData;
                    xajax_saveLevel(curEditedLvl,tf.value,lvlData);
                } else {
                    asynchError("Title must not be empty!");
                    tf.focus();
                }
            } else {
                asynchError("Not saved! Level name not found!");
            }
        } else {
            asynchError("Not saved! Level data is empty!");
        }
    }
}

function levelSaved(lvlid) {
    dispError(getGif('apply',mtxt[0][457]));
    dispCacheLevel(lvlid);
    if (curEditedLvl!=lvlid) {
        //new level
        //add in tab 4 & tab 5
        addLvlByDateDesc(4,lvlid);
        addLvlByDateDesc(5,lvlid);
    }
    curEditedLvl=lvlid;
    setLevelData(lvlid,pendingData);
    pendingData='';
    /*
    var tf=document.getElementById("lvlname");
    if (tf) {
        if (id<0) tf.value='';
        else tf.value=levelsInfo[id][1];
    }
    */
    updateLevel(lvlid);
}
function nominal() {
    if (state>0) {
        var updatelevelinfo=false;
        if (state==1) saveGlobalScore(globalscore);
        if (state==2) {
            if (curEditedLvl>=0) updatelevelinfo=true;
        }
        state=0;
        dispCacheLevel(curEditedLvl);
        updateButtons();
        restoreLvls();
        curEditedLvl=-1;
    }
    noClicks=false;
}
function asynchError(t) {
    noClicks=false;
    dispError(t);
}
var lvlShownOnce=false;
function showLevels() {
    //show level interface
    var lvlsObj=document.getElementById('lvls');
    if (lvlsObj.style.display=="") lvlsObj.style.display="none";
    else {
        if (!lvlShownOnce) {
            if (!noClicks) {
                lvlShownOnce=true;
                lvlsObj.style.display="";
                menuSelInner(0);
            }
        } else lvlsObj.style.display="";
    }
}
function refreshLevels() {
    if (!noClicks) {
        noClicks=true;
        
        pageLevels = new Array(new Array(),new Array(),new Array(),new Array(),new Array(),new Array());
        levelsInfo = new Array();
        dispCacheLevel(lastlvlinf);
        
        if (lasttabdisp>=0) display(lasttabdisp,true);
        else noClicks=false;
    }
}
function menuSelInner(l) {
    if (l!=currentMn) {
        click();
        if (currentMn>=0) {
            var mnc=document.getElementById("current");
            mnc.id="menu"+currentMn;
        }
        //display the tab
        display(l,true);
        
        currentMn=l;
        var mn=document.getElementById("menu"+currentMn);
        mn.id="current";
    }
}






//DISPLAY
function showGlobScore() {
    var globscoreObj=document.getElementById('globscore');
    if (globscoreObj) {
        var tmp=globalscore;
        if (bestScore>0) tmp+="<br><b class=small>"+bestScore+"</b>";
        globscoreObj.innerHTML=tmp;
    }
}
function showLvlScore(id,s) {
    var lvlscoreObj=document.getElementById('lvlscore'+id);
    if (lvlscoreObj) {
        lvlscoreObj.innerHTML=s;
    }
}
function updateButtons() {
    var shwlvlObj=document.getElementById('shwlvl');
    var gplayObj=document.getElementById('gplay');
    var nominalObj=document.getElementById('nominal');
    var asaveObj=document.getElementById('asave');
    var nwlvlObj=document.getElementById('nwlvl');
    var saveObj=document.getElementById('save');
    var lvlnameObj=document.getElementById('lvlname');
    
    if (state==0) {
        shwlvlObj.style.display="";
        gplayObj.style.display="";
        nominalObj.style.display="none";
        asaveObj.style.display="none";
        if (authoriz>0) {
        nwlvlObj.style.display="";
        saveObj.style.display="none";
        }
    } else if (state==1) { //highscore play
        shwlvlObj.style.display="none";
        gplayObj.style.display="none";
        nominalObj.style.display="";
        asaveObj.style.display="";
        if (authoriz>0) {
        nwlvlObj.style.display="none";
        saveObj.style.display="none";
        }
    } else if (state==2) { //edit
        shwlvlObj.style.display="none";
        gplayObj.style.display="none";
        nominalObj.style.display="";
        asaveObj.style.display="none";
        if (authoriz>0) {
        nwlvlObj.style.display="none";
        saveObj.style.display="";
        }
    }
    if (authoriz>0) lvlnameObj.style.display=saveObj.style.display;
}
function hideLvls() {
    var lvlsObj=document.getElementById('lvls');
    sveLvlDisp=lvlsObj.style.display;
    lvlsObj.style.display="none";
}
function restoreLvls() {
    var lvlsObj=document.getElementById('lvls');
    lvlsObj.style.display=sveLvlDisp;
}
var lastlvlinf=-1;
function dispCacheLevel(id) {
    debug("dispCacheLevel("+id+")");
    lastlvlinf=id;
    var levelObj=document.getElementById("levelinfo");
    if (levelsInfo[id]) {
        var levelInfo=levelsInfo[id];
        var lvlnb='';
        if ((currentNbItems[0]>=1)&&(levelInfo[4]>2)) lvlnb='Level <b>'+(levelInfo[4]-2)+'</b>/<b>'+currentNbItems[0]+"</b> - ";
        var tmp="<nobr>"+lvlnb+"<b class=lvltit>"+levelInfo[1];
        if (state==0) {
            if ((levelInfo[4]<2)||(authoriz>=4)) tmp+=" <a class=squarebut href='#h' onClick='levelPlay("+id+")'>"+getGif('play',mtxt[0][189])+"</a>";
            else if (levelInfo[4]>=2) {
                if (alreadyPlayed(id)!==false) tmp+=" <a class=squarebut href='#h' onClick='levelPlay("+id+")'>"+getGif('playul',mtxt[0][189])+"</a>";
                else tmp+=" <a class=squarebut href='#h' onClick='gPlay()'>"+getGif('playhs',mtxt[1][27])+"</a>";
            }
        }
        tmp+=" <a class=squarebut href='#h' onClick='levelMore("+id+")'>"+getGif('quiz',mtxt[0][398])+"</a>";
        tmp+="</b> &nbsp; <b id=lvlscore"+id+" class='globscore small'></b></nobr><br>";
        //TODO search in favorites.
        if ((authoriz>=1)) {
            var rating=1;
            var imgn='favorite';
            var txt=mtxt[0][451];
            debug("favInfo[id] "+favInfo[id]);
            if (favInfo[id]) {
                if (favInfo[id]>0) {
                    rating=0; imgn='favoriterej'; txt=mtxt[0][441]+" - "+txt;
                }
            }
            tmp+="<a class=squarebut href='#h' onClick='levelRate("+id+","+rating+")'>"+getGif(imgn,txt)+"</a> ";
        }
        if ((authoriz>=2)||((authoriz>=1)&&(playerid==levelInfo[3])&&(levelInfo[4]<2))) tmp+="<a class=adminbut href='#h' onClick='levelEdit("+id+")'>"+getGif('edit2',mtxt[0][433])+"</a> ";
        if ((authoriz>=4)&&(levelInfo[4]<2)) tmp+="<a class=adminbut href='#h' onClick='levelAdmin("+id+",2)'>"+getGif('promoteacc',mtxt[1][10]+" - "+mtxt[1][19])+"</a> ";
        if ((authoriz>=4)&&(levelInfo[4]>=2)) tmp+="<a class=adminbut href='#h' onClick='levelAdmin("+id+",1)'>"+getGif('promoterej',mtxt[1][10]+" - "+mtxt[1][20])+"</a> ";
        if ((authoriz>=4)&&(levelInfo[4]>=2)) tmp+="<a id='lvlrka"+id+"' href='#h' onClick='levelRank("+id+")'>[LEVEL <b id=lvlrk"+id+">"+(levelInfo[4]-2)+"</b>]</a><a href='#h' onClick='chLvlRk("+id+",-1)'>"+getGif('less','--')+"</a><a href='#h' onClick='chLvlRk("+id+",1)'>"+getGif('more','++')+"</a>";
        if ((authoriz>=2)&&(levelInfo[4]<1)) tmp+="<a class=adminbut href='#h' onClick='levelAdmin("+id+",1)'>"+getGif('accept2',mtxt[1][19])+"</a> ";
        if ((authoriz>=2)&&(levelInfo[4]<=1)&&(levelInfo[4]>-1)) tmp+="<a class=adminbut href='#h' onClick='levelAdmin("+id+",-1)'>"+getGif('reject2',mtxt[1][20])+"</a> ";
        if ((authoriz>=10)&&(levelInfo[4]<=0)) tmp+="<a class=adminbuth href='#h' onClick='levelAdmin("+id+",-2)'>"+getGif('remove',mtxt[0][441])+"</a> ";
        if (authoriz>=4) tmp+="<a class='adminbut small' href='#h' onClick='levelDelScores("+id+")'>[DEL_HIGHSCORES]</a>";
        if ((authoriz>=4)&&(levelInfo[4]>=2)) tmp+="<a class='adminbut small' href='#h' onClick='levelDelUserScores("+id+")'>[DEL_USERS_SCORES!]</a>";
        tmp+='<div class=small>'+dirlink.replace(/%d/g,id)+'</div>';
        tmp+='<div class=small>'+mtxt[0][98].replace(/%d/g,"<b>"+levelInfo[11]+"</b>")+'</div>';
        
        levelObj.innerHTML=tmp;
        var uids=new Array(levelInfo[3],levelInfo[5],levelInfo[7],levelInfo[9]);
        var unames=getUserName(uids);
        var authorObj=document.getElementById("author");
        if (unames[0]===false) {
            if (authorObj) authorObj.style.display="none";
        } else {
            if (authorObj) {
                //debug("["+uids[0]+"]["+unames[0]+"]");
                authorObj.style.display="";
                var authlkObj=document.getElementById("authlk");
                if (authlkObj) {
                    //debug("author display");
                    authlkObj.innerHTML="<a href='"+ubase+"login.php?action=viewp_"+uids[0]+"&lang="+lang+"'><b>"+unames[0]+"</b></a>";
                }
            }
        }
        var score1=levelInfo[6];
        var s1Obj=document.getElementById("sc1");
        var lochsObj=document.getElementById("lochs");
        if ((score1>0)&&(lochsObj)) lochsObj.style.display="";
        else if (lochsObj) lochsObj.style.display="none";
        if (s1Obj&&(score1>0)) {
            if (unames[1]!==false) {
                score1+=" ("+"<a href='"+ubase+"login.php?action=viewp_"+uids[1]+"&lang="+lang+"'><b>"+unames[1]+"</b></a>)";
            }
            s1Obj.innerHTML=score1;
        } else {
            if (s1Obj) s1Obj.innerHTML="";
        }
        var score2=levelInfo[8];
        var s2Obj=document.getElementById("sc2");
        if (s2Obj&&(score2>0)) {
            if (unames[2]!==false) {
                score2+=" ("+"<a href='"+ubase+"login.php?action=viewp_"+uids[2]+"&lang="+lang+"'><b>"+unames[2]+"</b></a>)";
            }
            s2Obj.innerHTML=score2;
        } else if (s2Obj) s2Obj.innerHTML="";
        var score3=levelInfo[10];
        var s3Obj=document.getElementById("sc3");
        if (s3Obj&&(score3>0)) {
            if (unames[3]!==false) {
                score3+=" ("+"<a href='"+ubase+"login.php?action=viewp_"+uids[3]+"&lang="+lang+"'><b>"+unames[3]+"</b></a>)";
            }
            s3Obj.innerHTML=score3;
        } else if (s3Obj) s3Obj.innerHTML="";
        
        return true;
    } else {
        levelObj.innerHTML="-";
        var authorObj=document.getElementById("author"); if (authorObj) authorObj.style.display="none";
        var lochsObj=document.getElementById("lochs"); if (lochsObj) lochsObj.style.display="none";
        var s1Obj=document.getElementById("sc1"); if (s1Obj) s1Obj.innerHTML="";
        var s2Obj=document.getElementById("sc2"); if (s2Obj) s2Obj.innerHTML="";
        var s3Obj=document.getElementById("sc3"); if (s3Obj) s3Obj.innerHTML="";
        return false;
    }
}

function levelMore(lvlid) {
    var uids=new Array();
    if ((levelsInfo[lvlid][3]>0)&&(uids.indexOf(levelsInfo[lvlid][3])<0)) uids.push(levelsInfo[lvlid][3]);
    if ((levelsInfo[lvlid][5]>0)&&(uids.indexOf(levelsInfo[lvlid][5])<0)) uids.push(levelsInfo[lvlid][5]);
    if ((levelsInfo[lvlid][7]>0)&&(uids.indexOf(levelsInfo[lvlid][7])<0)) uids.push(levelsInfo[lvlid][7]);
    if ((levelsInfo[lvlid][9]>0)&&(uids.indexOf(levelsInfo[lvlid][9])<0)) uids.push(levelsInfo[lvlid][9]);
    var unames=getUserName(uids);
    if (unames.indexOf(false)>=0) {
        if (!noClicks) {
            click();
            var missNames=new Array();
            for (var i in unames) {
                if (parseInt(i)==i) {
                    if (unames[i]===false) {
                        missNames.push(uids[i]);
                    }
                }
            }
            debug("xajax_loadUserNamesAndMore("+missNames+")");
            if (incSess(1)) xajax_loadUserNamesAndMore(lvlid,missNames);
            else {
                cleanSess(1);
                asynchError("Too many user names requests!");
            }
        }
    } else {
        cleanSess(1);
        dispCacheLevel(lvlid);
    }
}
function levelRate(lvlid,v) {
    debug("levelRate("+lvlid+","+v+")");
    if (!noClicks) {
        click();
        xajax_levelRate(lvlid,v);
    }
}
function levelDelScores(lvlid) {
    debug("levelDelScores("+lvlid+")");
    if (!noClicks) {
        click();
        xajax_levelAction(lvlid,1);
    }
}
function levelDelUserScores(lvlid) {
    debug("levelDelUserScores("+lvlid+")");
    if (!noClicks) {
        click();
        xajax_levelAction(lvlid,2);
    }
}
function updateLevelRate(lvlid,v) {
    //add or remove to/from tab 3
    if (v==-1) {  //already not favorite
        favInfo[lvlid]=-1;
    } else if (v==0) {
        rmvLvl(3,lvlid);
        favInfo[lvlid]=-1;
    } else if (v==1) {
        addLvlByDateDesc(3,lvlid);
        favInfo[lvlid]=1;
    } else if (v==2) {   //already favorite
        favInfo[lvlid]=1;
    }
    updateLevel(lvlid);
}
var burst = new Array(0,0);
var lclick = new Array(0,0);
function chLvlRk(lvlid,inc) {
    var lblrkObj=document.getElementById("lvlrk"+lvlid);
    if (lblrkObj) {
        var curLvlRk=parseInt(lblrkObj.innerHTML);
        var liinc=Math.round((inc+1)/2);
        var curt=(new Date()).getTime();
        if (curt<lclick[liinc]+1000) {
            burst[liinc]++;
        } else {
            burst[liinc]=0;
        }
        lclick[liinc]=curt;
        inc*=(1+5*Math.floor(burst[liinc]/10));
        curLvlRk+=inc;
        
        var tmpcp=currentNbItems[0];
        if (tmpcp>=0) {
            if (curLvlRk>=tmpcp) curLvlRk=tmpcp;
        }
        
        if (curLvlRk<=1) curLvlRk=1;
            
        //if (curLvlRk>=1) {
            lblrkObj.innerHTML=curLvlRk;
            var lvlrkaObj=document.getElementById("lvlrka"+lvlid);
            if (lvlrkaObj) lvlrkaObj.className='adminbut';
        //}
    }
}
function levelRank(lvlid) {
    var lblrkObj=document.getElementById("lvlrk"+lvlid);
    if (lblrkObj) {
        var curLvlRk=parseInt(lblrkObj.innerHTML);
        // TODO
        levelAdmin(lvlid,curLvlRk+2)
    }
}
function levelAdmin(lvlid,rk) {
    debug("levelAdmin("+lvlid+","+rk+")");
    if (!noClicks) {
        click();
        xajax_levelRank(lvlid,rk,levelsInfo[lvlid][4]);
    }
}
function setLevelRemoved(lvlid,ork) {
    rmvLvl(1,lvlid);
    rmvLvl(2,lvlid);
    rmvLvl(3,lvlid);
    rmvLvl(4,lvlid);
    rmvLvl(5,lvlid);
    levelsInfo[lvlid]=false;
    updateLevel(lvlid);
    dispError("Level removed!");
}
function updateLevelRk(lvlid,ork) {
    debug("updateLevelRk("+lvlid+","+ork+")");
    var newrk=levelsInfo[lvlid][4]
    debug(newrk);
    if (newrk!=ork) {
        if (ork>=2) {
            //remove from tab 0
            debug("ork>=2");
            pageLevels[0].splice(ork-3,1);
            for (var i in pageLevels[0]) {
                var id=pageLevels[0][i];
                if (levelsInfo[id]) {
                    if (levelsInfo[id][4]>ork) levelsInfo[id][4]--;
                }
            }
            currentNbItems[0]--;
        }
        if (newrk>=2) {
            //insert
            debug("newrk>=2");
            if (pageLevels[0].length>=newrk-2) pageLevels[0].splice(newrk-3,0,lvlid);
            else pageLevels[0][newrk-3]=lvlid;
            for (var i in pageLevels[0]) {
                var id=pageLevels[0][i];
                if (levelsInfo[id]) {
                    if ((levelsInfo[id][4]>=newrk)&&(id!=lvlid)) levelsInfo[id][4]++;
                }
            }
            currentNbItems[0]++;
        }
        if (ork==1) {
            if (newrk<1) {
                debug("ork==1 newrk<1");
                //remove from tab 1 & tab 2
                rmvLvl(1,lvlid);
                rmvLvl(2,lvlid);
                //refresh tab 5
                addLvlByDateDesc(5,lvlid);
                //currentNbItems[5]=-1;
            }
        }
        if (ork<=0) {
            if (newrk>0) {
                debug("ork<=0 newrk>0");
                //remove from tab 5
                rmvLvl(5,lvlid);
                //refresh tab 2
                addLvlByDateDesc(2,lvlid);
                //currentNbItems[2]=-1;
            }
        }
    }
    updateLevel(lvlid);
}
function updateLevel(lvlid) {
    dispCacheLevel(lastlvlinf);
    if (lasttabdisp>=0) display(lasttabdisp,true);
    else noClicks=false;
}
function pageCached(l,pg) {
    var start=pg*levelsPerPage;
    var end=start+levelsPerPage;
    var ret=new Array(pg,start,end,false,false);
    if (currentNbItems[l]<0) {
        ret[3]=new Array(new Array(start,(end-start)));
        ret[4]=true;
    } else {
        if (end>currentNbItems[l]) {
            end=currentNbItems[l];
            ret[2]=end;
        }
        if (end<=start) {
            end=start;
            ret[2]=end;
            ret[4]=true;
            if (pg>0) {
                ret[0]=pg-1;
            }
        } else {
            var ls=-1;
            var aret=new Array();
            for (var i=start;i<end;i++) {
                if ((pageLevels[l][i])&&(pageLevels[l][i]!=false)) {
                    if (ls>=0) {
                        aret.push(new Array(ls,i-ls));
                        ls=-1;
                    }
                } else {
                    if (ls<0) ls=i;
                }
            }
            if (ls>=0) {
                aret.push(new Array(ls,i-ls));
            }
            if (aret.length>0) ret[3]=aret;
        }
    }
    return ret;
}

var lasttabdisp=-1;
function display(l,bc) {
    debug("display("+l+","+bc+")");
    var level=pageLevels[l];
    var currentPage=currentPages[l];
    
    var cache=pageCached(l,currentPage);
    while (cache[0]<currentPage) {
        currentPage--;
        currentPages[l]=currentPage;
        cache=pageCached(l,currentPage);
    }
    
    if (cache[3]==false) {
        lasttabdisp=l;
        //cached data
        //debug("cached data "+currentPage);
        var nbPages=Math.ceil(currentNbItems[l]/levelsPerPage); if (nbPages<=0) nbPages=1;
        
        var pagestxt="";
        for (var j=0;j<nbPages;j++) {
            if (currentPage==j) pagestxt+="<b>"+(j+1)+"</b> ";
            else pagestxt+="<a class='bbck' href='#h' onClick='pageSel("+l+","+j+")'>&nbsp;"+(j+1)+"&nbsp;</a> ";
        }
        document.getElementById("pages0").innerHTML=pagestxt;
        //debug (cache[1]+" => "+cache[2]);
        for (var i=cache[1];i<cache[1]+levelsPerPage;i++) {
            debug("level["+i+"]");
            var levelObj=document.getElementById("lvl"+(i-cache[1]));
            if (i<cache[2]) {
                var img='';
                if (levelsInfo[level[i]][4]>=2) img=getGif('stargold',mtxt[1][10]);
                else if (levelsInfo[level[i]][4]==0) img=getGif('question','?');
                else if (levelsInfo[level[i]][4]==1) img=getGif('bulletgreen',mtxt[1][19]);
                else if (levelsInfo[level[i]][4]<0) img=getGif('bulletred',mtxt[1][20]);
                
                if ((favInfo[level[i]])&&(favInfo[level[i]]>0)) img=getGif('tinyheart',':-)')+img;
                //debug(levelsInfo[level[i]][3]+"=="+playerid);
                if (levelsInfo[level[i]][3]==playerid) img=getGif('tinypen','^_^')+img;
                
                var imgrate='';
                
                debug("offPlayed "+offPlayed[level[i]]);
                
                if ((offPlayed[level[i]])&&(offPlayed[level[i]]!==false)) imgrate+="("+offPlayed[level[i]]+") ";
                
                
                
                if (levelsInfo[level[i]][2]>=48) imgrate+=getGif('tinyheartblue','^_^');
                if (levelsInfo[level[i]][2]>=24) imgrate+=getGif('tinyheartblue','^_^');
                if (levelsInfo[level[i]][2]>=12) imgrate+=getGif('tinyheartblue','^_^');
                if (levelsInfo[level[i]][2]>=6) imgrate+=getGif('tinyheartblue','^_^');
                if (levelsInfo[level[i]][2]>=3) imgrate+=getGif('tinyheartblue','^_^');
                levelObj.innerHTML="<nobr> &nbsp; "+img+"<a href='#h' onclick='dispCacheLevel("+level[i]+")'>["+levelsInfo[level[i]][1]+"]</a>"+imgrate+"</nobr>";
            } else levelObj.innerHTML="-";
        }
        if (bc) {
            noClicks=false;
            cleanSess(0);
        }
    } else {
        debug("load data? "+bc);
        if (bc) {
            //load data
            debug("load data");
            //level[currentPage]=new Array(levelsPerPage);
            if (incSess(0)) xajax_loadLevelsAndDisplay(l,cache[3],cache[4],offPlayedLoaded);
            else {
                cleanSess(0);
                asynchError("Too many load levels requests!");
            }
        }
    }
}

//TOOLS
function getGif(nm,tit) {
    return "<img src='../images/"+nm+".gif' alt='"+tit+"' title='"+tit+"' border=0>";
}


function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}
