/**
 * HighScoresModule
 * This module creates the actual leaderboard. 
 * @param game object
 * @param mode of the module. 
 */
function HighScoresModule(game, mode)
{
    this._name = HighScoresModule.PREFIX + "_" + mode + "_" + game.id;

    this._game = game;

    this._mode = mode;

    this._uuid = null;

    this._profileUserId = null;

    this._isSelf = false;

    this._privacySetting = null;

    /** top-level DOM container for the module */
    this._cont = null;

    this._showProfileImg = false;
    this._profileImgSize = "small";
    this._highlightLoggedUser = false;

    /** number of scores to display */
    this._numScoresToShow = null;

    /** either friends or everyone */
    this._displayMode = null;

    this._hsDialogControl = null;

    /** variable for the timeout method */
    this._timeout = null;

    /** can be day, week, month, all (default: all)**/
    this._timeRange = HighScoresModule.TIME_RANGE_WEEK;

    this._startIndex = -1;

    this.initialize = function()
    {
        this._hsDialogControl = new DialogControl("#hsDialog");
        $("#hsDialogSave").bind("click",this,function(e){
            e.preventDefault();
            var module = e.data;
            module._privacySetting = $("#hsDialog input:checked").val();
            module._setHighScoreSettingReq(module._privacySetting);
            module._hsDialogControl.hideDialog();
        });
        $("#hsDialogCancel").bind("click",this,function(e){
            e.preventDefault();
            var module = e.data;
            module._hsDialogControl.hideDialog();
        });

        switch(this._mode) {
        case HighScoresModule.MODE_PROFILE_PAGE:
            this._cont = $(HighScoresModule.PARENT_ELEMENT).append(HighScoresModule.DIV_PROFILE_PAGE).children(".highScore:last");
            this._showProfileImg = true;
            this._profileImgSize="small";
            this._numScoresToShow = 3;
            this._numDefaultEntries = 2;
            this._displayMode = HighScoresModule.DISP_MODE_FRIENDS;
            this._initializeScroll();
        break;

        case HighScoresModule.MODE_VIEW_ALL_HS_PAGE:
            this._cont = $(HighScoresModule.PARENT_ELEMENT).append(HighScoresModule.DIV_VIEW_ALL_HS_PAGE).children(".highScore:last");
            this._cont.find(".privacyPref").attr("id", "game_"+this._game.id);
            this._numScoresToShow = 10;
            this._displayMode = HighScoresModule.DISP_MODE_FRIENDS;
            this._initializePrivacy();
        break;

        case HighScoresModule.MODE_FILTER_PAGE:
            this._cont = $(HighScoresModule.PARENT_ELEMENT).append(HighScoresModule.DIV_FILTER_PAGE).children(".highScore:last");
            this._showProfileImg = true;
            this._profileImgSize="mini";
            this._highlightLoggedUser = true;
            this._numScoresToShow = 5;
            this._startIndex = 0;
            this._displayMode = HighScoresModule.DISP_MODE_EVERYONE;
        break;

        case HighScoresModule.MODE_PLAY_WITH_FRIENDS_PAGE:
            this._cont = $(HighScoresModule.PARENT_ELEMENT).append(HighScoresModule.DIV_PLAY_WITH_FRIENDS_PAGE).children(".highScore:last");
            this._showProfileImg = true;
            this._profileImgSize="mini";
            this._highlightLoggedUser = true;
            this._numScoresToShow = 5;
            this._startIndex = 0;
            this._displayMode = HighScoresModule.DISP_MODE_EVERYONE;
        break;

        case HighScoresModule.MODE_GAME_PAGE_FRIENDS:
            this._cont = $("#friendScores").html(HighScoresModule.DIV_GAME_PAGE);
            this._showProfileImg = true;
            this._profileImgSize="mini";
            this._highlightLoggedUser = true;
            this._numDefaultEntries = 4;
            this._numScoresToShow = 8;
            this._startIndex = this._uuid ? -1 : 0;
            this._displayMode = HighScoresModule.DISP_MODE_FRIENDS;
            this._initializeViewSetting();
            this._initializeScroll();
        break;

        case HighScoresModule.MODE_GAME_PAGE_EVERYONE:
            this._cont = $("#everyoneScores").html(HighScoresModule.DIV_GAME_PAGE);
            this._showProfileImg = true;
            this._profileImgSize="mini";
            this._highlightLoggedUser = true;
            this._numScoresToShow = 8;
            this._startIndex = this._uuid ? -1 : 0;
            this._displayMode = HighScoresModule.DISP_MODE_EVERYONE;
            this._initializeViewSetting();
            this._initializeScroll();
        break;
        default:
            throw("HighScoresModule - unsupported mode [" + this._mode + "]");
        }

        var gameName = this._game.name;
        if (gameName.length > 18){
           gameName= gameName.substr(0,18) + "...";
        }
        this._cont.find(".gameModImg img").attr("src", "/fimages/" + this._game.id + "_sp.jpg");
        this._cont.find(".gameModImg a").attr("href", "/" + this._game.url);            
        this._cont.find(".gameMdTitle a").attr({href: "/" + this._game.url,title:this._game.name}).html(gameName);
        this._cont.find(".playCont a").attr("href", "/" + this._game.url).html("Play Now!");
        this._cont.find(".action a").attr("href", "/" + this._game.url);
        this._cont.find(".gameTag").html(this._game.miniDescription);
        if (this._game.maturity) this._cont.find(".gameMdTitle a").addClass("bomb");

        this.makeLeaderBoardReq();
    };

    this.setIsSelf = function(isSelf){
        this._isSelf = isSelf;
    };

    this.setUuid = function(id){
        this._uuid = id;
    };

    this.setProfileUserId = function(id){
        this._profileUserId = id;
    };
    this._initializeScroll = function() {
        var scrollDownFunc = bindContext(this, this._handleScrollDown);
        this._cont.find(".arrow_down").click(scrollDownFunc);

        var scrollUpFunc = bindContext(this, this._handleScrollUp);
        this._cont.find(".arrow_up").click(scrollUpFunc);
    };

    this._initializeViewSetting = function() {
        this._cont.find(".time_links a").bind("click",this,function(e){
            e.preventDefault();
              if ($(this).hasClass("on")){
                return;
            }
            var module = e.data;
            module._cont.find(".time_links a").removeClass("on");

            $(this).addClass("on");
            if ($(this).hasClass("timeRange_week")){
                module._timeRange = HighScoresModule.TIME_RANGE_WEEK;
            }else if ($(this).hasClass("timeRange_all")){
                module._timeRange = HighScoresModule.TIME_RANGE_ALL;
            }else if ($(this).hasClass("timeRange_month")){
                module._timeRange = HighScoresModule.TIME_RANGE_MONTH;
            }else if ($(this).hasClass("timeRange_day")){
                module._timeRange = HighScoresModule.TIME_RANGE_DAY;
            }
            module.makeLeaderBoardReq();
        });
    };

    this._initializePrivacy = function(){
        if (this._isSelf){
            this._cont.find(".action a").html("PLAY NOW");
            this._cont.find("#game_"+this._game.id).bind("click",this,function(e){
                var module = e.data;
                HighScoresModule.current_game_id = module._game.id;
                module._initDialog();
                module._hsDialogControl.showDialog();
            });

           this._makeHighScoreSettingReq();

        }else{
            this._cont.find(".privacy").html("&nbsp;");
        }

    };

    this._initDialog = function(){
            $("#hsDialog .dialoguePic img").attr("src", "/fimages/"+this._game.imageName);
            $(".hsDialogGameName").html(this._game.name);
            $("#hsDialog input").val([this._cont.find(".privacyRel").text()]);
    };
    /** make a call to the high scores server to get the privacy setting for the game */

    this._makeHighScoreSettingReq = function(){
        var request = [{
            "methodName": "highScoreService.getHighScoreSetting",
            "gameId": this._game.id,
            "userUuid" : this._uuid}];

        this._page.makeModuleAjaxCall(this,request);

    };
    this._setHighScoreSettingReq = function(val){
        if (HighScoresModule.current_game_id != this._game.id){return;}
        var request = null;
        if (val){
            request = [{
               "methodName": "highScoreService.setHighScoreSetting",
               "gameId" : this._game.id,
               "scoreSetting" : val,
               "userUuid" : this._uuid}];
        }
        $("#game_"+this._game.id).closest(".privacy").find(".privacyRel").html(this._privacySetting);
        this._page.makeModuleAjaxCall(this,request);

    };

    this._handleGetHighScoreSettingRes = function(res){
        this._privacySetting = res.scoreSetting;
        this._cont.find(".privacyRel").html(this._privacySetting);
    };


    /** make a call to high scores server to get list of rankings for the game */
    this.makeLeaderBoardReq = function()
    {
        this._cont.find(".scoreListWait").show();

        /*if the server doesn't respond in 15 seconds */
        clearTimeout(this._timeout); //clear the old one before you overwrite it
        this._timeout = setTimeout(this._handleTimeout,15000);

        this._cont.find(".scoreListSet").hide();
        var request = null;

        if (this._displayMode == HighScoresModule.DISP_MODE_EVERYONE) {
            request = [{
                "ajaxPath" : "/jscores/get",
                "methodName": "highScoreService.getLeaderboard",
                "gameId": "" + this._game.id,
                "mode" : "Everyone",
                "timeRange" : this._timeRange,
                "userUuid"  : this._uuid,
                "startIndex" : this._startIndex,
                "resultSize" : this._numScoresToShow}];

        } else if (this._displayMode == HighScoresModule.DISP_MODE_FRIENDS) {
            request = [{
                "ajaxPath" : "/jscores/get",
                "methodName": "highScoreService.getLeaderboard",
                "gameId": "" + this._game.id,
                "userUuid": this._uuid,
                "mode" : "Friends",
                "timeRange" : this._timeRange,
                "startIndex" : this._startIndex,
                "resultSize" : this._numScoresToShow}];
        }
        this._page.makeModuleAjaxCall(this, request);
    };

    /**
     * populate the leader board then make a call to get user informations
     */
    this._handleLeaderBoardRes = function(res)
    {
        // actual scores
        var scores = res.scores;
        // index of the highest rank visible

        this._startIndex = res.startIndex;
        this._uuids = [];

        //update the scroll states
        this._updateScroll(res.total);

        this._cont.find(".scoreListSet").empty();

        for (var j = 0; j < scores.length; j++) {
            var score = scores[j];
            this._uuids[j] = score.uuid;
            this._populateScore(score);
        }
        if (this._numDefaultEntries){
            this._insertDefaultEntries(res.total);
        }

        if (res.total) {
            this._makeGetProfileReq();
        } else {
            this._displayContent();
            return;
        }
    };

    this._populateScore = function(score) {
        var scoreStr = score.score;
        if (scoreStr.length > HighScoresModule.SCORE_CHAR_COUNT){
            scoreStr = scoreStr.substr(0,HighScoresModule.SCORE_CHAR_COUNT) +"...";
        }
        var scoreList = this._cont.find(".scoreListSet");
        var divId = "hsm_" + this._game.id + "_" + score.uuid;
        var rank="";
        if (score.rank){
            rank ="#" + score.rank;
        }
        var s = "<div class='score' id='"+ divId + "'>\
                    <div class='scoreRank'>" + rank +"</div>\
                    <div class='scoreProfileImg'><a><img/></a></div>\
                    <div class='scoreProfile'><a></a></div>\
                    <div class='scoreDesc'>"+ scoreStr+"</div>\
                    <br class='clearFloat'/>\
                </div>";

        scoreList.append(s);
   };

    this._insertDefaultEntries  = function(idx){
        var scoreList = this._cont.find(".scoreListSet");
        var s = "<div class='score'>\
                    <div class='scoreRank'></div>\
                    <div class='scoreProfileImg'><a class='gamePgInvite' href=''><img src='/static/images/userIcon_questionMark.jpg'/></a></div>\
                    <div class='scoreProfile'><a href='' class='gamePgInvite'>Invite a Friend</a></div>\
                    <div class='scoreDesc'></div>\
                    <br class='clearFloat'/>\
                </div>";
        for (i=idx; i <= this._numDefaultEntries; i++){
             scoreList.append(s);
        }
        if (this._mode == HighScoresModule.MODE_PROFILE_PAGE){
            if (this._isSelf){
              this._cont.find(".gamePgInvite").bind("click",bindContext(this,this._inviteRequest));
            }else{
              this._cont.find(".gamePgInvite").attr("href", "/" + this._game.url);
              this._cont.find(".scoreProfile .gamePgInvite").html("Play "+ this._game.name +"!");
            }
        }
        this._displayContent();
    };
    
    this._inviteRequest = function(e){
         e.preventDefault();
         var gameInviteModule = this._page.getModule("GameInviteModule");
         gameInviteModule.setUserId(this._profileUserId);
         gameInviteModule.setGameInfo(this._game.id, this._game.name);
         gameInviteModule.showInputDialog();
   };

    /** make call to the AG server to get list of profile details */
    this._makeGetProfileReq = function() {
        var reqs = [];

        for (var i = 0; i < this._uuids.length; i++) {
            var uuid = this._uuids[i];
            reqs[i] = { "methodName" : "profileService.getProfile", "userUuid" : uuid };
        }

        this._page.makeModuleAjaxCall(this, reqs);
    };

    /* handle response for profile details */
    this._handleGetProfileRes = function(res)
    {
        var loggedInUserUuid = this._page.getLoggedInUserUuid();
        var scoreDiv = this._cont.find("#hsm_" + this._game.id + "_" + res.profile.uuid);
        if (res.profile.profilePath){ //check if user is active
            scoreDiv.find("a").attr("href", "/profile/" + res.profile.profilePath);
        }

        if (this._highlightLoggedUser){
            if (res.profile.uuid == loggedInUserUuid){
             scoreDiv.addClass("on");
            }
        }else if (res.profile.uuid == this._uuid){
              scoreDiv.addClass("on");
        }
        if (this._showProfileImg) {
            var imgArg = {userUuid:res.profile.uuid,userPicSet: res.profile.userPicSet,size:this._profileImgSize};
            if (loggedInUserUuid == res.profile.uuid) imgArg.self = true;
            scoreDiv.find("img").attr("src", ProfileUtil.getImg(imgArg));

         }

        var profileName = res.profile.userName;
         if (profileName.length > 10){
           profileName = profileName.substr(0,10) + "...";
        }
        scoreDiv.find(".scoreProfile").find("a").html(profileName);

        this._displayContent();
    };

    this._displayContent = function() {
        clearTimeout(this._timeout);
        this._cont.find(".scoreListWait").hide();
        this._cont.find(".scoreListSet").show();
    };
    this._handleTimeout = function(){
       $(".scoreListWait").hide();
       $(".scoreListSet")
                .html("Leaderboards are not available at this time. You can play games but not save your scores.")
                .show();

    };
    this._handleScrollUp = function() {
        if (this._cont.find(".arrow_up").hasClass("disabled")){
            return;
        }
        this._startIndex = Math.max(0, this._startIndex - this._numScoresToShow);
        this.makeLeaderBoardReq();
    };

    this._handleScrollDown = function() {
        if (this._cont.find(".arrow_down").hasClass("disabled")){
            return;
        }
        this._startIndex = this._startIndex + this._numScoresToShow;
        this.makeLeaderBoardReq();
    };

    this._updateScroll = function(total){
        if (this._startIndex ==0){
          this._cont.find(".arrow_up").addClass("disabled").css("cursor","default");
        }else{
          this._cont.find(".arrow_up").removeClass("disabled").css("cursor","pointer");
        }
        if (total - this._startIndex > this._numScoresToShow){
            this._cont.find(".arrow_down").removeClass("disabled").css("cursor","pointer");
        }else{
          this._cont.find(".arrow_down").addClass("disabled").css("cursor","default");
        }
    };
    /** handle AJAX response object */
    this.handleResObjects = function(resObjects) {
        for (var i = 0; i < resObjects.length; i++) {
            var res = resObjects[i];
            if (res.methodName == "highScoreService.getLeaderboard") this._handleLeaderBoardRes(res.response);
            else if (res.methodName == "profileService.getProfile") this._handleGetProfileRes(res.response);
            else if(res.methodName == "highScoreService.getHighScoreSetting") this._handleGetHighScoreSettingRes(res.response);
        }
    };
}

HighScoresModule.PREFIX = "HighScoresModule";

HighScoresModule.prototype = new Module();

/** id of the parent to append to */
HighScoresModule.PARENT_ELEMENT = "#highScoresModList";

/** show only friends scores */
HighScoresModule.DISP_MODE_FRIENDS = "DISP_MODE_FRIENDS";

/** show everyone's scores */
HighScoresModule.DISP_MODE_EVERYONE= "DISP_MODE_EVERYONE";

/** display friends high scores on the profile page
 * uuid of the viewed profile is set. center around the user
 */
HighScoresModule.MODE_PROFILE_PAGE = "MODE_PROFILE_PAGE";

/** display everyone's high score on high score game filter page
 * no centering - start index is 0
 */
HighScoresModule.MODE_FILTER_PAGE = "MODE_FILTER_PAGE";

/** display frinds high scores on 'play with friends' page
 * no centering - start index is 0
 * */
HighScoresModule.MODE_PLAY_WITH_FRIENDS_PAGE = "MODE_PLAY_WITH_FRIENDS_PAGE";

/** display friends high scores on a user's view all high score page
 * uuid is viewed profile is always set. center around the profile
 * */
HighScoresModule.MODE_VIEW_ALL_HS_PAGE = "MODE_VIEW_ALL_HS_PAGE";

/** display everyone/friends high scores on game page
 * uuid of the logged in user may or may not be set. center if uuid is set.
 * otherwise, start index is 0
 * */
HighScoresModule.MODE_GAME_PAGE_FRIENDS = "MODE_GAME_PAGE_FRIENDS";
HighScoresModule.MODE_GAME_PAGE_EVERYONE = "MODE_GAME_PAGE_EVERYONE";
/** sets the game id for the privacy setting */
HighScoresModule.current_game_id = null;

/** for setting the time range in leaderboard results **/
HighScoresModule.TIME_RANGE_ALL = "AllTime";
HighScoresModule.TIME_RANGE_WEEK = "Week";
HighScoresModule.TIME_RANGE_MONTH = "Month";
HighScoresModule.TIME_RANGE_DAY = "Day";

/** for setting the truncation character limit of a score**/
HighScoresModule.SCORE_CHAR_COUNT = 12;

/** div definition for profile page */
HighScoresModule.DIV_PROFILE_PAGE =
"<div class='highScore'>\
    <div class='gameMd'>\
     <div class='gameModImg'>\
        <a><img height='111' width='158'/></a>\
     </div>\
     <div class='gameMdTitle'><a/></div>\
    </div>\
    <div class='scoreListSet displayNone'></div>\
    <div class='scoreListWait'></div>\
    <div class='scroll'></div>\
    <a class='arrow_up'>\
        <span class='hidden'>Prev</span>\
    </a>\
    <a class='arrow_down'>\
        <span class='hidden'>Next</span>\
    </a>\
    <div class='playCont'>\
        <a></a>\
    </div>\
</div>";

/** div definition for view all page */
HighScoresModule.DIV_VIEW_ALL_HS_PAGE =
   "<div class='highScore'>\
       <div class='gameMd float'>\
          <div class='gameModImg'>\
            <a><img  height='111' width='158'/></a>\
          </div>\
          <h3 class='gameMdTitle'><a/></h3>\
          <p class='gameTag'></p>\
       </div>\
    <div class='scoreList float '>\
        <div class='scoreListWait'>\
            <img src='/static/images/preloader_40x40.gif' alt='Please Wait'/>\
        </div>\
        <div class='scoreListSet displayNone'></div>\
        <div class='gameSetFooter'>\
            <div class='privacy float'>Privacy: <span class='privacyRel'></span> (<a class='privacyPref'>edit</a>)</div>\
            <div class='action float'><a class='button_standard' href=''>PLAY AGAINST</a></div>\
            <br class='clearFloat'/>\
        </div>\
    </div>\
   <br class='clearFloat'/>\
  </div>";

HighScoresModule.DIV_PLAY_WITH_FRIENDS_PAGE =
HighScoresModule.DIV_FILTER_PAGE =
"<div class='whiteMod_thin float highScore'>\
    <div class='mod_top'></div>\
    <div class='mod_main'>\
        <div class='gameModImg'>\
            <a><img height='111' width='158'/></a>\
        </div>\
        <h3 class='gameMdTitle'>\
             <a> </a>\
        </h3>\
        <p class='gameTag'></p>\
        <h4>Top Players</h4>\
        <div class='scoreList'>\
            <div class='scoreListSet displayNone'></div>\
            <div class='scoreListWait'></div>\
            <div class='playCont'>\
               <a class='button_standard'>PLAY NOW!</a>\
            </div>\
        </div>\
    </div>\
    <div class='mod_bottom'></div>\
</div>";

HighScoresModule.DIV_GAME_PAGE =
      "<div class='time_links'><a href='' class='timeRange_week on'>This Week</a>&nbsp;|&nbsp;<a href='' class='timeRange_all'>All Time</a></div>\
      <div class='leader_scores scoreListSet displayNone'></div>\
       <div class='scoreListWait'>\
            <img src='/static/images/preloader_70x70.gif'/>\
       </div>\
      <div class='paging_arrows'><a class='arrow_up disabled'>&nbsp;</a> <a class='arrow_down'><span class='displayNone'>Next</span></a></div>";
