// Flock Facebook Connect

function alphaSort_Friends(a, b) {
  var nameA = (a.last_name).toLowerCase();
  var nameB = (b.last_name).toLowerCase();
  if (nameA < nameB) {
   return -1;
  } else if (nameA > nameB) {
   return 1;
  }
  return 0;
}

var gFacebookStrings = {
  invite: { msg: "Go get the Flock browser.  Over a million Facebook users have it.  Find out for yourself why it's so good."
               + "<fb:req-choice url='http://www.flock.com/' label='Take me to Flock.com' />" },

  tokens: { singular: "Flock Token Earned",
            plural: "Flock Tokens Earned"},

  referredUsers: { singular: "Referred User",
                   plural: "Referred Users"}
};

var gFacebookConnect = {
  API_KEY: "7fa235c847b11f157e12586c86660f47",
  NO_AVATAR_URL: "",
  FACEBOOK_PROFILE_URL: "",

  _loginButtonClicked: false,
  _autoConnect: 0,

  // Client API Object
  _api: null,

  // Flag for PHP $_SESSION vars
  _hasSessionInfo: false,

  // Logged in UserID
  _uid: null,
  _userInfo: {},
  _affiliation: null,
  _isFlockUser: false,

  _userInfofields: ["last_name", "first_name", "name", "pic_small_with_logo", "uid", "affiliations"],

  _apiCalled: false,
  _callbackCalled: false,
  _sendNotifications: false,
  _notificationUsers: null,
  _appFriends: [],
  _friends: [],
  _friendsUids: [],

  _friendsHash: {},

  init: function gFacebookConnect_init(aAutoConnect) {

    var inst = this;
    FB_RequireFeatures(["Api"], function() {
      FB.Bootstrap.init(inst.API_KEY, "xd_receiver.htm");
      FB.Bootstrap.ensureInit( function requireApi_ensureInit() {
        // We are not using fbml parsing, disbale it
        FB.XFBML.Host.autoParseDomTree = false;

        // Initialize the api object
        if (FB.Facebook && FB.Facebook.apiClient) {
          inst._api = FB.Facebook.apiClient;
        }

        // Initialize the logged in user's uid
        if (inst._api && inst._api.get_session()) {
          inst._uid = inst._api.get_session().uid;
        }

        FB.FBDebug.isEnabled = false;
        FB.FBDebug.logLevel = 0;

        function _genericCallback(aCallback) {
          if (inst._callbackCalled) {
            return;
          }
          if (aCallback) {
            aCallback();
            inst._callbackCalled = true;
          }
        }
        if (aAutoConnect === undefined) {
          aAutoConnect = 0;
        }
        inst._autoConnect = aAutoConnect;
        var connectCallback = (aAutoConnect == 1)
                            ? function autoConnectCallback() {
                                _genericCallback(inst.initData);
                              }
                            : function showloginTextCallback() {
                                _genericCallback(function () {
                                                   $("#loggedInStateText").fadeIn();
                                                 });
                              };
        var logoutCallback = function logoutCallback() {
                               _genericCallback(inst.logout);
                             };
        FB.Connect.ifUserConnected(connectCallback, logoutCallback);

        if (!FB.Facebook.get_sessionWaitable().result) {
          // Subscribe to session changed event
          FB.Facebook.get_sessionWaitable()
                     .add_changed(inst.checkSessionState);
        }
      });
    });
  },

  logout: function gFacebookConnect_logout() {
    var inst = gFacebookConnect;
    if (!inst._uid) {
      return;
    }
    // Logout from server and kill session data
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: "action=logout&uid=" + inst._uid,
       cache: false,
       error: function(){
         alert("Error");
       },
       success: function(aResponse){
         // Now logout of facebook and redirect to start
         FB.Connect.logoutAndRedirect(document.location.href);
         inst._uid = null;
         setTimeout(function () {
           $("#logoutMessage").fadeIn();
           setTimeout(function () {
             // Redirect if not already
             document.location.href = unescape(window.location.pathname);
             }, 1000);
         }, 2800);
       }
    });
  },

  connectButtonClick: function gFacebookConnect_connectButtonClick() {
    var inst = gFacebookConnect;
    inst._loginButtonClicked = true;
    FB.Connect.requireSession(gFacebookConnect.initData);
  },

  checkSessionState: function gFacebookConnect_checkSessionState() {
    var inst = gFacebookConnect;
    var sessionWaitable = FB.Facebook.get_sessionWaitable();
    if (sessionWaitable.get_isReady() && sessionWaitable.result) {
      if ((inst._loginButtonClicked == true && inst._autoConnect == 0) ||
          (!(inst._loginButtonClicked == true) && inst._autoConnect == 1))
      {
        gFacebookConnect.initData();
      } else {
        $("#loggedInStateText").fadeIn();
      }
     }
  },

  initData: function gFacebookConnect_initData() {
    var inst = gFacebookConnect;

    // Ensure the uid has been set if not already (this occurs when
    // the user has logged in via the dialog)
    if (!inst._uid && inst._api && inst._api.get_session()) {
      inst._uid = inst._api.get_session().uid;
    }

    if (inst._apiCalled) {
      return;
    }
    inst._apiCalled = true;

    // Get token data
    gFlockReferralData.getTokens();

    // Hide the introBox
    $("#introBox").hide();
    $("#authenticatedView").show();

    // Show the profile loader
    if (!inst._hasSessionInfo) {
      $("#profileLoader").show();
      $("#profileLoader").show();
    }

    // Show / Hide respective footers
    $("#footerLoggedOut").hide();
    $("#footerLoggedIn").show();

    // Create a sequencer for batch execution of user data
    var sequencer = new FB.BatchSequencer();
    var isAppUserResponse = inst._api.users_isAppUser(sequencer);
    var getInfoResponse = inst._api.users_getInfo([inst._uid],
                                                  inst._userInfofields,
                                                  sequencer);

    // Select all friend info and create a hash table for later use
    var fql = "SELECT uid,name,last_name,pic_small_with_logo "
            + "FROM user "
            + "WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = "+ inst._uid + ")";
    var fqlQueryResponse = inst._api.fql_query(fql, sequencer);

    var getAppUsersResponse = inst._api.friends_getAppUsers(sequencer);

    // Execute batch sequenced API calls
    sequencer.execute(function batch_Callback() {
      function _handleIsAppUser(aResponse) {
        if (aResponse && aResponse.toString() == "true") {
          inst._isFlockUser = true;
        } else {
          inst._isFlockUser = false;
        }
      }
      _handleIsAppUser(isAppUserResponse.result);

      function _handleGetInfo(aUserInfo) {
        if (aUserInfo[0]) {
          inst._userInfo = aUserInfo[0];

          inst.drawUserProfile(aUserInfo[0]);
          inst.removeLoader("profileLoader");

          // Show the user profile
          $("#userInfo").show();
          $("#newsFeed").show();

          // Send notifications to users notifying them that they have recieved an invite.
          if (inst._sendNotifications) {
            inst.sendNotificationToUsers();
          }
        }
      }
      _handleGetInfo(getInfoResponse.result);

      function _handleFqlQuery(aFriends) {
        if (aFriends && aFriends.length > 0) {
          inst._friends = aFriends;

          for (var i = 0; i < aFriends.length; i++) {
            inst._friendsUids.push(aFriends[i].uid);
            inst._friendsHash[aFriends[i].uid] = aFriends[i];
          }
        }
      }
      _handleFqlQuery(fqlQueryResponse.result);

      // Last call now that the friends hash has been initialized
      inst.getFlockFacebookFriends(getAppUsersResponse.result);
      gFlockReferralData.getNewsFeed("feed");
    });

    // Init the leaderboard
    gFlockReferralData.initLeaderboardPagination();
  },

  getUserForUid: function gFacebookConnect_getUserForUid(aUid) {
    var user = {};
    if (this._uid == aUid) {
      user = this._userInfo;
      user.name = "You";
    } else if (this._friendsHash[aUid]) {
      user = this._friendsHash[aUid];
    }
    return user;
  },

  getAvatar: function gFacebookConnect_getAvatar(aUser) {
    // Set a blank avatar if there is none supplied
    return (aUser.pic_small_with_logo && aUser.pic_small_with_logo.length > 0)
          ? aUser.pic_small_with_logo.replace(/&amp;/g, "&")
          : gFacebookConnect.NO_AVATAR_URL;
  },

  drawUserProfile: function gFacebookConnect_drawUserProfile(aUser) {
    var inst = gFacebookConnect;

    // Show the user information and friends loader
    document.getElementById("authenticatedView").removeAttribute("class");
    document.getElementById("userInfo").removeAttribute("class");

    // Populate the affiliation field
    for (var i in aUser.affiliations) {
      if (aUser.affiliations[i] && aUser.affiliations[i].name) {
        inst._affiliation = aUser.affiliations[i].name;
        break;
      }
    }

    document.getElementById("profilePic").src = inst.getAvatar(aUser);

    var profileName = document.getElementById("profileName");
    profileName.innerHTML = aUser.name;
    profileName.setAttribute("target", "_blank");
    profileName.setAttribute("href", inst.FACEBOOK_PROFILE_URL + inst._uid);
  },

  drawFriend: function gFacebookConnect_drawFriend(aFriend, aNum) {
    if (!aFriend) {
      return;
    }

    var friend = document.createElement("div");
    friend.setAttribute("class", "friendContainer");
    friend.setAttribute("className", "friendContainer");

    var avatar = document.createElement("img");
    avatar.src = this.getAvatar(aFriend);
    avatar.setAttribute("class", "avatar");
    avatar.setAttribute("className", "avatar");
    avatar.onclick = function avatar_onClick() {
      window.open(gFacebookConnect.FACEBOOK_PROFILE_URL + aFriend.uid, "_blank");
    };
    var friendName = document.createElement("a");
    friendName.setAttribute("target", "_blank");
    friendName.setAttribute("href",
                            this.FACEBOOK_PROFILE_URL + aFriend.uid);
    friendName.innerHTML = aFriend.name;
    
    for (var i in aFriend.affiliations) {
      if (aFriend.affiliations[i] && aFriend.affiliations[i].name) {
        friendName.innerHTML += "<i>" + aFriend.affiliations[i].name + "</i>";
        break;
      }
    }

    friend.appendChild(avatar);
    friend.appendChild(friendName);
    return friend;
  },

  removeLoader: function gFacebookConnect_removeLoader(aID) {
    // Remove the loader
    var loader = document.getElementById(aID);
    loader.parentNode.removeChild(loader);
  },

  showLoginButton: function gFacebookConnect_showLoginButton() {
    document.getElementById("introBox").removeAttribute("class");
  },

  sendNotificationToUsers: function gFacebookConnect_sendNotificationToUsers() {
    var inst = gFacebookConnect;
    if (inst._notificationUsers) {
      var notificationMsg = "says: Hey! Go get the <a href='http://www.flock.com'>Flock browser</a>. "
                          + "Over a million Facebook users have it. <a href='http://www.flock.com'>Try it and find out for yourself</a>"
                          + " why it's so good.";
      inst._api.notifications_send(inst._notificationUsers, notificationMsg,
        function api_notifications_send(aResponse) {
          //alert("sendNotificationToUsers:" + aResponse);
        });
    }
  },

  getFlockFacebookFriends: function gFacebookConnect_getFlockFacebookFriends(aAppUsers) {
    var inst = gFacebookConnect;
    var appUsersDiv = document.getElementById("appUsersDiv");
    if (aAppUsers && aAppUsers.length >= 0) {
      inst._appFriends = aAppUsers;

      var users = [];
      for (var appUser in aAppUsers) {
        if (aAppUsers.hasOwnProperty(appUser)) {
          users.push(inst._friendsHash[aAppUsers[appUser]]);
        }
      }

      // Alpha sort friends
      users.sort(alphaSort_Friends);
      for (var k = 0; k < users.length; k++) {
        appUsersDiv.appendChild(inst.drawFriend(users[k], k));
      }
    }

    var flock_friend_count = (aAppUsers && aAppUsers.length) ? aAppUsers.length : 0;

    // Update the friend count
    var percentage = Math.ceil((flock_friend_count / inst._friends.length) * 100);
    percentage = isNaN(percentage) ? 0 : percentage;
    $("#friendCount")[0].innerHTML = flock_friend_count;
    $("#friendPercentage")[0].innerHTML = "(" + percentage + "%)";
    inst.drawHeadlines(percentage, (inst._friends.length - flock_friend_count));

    // Only update once per session
    if (!inst._hasSessionInfo) {
  
      // Initialize post vars
      var postVars = "flock_friend_count=" + flock_friend_count
                   + "&total_friend_count=" + inst._friends.length
                   + "&friendsUid=" + inst._friendsUids.join(",");
      if (inst._userInfo) {
        if (inst._userInfo.name) {
          // Update first and last name
          postVars += "&first_name=" + inst._userInfo.first_name
                    + "&last_name=" + inst._userInfo.last_name;
        }
        if (inst._userInfo.pic_small_with_logo) {
          // Update avatar
          postVars += "&avatar_url=" + escape(inst._userInfo.pic_small_with_logo);
        }
        if (inst._affiliation) {
          // Update affiliation
          postVars += "&affiliation=" + inst._affiliation;
        }
      }

      var getVars = "?action=registerUID"
                  + "&uid=" + inst._uid;
      // Execute AJAX call
      $.ajax({
         url: "ajax_handler.php" + getVars,
         type: "POST",
         dataType: "json",
         data: postVars,
         cache: false,
         error: function(){
           //alert("Error");
         },
         success: function(aJSONData){
           // Successfully saved
           if (aJSONData && aJSONData.response == "registered") {
             gFlockReferralData.setTokens(aJSONData.tokens,
                                          aJSONData.referral_count);
             if (!isNaN(aJSONData.tokens) && aJSONData.tokens > 0) {
               // Show the free tokens message
               $("#freeTokens")[0].innerHTML = aJSONData.tokens;
               var freeTokenMessage = $("#freeTokensMessage");
               freeTokenMessage.show();
               setTimeout(
                 function freeTokenMessageFadeOut() {
                   freeTokenMessage.fadeOut();
                 }, 10000);
             }
           }
         }
      });
    }

    $("#appUsersLoader").hide();
    $("#friendsContent").show();
    document.getElementById("friendsContent").removeAttribute("class");
  },

  // Set the headline and sub-headline content
  drawHeadlines: function gFacebookConnect_drawHeadlines(aPercent, aRemaining) {
    var inst = gFacebookConnect;
    var subheadline;
    var headline;
    if (inst._isFlockUser) {
      // Flock user so show the refer friends button
      $("#referFriends")[0].removeAttribute("class");
      $("#referFriends").show();
      if (aPercent === 0) {
        headline = "Ok...you're clearly a trendsetter.";
        subheadline = "Turn your other <span id='friendsWithoutFlockPercentage'>" + aRemaining + "</span> friends on to Flock and earn tokens for <a onclick='gNavController.navClickHandler(1);'>great stuff</a>.";
      } else if (aPercent >= 1 && aPercent <= 15) {
        headline = "Alright! You've got some friends with good taste.";
        subheadline = "The other <span id='friendsWithoutFlockPercentage'>" + aRemaining + "</span> could use your help. Turn them on to Flock and earn tokens for <a onclick='gNavController.navClickHandler(1);'>great stuff</a>.";
      } else {
        headline = "Holy cow! Your friends seem to know a good thing when they see it!";
        subheadline = "Help your other <span id='friendsWithoutFlockPercentage'>" + aRemaining + "</span> friends discover Flock and earn tokens for <a class='actionable' onclick='gNavController.navClickHandler(1);'>great stuff</a>.";
      }
    } else {
      // Not a flock user so show the download button and tour link
      $("#downloadButton")[0].removeAttribute("class");
      $("#tourBox")[0].removeAttribute("class");
      $("#downloadButton").show();
      $("#tourBox").show();
      if (aPercent === 0) {
        headline = "You could be the first of your friends to discover Flock.";
        subheadline = "Get Flock and get ready to meet your new favorite browser!";
      } else if (aPercent >= 1 && aPercent <= 15) {
        headline = "Alright! Youve got some friends with good taste.";
        subheadline = "You should get Flock and rock Facebook like they do.";
      } else {
        headline = "Your friends know a good thing when they see it!";
        subheadline = "What's your excuse? Get Flock and rock Facebook like they do!";
      }
    }
    // Last check for 100%
    if (aPercent == 100) {
      // Hide the invite button as all their friends are Flock users
      $("#referFriends")[0].setAttribute("class", "hide");
      $("#referFriends")[0].setAttribute("className", "hide");
      headline = "We're not worthy!  We're not worthy!";
      subheadline = "100% of your friends are using Flock!  You are truly a Flockstar extraordinaire! "
                  + "<a href='mailto:hundredpercent@flock.com'>Shoot us a line</a> and maybe we can figure out a new way for you to spread the word.";
    }

    $("#headlineContent")[0].innerHTML = headline;
    $("#subHeadlineContent")[0].innerHTML = subheadline;
  },

  getActionUrl: function gFacebookConnect_getActionUrl() {
    var url = document.location.href;
    if (url.lastIndexOf("/") != -1) {
      url = url.substring(0, url.lastIndexOf("/") + 1);
    }
    return url;
  },

  addServerFbml: function gFacebookConnect_addServerFbml(aDiv) {
    FB_RequireFeatures(["XFBML"],
                       function gFacebookConnect_addServerFbml_RequireFeatures() {
                          var serverFbml = new FB.XFBML.ServerFbml(aDiv);
                          FB.XFBML.Host.addElement(serverFbml);
                        });
  },

  reInviteFriend: function gFacebookConnect_reInviteFriend(aUid) {
    var inst = gFacebookConnect;
    var user = "User";
    if (gFacebookConnect._friendsHash[aUid] &&
        gFacebookConnect._friendsHash[aUid].name)
    {
      user = gFacebookConnect._friendsHash[aUid].name;
    }

    FB.IFrameUtil.CanvasUtilServer.run(true);
    var divFrame = document.createElement("div");
    divFrame.setAttribute("iframeWidth","620px");
    divFrame.setAttribute("iframeHeight","370px");

    var popupDialog = new FB.UI.PopupDialog("Remind " + user + " to get Flock",
                                            divFrame, false, false);
    popupDialog.setContentWidth(620);
    popupDialog.setContentHeight(370);
    popupDialog.set_placement(FB.UI.PopupPlacement.center);
    divFrame.setAttribute("fbml","<fb:fbml>"
                              + "<fb:request-form action='" + this.getActionUrl() + "?action=inviteFriends' "
                                               + "method='POST' "
                                               + "invite='true' "
                                               + "type='Flock' "
                                               + "content=\"" + gFacebookStrings.invite.msg + "\">"
                                + "<fb:request-form-submit uid=" + aUid + "/>"
                              + "</fb:request-form>" +
                            "</fb:fbml>");
    popupDialog.show();
    this.addServerFbml(divFrame);
  },

  inviteFriendsForm: function gFacebookConnect_inviteFriendsForm() {
    var inst = gFacebookConnect;
    var excludedFriends = [];
  
    // We needs to add already invited 
    for (var i = 0; i < inst._appFriends.length; i++) {
      var user = inst._friendsHash[inst._appFriends[i]];
      excludedFriends.push(user.uid);
    }
  
    var iframeHeight = 570;
    FB.IFrameUtil.CanvasUtilServer.run(true);
    var divFrame = document.createElement("div");
    divFrame.setAttribute("iframeWidth","750px");
    divFrame.setAttribute("iframeHeight", iframeHeight + "px");

    var popupDialog = new FB.UI.PopupDialog("Invite Your Friends to Join Flock", divFrame, false, false);
    popupDialog.setContentWidth(750);
    popupDialog.setContentHeight(iframeHeight);
    popupDialog.set_placement(FB.UI.PopupPlacement.center);
    divFrame.setAttribute("fbml","<fb:fbml>"
                              + "<fb:request-form style='width:630px; height:" + iframeHeight + "px;' "
                                               + "action='" + this.getActionUrl() + "?action=inviteFriends' "
                                               + "method='POST' "
                                               + "invite='true' "
                                               + "type='Flock' "
                                               + "content=\"" + gFacebookStrings.invite.msg + "\">"
                                + "<fb:multi-friend-selector showborder='false' "
                                                          + "actiontext='Invite your friends to Flock' "
                                                          + "rows='4' "
                                                          + "bypass='cancel' "
                                                          + "showborder='false' "
                                                          + "exclude_ids='" + excludedFriends.join(",") + "' "
                                                          + "max='35' />"
                              + "</fb:request-form>" +
                            "</fb:fbml>");
    popupDialog.show();
    this.addServerFbml(divFrame);
  }
};

var gFlockReferralData = {

  LEADERBOARD_LIMIT: 0,

  _leaderboardType: "all",
  _paginationNeedsSetup: false,
  _paginationIsSettingUp: false,

  /* News Feed */
  getProfileUrlForUid: function gFlockReferralData_getProfileUrlForUid(aUid) {
    var user = gFacebookConnect.getUserForUid(aUid);
    if (user) {
      return "<a href='" + gFacebookConnect.FACEBOOK_PROFILE_URL +  aUid + "' target='_blank'>"
               + user.name
           + "</a>"
           + " ";
    }
  },

  getAvatarForUid: function gFlockReferralData_getAvatarForUid(aUid) {
    var user = gFacebookConnect.getUserForUid(aUid);
    return "<img class='avatar' src='" + gFacebookConnect.getAvatar(user) + "' "
                             + "onclick='javascript:openProfile(" + aUid + ");'/>";
  },

  createFeedHTML:
  function gFlockReferralData_createFeedHTML(aStory, aStoryText, aActorUID) {
    var image;
    if (aStory.type == "invite") {
      image = "<img class='inivite' src='images/invited.png' />";
    } else {
      image = gFlockReferralData.getAvatarForUid(aActorUID);
    }

    var storyDisplayTime = "<span class='feedTime'>"
                         + aStory.time_display
                         + "</span>";
    if (aStory.type == "notDownloaded") {
      // Not downloaded story, no need to show the time
      storyDisplayTime = "";
    }

    return "<div class='feedStory clearfix'>"
           + image
           + "<div class='feedUserInfo clearfix'>"
           + aStoryText
           + storyDisplayTime
           + "</div>"
         + "</div>\n";
  },
    
  createFeed: function (aStory, aType) {
    var actorUID;
    var storyText;
    switch (aStory.type) {
      case "registered":
        actorUID = aStory.uid;
        storyText = this.getProfileUrlForUid(aStory.uid)
                  + " Joined Top Flockstars.";
        break;

      case "join":
        actorUID = aStory.join_uid;
        storyText = this.getProfileUrlForUid(aStory.join_uid)
                  + " Has Downloaded Flock because of you.";
        break;

      case "invite":
        actorUID = aStory.uid;
        var friendNoun = (aStory.invite_count == 1) ? "friend" : "friends";
        storyText = this.getProfileUrlForUid(aStory.uid)
                  + " Invited " + aStory.invite_count
                  + " "
                  + friendNoun
                  + " to join Flock.";
        break;

      default:
        actorUID = aStory.uid2;
        var actionText;
        var reinviteButton;
        if (aType == "downloaded") {
          actionText = " Is a Flock User";
          reinviteButton = "";
        } else {
          // Not downloaded
          var subject = "Check out the Flock Browser";
          var msg = "This browser is built for Facebook and has some amazing features for keeping in touch."
                  + "\n http://www.flock.com";
          var facebookMessageURL = "http://www.facebook.com/message.php?id=" + aStory.uid2
                                 + "&subject=" + subject
                                 + "&msg=" + msg;
          actionText = " Still has not downloaded Flock";
          reinviteButton = " <a class='reinvite' style='display: inline;' "
                         + "href='" + facebookMessageURL + "' "
                         + "target='_blank'>Reinvite</a>";
        }
        storyText = this.getProfileUrlForUid(aStory.uid2)
                  + actionText
                  + reinviteButton;
        break;
    }
    return this.createFeedHTML(aStory, storyText, actorUID);
  },

  getDateString: function gfrd_getDateString(aDateString) {
    return "<div class='feedDate'>"
           + aDateString
         + "</div>";
  },

  getNewsFeed: function gFlockReferralData_getNewsFeed(aType) {
    var inst = gFlockReferralData;
    var dataUrl = "action=getNewsFeed&"
                + "uid=" + gFacebookConnect._uid + "&"
                + "type=" + aType;
    var newsFeedContent = $("#newsfeed-content");
    var newsFeedLoader = $("#newsFeedLoader");
    newsFeedLoader[0].removeAttribute("class");

    newsFeedContent.hide();
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: dataUrl,
       cache: false,
       error: function(){
         alert("Error");
       },
       success: function(aResponse) {
         if (aResponse && aResponse.feed) {
           var output = "";
           var dateString;
           var dateHash = {};
           var feed = aResponse.feed;
           if (feed[0] && feed[0].type && feed[0].type == "message") {
             output = feed[0].text;
           } else {
             for (var i = 0; i < feed.length; i++) {
               dateString = feed[i].date_created.substring(0, 10);
               if (!dateHash[dateString]) {
                 // Each day of new activity receives a datestamp
                 output += inst.getDateString(feed[i].date_header);
                 dateHash[dateString] = true;
               }
               output += inst.createFeed(feed[i], aType);
             }
           }
           newsFeedContent[0].innerHTML = output;
           newsFeedLoader[0].setAttribute("class", "hide");
           newsFeedLoader[0].setAttribute("className", "hide");
           newsFeedContent.show();
         }
       }
    });
  },

  /* Leaderboard */
  changeLeaderboardType: function gFlockReferralData_changeLeaderboardType(aType) {
    if (aType) {
      this._leaderboardType = aType;
      this.initLeaderboardPagination();
    }
  },

  initLeaderboardPagination:
  function gFlockReferralData_initLeaderboardPagination() {
    this._paginationNeedsSetup = true;
    this.leaderboardPaginationHandler(0, null);
  },

  setPrizeButtonStates: function gFacebookConnect_setPrizeButtonStates(aTokenBalance) {
    var prizeButtons = $("a[type='prize']");
    for (var i = 0; i < prizeButtons.length; i++) {
      var button = prizeButtons[i];
      var tokens = parseInt(button.getAttribute("tokens"));
      if (tokens > aTokenBalance) {
        button.setAttribute("disabled", "true");
        button.setAttribute("onclick", "return false;");
        button.innerHTML = "NOT ENOUGH TOKENS";
      } else {
        button.removeAttribute("disabled");
        button.onclick = function button_onClick() {
          jQuery.facebox({ ajax: "order.php?id=" + this.getAttribute("productId") });
        };
        button.innerHTML = "I want this!";
      }
    }
  },

  leaderboardPaginationHandler:
  function gFlockReferralData_handlePaginationClick(aIndex, aContainer) {
    var inst = gFlockReferralData;
    if (inst._paginationIsSettingUp) {
      return;
    }

    var leaderboardLoader = $("#leaderboardLoader");
    leaderboardLoader[0].removeAttribute("class");
    var offset = inst.LEADERBOARD_LIMIT * parseInt(aIndex);
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: "action=getLeaderboard&type=" + gFlockReferralData._leaderboardType
                                + "&offset=" + offset,
       cache: false,
       error: function handlePaginationClick_error() {
         //alert("Error");
       },
       success: function handlePaginationClick_success(aResponse) {
         if (aResponse && aResponse.content) {

           if (inst._paginationNeedsSetup) {
             inst._paginationIsSettingUp = true;
             // Setup pagination
             var options = { items_per_page: gFlockReferralData.LEADERBOARD_LIMIT,
                             num_display_entries: 5,
                             link_to: "#leaderboard",
                             callback: gFlockReferralData.leaderboardPaginationHandler };
             $("#leaderboard-pagination").pagination(aResponse.size, options);
             inst._paginationNeedsSetup = false;
             inst._paginationIsSettingUp = false;
           }

           // Load Content
           $("#leaderboard-content")[0].innerHTML = aResponse.content;
         }
         leaderboardLoader[0].setAttribute("class", "hide");
         leaderboardLoader[0].setAttribute("className", "hide");
       }
    });
  },

  getTokens: function gFlockReferralData_getTokens() {
    // Get points accrued by the user
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: "action=getTokens&uid=" + gFacebookConnect._uid,
       cache: false,
       error: function(){
         //alert("Error");
       },
       success: function(aJSONData){
         // Successfully saved
         if (aJSONData && aJSONData.tokens && aJSONData.referral_count) {
           gFlockReferralData.setTokens(aJSONData.tokens, aJSONData.referral_count);
           gFlockReferralData.setPrizeButtonStates(aJSONData.tokens);
         }
       }
    });
  },

  setTokens: function gFlockReferralData_setTokens(aTokens, aReferredUsers) {
     $("#flockStar")[0].setAttribute("class", "flockStar");
     $("#flockStar")[0].setAttribute("className", "flockStar");
     var tokenString = (aTokens == 1) ? gFacebookStrings.tokens.singular
                                     : gFacebookStrings.tokens.plural;
     var usersString = (aReferredUsers == 1) ? gFacebookStrings.referredUsers.singular
                                            : gFacebookStrings.referredUsers.plural;
     $("#tokenCount")[0].innerHTML = aTokens
                                   + " "
                                   + tokenString
                                   + " ("
                                   + aReferredUsers
                                   + " "
                                   + usersString
                                   + ")";
  }
};

var gNavController = {
  navClickHandler: function gNavController_clickHandler(aIndex) {
    function _resetTabs(aTabArray) {
      for (var i = 0; i < aTabArray.length; i++) {
        aTabArray[i].removeAttr("class");
      }
    }

    function _resetSections(aSectionsArray) {
      for (var i = 0; i < aSectionsArray.length; i++) {
        aSectionsArray[i].hide();
      }
    }

    var accountTab = $("#accountTab");
    var storeTab = $("#storeTab");
    var logoutTab = $("#logoutTab");
    var tabArray = [accountTab, storeTab, logoutTab];

    var accountSection = $("#accountSection");
    var storeSection = $("#storeSection");
    var faqSection = $("#faqSection");
    var legalSection = $("#legalSection");
    var sectionArray = [accountSection, storeSection,
                        faqSection, legalSection];

    _resetTabs(tabArray);
    _resetSections(sectionArray);
    switch (aIndex) {
      case 0:
        // Accounts section
        accountTab.attr("class", "selectedTab");
        accountSection.show();
        break;

      case 1:
        // Store section
        storeTab.attr("class", "selectedTab");
        storeSection.show();
        break;

      case 2:
        // Logout
        logoutTab.attr("class", "selectedTab");
        $("#appUsersLoader").show();
        $("#newsFeed").hide();
        $("#friendsContent").hide();
        accountSection.show();
        gFacebookConnect.logout();
        break;

      case 3:
        // Faq section
        faqSection.show();
        break;

      case 4:
        // Legal section
        legalSection.show();
        break;
    }
  },

  controlsClickHander: function gNavController_controlsClick(aControl, aType, aIndex) {
    function _resetControls(aControlsArray) {
      var children = aControlsArray.childNodes;
      for (var i = 0; i < children.length; i++) {
        if (children[i].nodeName && children[i].nodeName.toLowerCase() == "a") {
          $(children[i]).removeAttr("class");
        }
      }
    }

    _resetControls(aControl.parentNode);
    $(aControl).attr("class", "selected");

    if (aType == "newsfeed") {
      // Newsfeed
      switch (aIndex) {
        case 0:
          gFlockReferralData.getNewsFeed('feed');
          break;
  
        case 1:
          gFlockReferralData.getNewsFeed('downloaded');
          break;
  
        case 2:
          gFlockReferralData.getNewsFeed('notDownloaded');
          break;
      }
    } else {
      // Leaderboard
      switch (aIndex) {
        case 0:
          gFlockReferralData.changeLeaderboardType('all');
          break;
  
        case 1:
          gFlockReferralData.changeLeaderboardType('friends');
          break;
      }
    }
  }

};

var gOrder = {
  _steps: ["userInfoStep", "confirmStep", "successStep"],
  _addressFields: ["user_address", "user_city", "user_state", "user_country", "user_zip"],
  _uid: null,
  _itemId: null,
  _form: null,
  _validator: null,
  _isDigital: null,
  _currentStep: null,
  init: function gStore_init() {
    this._form = document.getElementById("userInfoForm");
    this._validator = $("#userInfoForm").validate();
    var emailConfirmationRule =
      { equalTo: "#user_email", messages: { equalTo: "Entered email addresses don't match."}};
    $("#user_email_verify").rules("add", emailConfirmationRule);
    this.showUserInfoStep();
    
    // Setup listener for the enter key press (cross browser)
    var nn = (document.layers) ? true : false;
    document.onkeydown = this.handleEnterKeyPress;
    if(nn) {
      document.captureEvents(Event.KEYDOWN);
    } 
  },
  handleEnterKeyPress: function gStore_handleEnterKeyPress(e) { 
    var evt = (e) ? e: (window.event) ? window.event : null; 
    if (evt) {
      var key = (evt.charCode) ? evt.charCode: ((evt.keyCode) ? evt.keyCode : ((evt.which) ? evt.which : 0));
      if(key=="13") {
        // We are controlling the enter key behaviour so stop the default
        // behaviour associated with pressing the enter key
        evt.preventDefault();
        switch (gOrder._currentStep) {
          case "userInfoStep":
            gOrder.userinfoCompletedClicked();
            break;
          case "confirmStep":
            gOrder.confirmClicked();
            break;
          case "successStep":
            $.facebox.close();
            break;
          default:
            // Nothing to do
        } 
      }
    }
  },
  hideAll: function gStore_hideAll() {
    for (var i = 0; i < this._steps.length; i++) {
      $("#" + this._steps[i]).hide();
    }
  },
  showStep: function gStore_showStep(aStepContainerId) {
    this.hideAll();
    // Store the current step
    this._currentStep = aStepContainerId;
    // Show the appropriate step
    $("#" + aStepContainerId).show();
    // Center the dialog on the page
    centerOnPage();
  },
  showUserInfoStep: function gStore_showUserInfoStep() {
    if (this._isDigital == 1) {
      $("#addressInfoContainer").hide();
    } else {
      // Enable validators for the address fields.
      for (var i = 0; i < this._addressFields.length; i++) {
        $("#" + this._addressFields[i]).rules("add", { required: true });
      }
    }
    this.showStep("userInfoStep");
  },
  showConfirmStep: function gStore_showConfirmStep() {
    $("#confirm_email").html($("#user_email").val());
    $("#confirm_name").html($("#full_name").val());
    if (this._isDigital) {
      $("#confirmAddressContainer").hide();
    } else {
      $("#confirmAddressContainer").show();
      // Copy over user entered values to our confirmation area.
      $("#confirm_address").html($("#user_address").val());
      $("#confirm_city").html($("#user_city").val());
      $("#confirm_state").html($("#user_state option:selected").text());
      $("#confirm_zip").html($("#user_zip").val());
      $("#confirm_country").html($("#user_country option:selected").text());
    }

    // Handle Flickr pro account selection
    if (this._itemId == 129) {
      $("#flickrUsernameContainer").show();
      $("#confirm_flickr_username").html($("#flickr_username").val());
    } else {
      $("#flickrUsernameContainer").hide();
    }
    this.showStep("confirmStep");
  },
  showSuccessStep: function gStore_showSuccessStep() {
    this.showStep("successStep");
  },
  purchaseClicked: function gStore_purchaseClicked() {
    this.showUserInfoStep();
  },
  confirmClicked: function gStore_confirmClicked() {
    $("#confirmStepLoader").show();
    var inst = this;

    var purchaseHandler = {
      error: function() {
        $("#confirmStepLoader").hide();
        $("#errorBox_confirmInfo").show();
        $("#errorBox_confirmInfo").html("We encountered a problem while trying to save your information. Please try saving it again.");
        displayWithDelayedFade("errorBox_confirmInfo");
       },
        success: function() {
          $("#confirmStepLoader").hide();
          inst.showSuccessStep();
        }
    };
    gStore.savePurchase(purchaseHandler);
  },
  userinfoCompletedClicked: function gStore_userinfoCompletedClicked() {
    if (!this._validator.form()) {
      return;
    }
    this.showConfirmStep();
  }
};

var gStore = {
  savePurchase: function gStore_savePurchase(aHandler) {
    var ajaxData = "action=savePurchase&";
    ajaxData += $("#userInfoForm").formSerialize();
    // Execute AJAX call
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: ajaxData,
       cache: false,
       error: function() {
         aHandler.error();
       },
       success: function(aJSONData){
         aHandler.success();
       }
    });
  },
  saveUserInfo: function gStore_saveUserInfo(aHandler) {
    var ajaxData = "action=saveUserInfo&";
    ajaxData += $("#userInfoForm").formSerialize();
    // Execute AJAX call
    $.ajax({
       url: "ajax_handler.php",
       type: "GET",
       dataType: "json",
       data: ajaxData,
       cache: false,
       error: function() {
         aHandler.error();
       },
       success: function(aJSONData) {
         aHandler.success();
       }
    });
  }
};

function displayWithDelayedFade(aElementId) {
  //debug("displayWithDelayedFade(" + aElementId + ")");
  $("#" + aElementId).show();
  setTimeout(function() {$("#" + aElementId).fadeOut(1000);}, 5000); 
}

function openProfile(aUID) {
  window.open(gFacebookConnect.FACEBOOK_PROFILE_URL + aUID, "_blank");
}

