/**
 * NotificationModule
 * @author Jae Cho
 * Subclass of Module that displays list of notifications. there are
 * several types for notifications. Notifications support two views.
 * small view only shows 3 notifications. When a user clicks on 'more'
 * button, full view is displayed with 10 notifictions
 *
 * @dependencies
 * Pagination
 *
 * @param type notification type
 *
 */
function NotificationsModule(type) {

    /** name of the module */
    this._name=NotificationsModule.NAME_PREF + type;

    /** module container */
    this._cont = $("#notifMod_" + type);
    this._modView = this._cont.find(".notifModView");
    this._defViewList = this._cont.find(".notifModDefList");
    this._fullViewList = this._cont.find(".notifModFullList");
    this._moreLinkCont = this._cont.find(".moreLink");
    this._viewLinkToggle = this._cont.find(".notifModViewLinkToggle");
    this._paginationTitle = this._cont.find(".notifModPgTitle");
    this._paginationCtrl= this._cont.find(".notifModPgCtrl");
    this._paginationCont= this._cont.find(".pagination");

    this._type = type;


    this._view = NotificationsModule._VIEW_DEFAULT;

    this._currentIndex = 0;

    /** pagination control */
    this._pagination = null;

    /** user id for the profile */
    this._userId = null;

    /** */
    this.initialize = function() {
        this._userId = this._page.getLoggedInUserId();
        this._viewLinkToggle.bind("click", this, function(event){
            var module = event.data;
            module._viewToggle();
        });
        this._pagination = new PaginationHelper(
                ".pgHelperTitle_" + this._type,
                ".pgHelperCtrlTop_" + this._type,
                ".pgHelperCtrlBottom_" + this._type,
                this, NotificationsModule.RESULT_SIZE_DEFAULT);
       
    };

    /** Handle page change in the full view
     * @param pageNumber number to display
     */
    this.handlePageChange = function(pageNumber)
    {
        // paginate only in full view
        if (this._view != NotificationsModule._VIEW_FULL) return;

        this._currentIndex = pageNumber *  NotificationsModule.RESULT_SIZE_FULL;
        var req = [ this._getRequest() ];
        this._page.makeModuleAjaxCall(this, req);
    };

    /**
     * create ajax request for the current setting
     * @return AJAX request
     */
    this._getRequest = function()
    {
        var uuid = this._page.getLoggedInUserUuid();
        //Always use the full result size
        var resultSize =  NotificationsModule.RESULT_SIZE_FULL;
        var jsonApiType = null;
        if (this._type == NotificationsModule.TYPE_FRIEND_REQUEST) jsonApiType = "FriendRequest";
        else if (this._type == NotificationsModule.TYPE_HIGH_SCORE) jsonApiType = "ScoreBeat";
        else if (this._type == NotificationsModule.TYPE_COMMENT) jsonApiType = "NewComment";
        else if (this._type == NotificationsModule.TYPE_HIGH_SCORE_INVITE) jsonApiType = "HighScoreInvite";
        
        return   { "methodName" : "profileService.getNotifications",
            "notificationType" : jsonApiType,
            "userUuid" : uuid,
            "startIndex" : this._currentIndex, "resultSize" : resultSize };
    };

    /** list of initial AJAX request that needs to be made when a module loads */
    this.getInitRequests = function()
    {
        this._currentIndex = 0;
        var req = this._getRequest();
        this._bindNotifEvent(this._modView,this._type);
        return [ req ];
  
    };

    /** make a request for current view of notifications */
    this._makeReq = function()
    {
        var req = [ this._getRequest() ];
        this._page.makeModuleAjaxCall(this, req);
    };


    this._viewToggle = function()
    {
        //toggle the sliding animation of the views
        this._fullViewList.slideToggle();
        if( this._view == NotificationsModule._VIEW_FULL){
            //default view settings
            this._view = NotificationsModule._VIEW_DEFAULT;
            this._viewLinkToggle.text("more >>");
            this._paginationCont.slideUp() ;
            this._pagination.setPageSize(NotificationsModule.RESULT_SIZE_DEFAULT);
        }
        else{
            //full view settings
            this._view = NotificationsModule._VIEW_FULL;
            this._viewLinkToggle.text("<< less");
            this._paginationCont.slideDown();
            this._pagination.setPageSize(NotificationsModule.RESULT_SIZE_FULL);
            this._pagination.updateControl(this._currentIndex, NotificationsModule._typeTotalArr[this._type]);
        }
        //update the pagination in the title
        this._pagination.updateTitle(this._currentIndex, NotificationsModule._typeTotalArr[this._type]);

    };

    /** handle notificaiton response */
    this.handleNotificationRes = function(response)
    {
        var notifications = response.notifications;

        this._defViewList.empty();
        this._fullViewList.empty();        

        // total number of notifications
        var total = response.total;

        //Collect the total for the type
        NotificationsModule._typeTotalArr[this._type] = total;
        NotificationsModule._updateTotal();

        if (total == 0){
            this._cont.find(".h3parens").empty();
            this._appendNotif(this._defViewList,null,this._type);
            return;
        }

        if (total > NotificationsModule.RESULT_SIZE_DEFAULT) {
           this._moreLinkCont.show();
        }else{
           this._moreLinkCont.hide();
           this._fullViewList.hide();
           this._paginationCont.hide();
        }

        if (this._view == NotificationsModule._VIEW_DEFAULT) {
            this._pagination.setPageSize(NotificationsModule.RESULT_SIZE_DEFAULT);
            this._pagination.updateTitle(this._currentIndex, total);
            this._pagination.updateControl(this._currentIndex, total);
        } else {
            this._pagination.setPageSize(NotificationsModule.RESULT_SIZE_FULL);
            this._pagination.updateTitle(this._currentIndex, total);
            this._pagination.updateControl(this._currentIndex, total);
       }
       if (notifications.length < 1 && this._currentIndex > 0){
           this._currentIndex -= NotificationsModule.RESULT_SIZE_FULL;
           this._makeReq();
       }
        for (var i = 0; i < notifications.length; i++) {
            var notif = notifications[i];
            var notifContentStr =
                    "<div class='notificationsModItem'>" + notif.text + "</div>";
            if (i < NotificationsModule.RESULT_SIZE_DEFAULT){
                //Populate default view div
                this._appendNotif(this._defViewList,notif,this._type);
            }else{
                //Populate the full view div with the remainder
                this._appendNotif(this._fullViewList,notif,this._type);
            }
        }
        this._cont.find(".notice:last").addClass("last");
        

    },

    /** append notification item */
    this._appendNotif = function(list, notif, type) {
      var acceptText = 'Accept';
      var ignoreText = 'Ignore';
      var emptyText = "";
      var notifContent="";
      var acceptHref = "";
      var profilePath = "";       
        
      switch(type){
         case NotificationsModule.TYPE_COMMENT:
            acceptText = 'Reply';
            emptyText = 'You have no new Comments.';
            break;
         case NotificationsModule.TYPE_FRIEND_REQUEST:
            emptyText = 'You have no pending Friend Requests.';
            break;
         case NotificationsModule.TYPE_HIGH_SCORE:
            if (notif){
                 acceptText = 'Play Now';
                 acceptHref = "/"+notif.game.url;
            }
            emptyText = 'You have no High Score Alerts.';
            break;
         case NotificationsModule.TYPE_HIGH_SCORE_INVITE:
              if (notif){
                acceptText = 'Play Now';
                acceptHref = "/"+notif.game.url;
              }
            emptyText = 'You have no High Score Challenges.';
            break;
      }

        if (notif){
            if (notif.profilePath){
                 profilePath = "href='/profile/" + notif.profilePath + "'";
             }
            notifContent = "<div class='notice'>" +
                              "<div class='friendPic float'>"+
                                  "<a "+ profilePath +"><img src='" + ProfileUtil.getImg({userId:notif.userId,userPicSet:notif.userPicSet,size:"mini"}) + "' /></a>" +
                               "</div>" +
                                "<div class='noticeInfo float'>"+
                                    "<div class='noticeEvent'><a "+profilePath+">" + notif.userName + "</a><span class='notifText'>"+this._getNotifTypeText(notif,type)+"</span></div>"+
                                    "<div class='noticeAction'>"
        if (notif.profilePath){ if (this._type ==NotificationsModule.TYPE_COMMENT){
                                notifContent +="<a class='view' notifId='"+notif.id+"' commentId='"+notif.commentId+"'>View</a>&nbsp;&nbsp;|&nbsp;&nbsp;";
                                }
                                notifContent += "<a class='accept' gamePath='"+ acceptHref +"' userId='" + notif.userId + "' notifId='"+ notif.id +"'>"+ acceptText +"</a>&nbsp;&nbsp;|&nbsp;&nbsp;";}
                                notifContent += "<a class='ignore' notifId='"+notif.id+"'>"+ ignoreText +"</a></div>" +
                                "</div>" +
                                "<br class='clearFloat' />" +
                            "</div>";
        }
        else{
            notifContent = "<div class='notice empty'>"+
                                "<div class='noticeInfo float'>"+
                                   "<div class='noticeEvent'><span class='notifText notifEmpty'>" + emptyText + "</span></div>"+
                                "</div>"+
                                "<br class='clearFloat' />" +
                            "</div>";
        }
        list.append(notifContent);

    },

    this._bindNotifEvent = function(cont,type){
           cont.bind("click",  this,function(event){
             var target = $(event.target);
               var module = event.data;
               if (target.hasClass("accept")){
               switch(type){
                    case NotificationsModule.TYPE_FRIEND_REQUEST:
                        module._acceptFriendReq(target.attr("notifId"), parseInt(target.attr("userId")));
                        break;
                    case NotificationsModule.TYPE_COMMENT:
                        module._removeNotification(parseInt(target.attr("notifId")));
                        window.location ="/profile/commentsPage.php?userId=" + target.attr("userId");
                        break;
                    case NotificationsModule.TYPE_HIGH_SCORE:
                        module._removeNotification(parseInt(target.attr("notifId")));
                        window.location = target.attr("gamePath");
                        break;
                    case NotificationsModule.TYPE_HIGH_SCORE_INVITE:                          
                        module._removeNotification(parseInt(target.attr("notifId")));
                        window.location = target.attr("gamePath");
                        break;
                    default:
                        return;
                }
             }
             else  if (target.hasClass("ignore")){
                 module._removeNotification(parseInt(target.attr("notifId")));
             }else if(target.hasClass("view")){
                  module._removeNotification(parseInt(target.attr("notifId")));
                  window.location ="/profile/commentsPage.php?userId=" + module._userId +"#comment_"+target.attr("commentId");
             }
         });
    },

    this._getNotifTypeText = function(notif,type){
        switch(type){
          case NotificationsModule.TYPE_FRIEND_REQUEST:
            return " sent you a friend request. <span class='time'>("+DateUtil.formatAge(notif.age) +")</span>";
          case NotificationsModule.TYPE_COMMENT:
            return " left a comment on your profile. <span class='time'>("+DateUtil.formatAge(notif.age) +")</span>";
          case NotificationsModule.TYPE_HIGH_SCORE:
           return " beat your high score "+
                    " in <a href='/" + notif.game.url + "'>" + notif.game.name + "</a>.";                        
          case NotificationsModule.TYPE_HIGH_SCORE_INVITE:
           return " wants to compete for high scores in " +
                    "<a href='/" + notif.game.url + "'>" + notif.game.name + "</a>!<br/><br/>" +
                    "Think you can beat " +
                    "<a href='" + notif.profilePath + "'>" + notif.userName + "</a>" +
                    "'s high score? Play now!";
          default:
            return "";
         }
    },

    /** accept friend request
     * @param notifId
     * @param userId user ID of the requestor
     * */
    this._acceptFriendReq = function(notifId, userId)
    {
        var req = [
            { "methodName" : "profileService.acceptFriendRequest", "userId": userId },
            this._getRequest()
            ];

        this._page.makeModuleAjaxCall(this, req);
    },

    /** ignore a notification */
    this._removeNotification = function(notifId)
    {
        var req = [ 
            { "methodName" : "profileService.removeNotification", "notificationId": notifId },
            this._getRequest()
        ];

        this._page.makeModuleAjaxCall(this, req);
    },


    /** handle AJAX response object */
    this.handleResObjects = function(resObjects) {
        for (var i = 0; i < resObjects.length; i++) {
            var res = resObjects[i];
            if (res.methodName == "profileService.getNotifications") {
                this.handleNotificationRes(res.response);
            }
        }
    };
}

NotificationsModule.prototype = new Module();

/** prefix for the module names since multiple notifications modules can be in a page */
NotificationsModule.NAME_PREF = "NotificationsModule_";

NotificationsModule.RESULT_SIZE_DEFAULT = 3;

NotificationsModule.RESULT_SIZE_FULL = 10;

/** friends request */
NotificationsModule.TYPE_FRIEND_REQUEST = "friendReq";

/** high score beat */
NotificationsModule.TYPE_HIGH_SCORE = "highScore";

/** high score game invitation */
NotificationsModule.TYPE_HIGH_SCORE_INVITE = "highScoreInvite";

/** comment */
NotificationsModule.TYPE_COMMENT = "comment";

/** default view */
NotificationsModule._VIEW_DEFAULT = "default";

/** full view */
NotificationsModule._VIEW_FULL = "full";

/** Associative array with notification totals. this._type is the key. */
    NotificationsModule._typeTotalArr = [];

NotificationsModule._updateTotal = function() {
    var total = 0;
    var inc = NotificationsModule._typeTotalArr[NotificationsModule.TYPE_FRIEND_REQUEST];
    if (inc) total += inc;
    inc = NotificationsModule._typeTotalArr[NotificationsModule.TYPE_HIGH_SCORE];
    if (inc) total += inc;
    inc = NotificationsModule._typeTotalArr[NotificationsModule.TYPE_HIGH_SCORE_INVITE];
    if (inc) total += inc;
    inc = NotificationsModule._typeTotalArr[NotificationsModule.TYPE_COMMENT];
    if (inc) total += inc;

    $("#notificationsPgCount").html("(" + total + ")");
    $("#uimNumNotifs").html("(" + total + ")");
};