Sources.facebook = function() {
    var id = 'facebook';
    var baseURL = "api://www.facebook.com/?";
    Sources.register(id);
    
    var app_key = "66066ba656d35d1cb0eae126397eaff6";
    var expires;
    var sessionKey;
    var user;
    var feedType;
    
    var onAlbumsLoaded = function(result) {
        $(".fb-album-thumb").remove();
        
        var albums = {};

        $.each(result[1].fql_result_set, function() {
            albums[this.aid] = {
                thumb: this.src
            };
        });

        $.each(result[0].fql_result_set, function() {
            if (albums[this.aid]) {
                albums[this.aid].name = this.name;
            }
        });

        $.each(albums, function(key) {
            var newElement = $("#fb-album-thumb-dummy")
                .clone()
                .attr('id', "facebook-" + key)
                .addClass("fb-album-thumb");
            
            newElement.find("img")
                .load(function() {
                    if ($(this).height() > $(this).width()) {
                        $(this).width("50px");
                        var offset = ($(this).height() - 50) / 2;
                        // Sanity check that IE fails ;)
                        if (offset > 0) { 
                            $(this).css("margin-top", "-" + offset + "px");
                        }
                    } 
                    else {
                        $(this).height("50px");
                        var offset = ($(this).width() - 50) / 2;
                        if (offset > 0) { 
                            $(this).css("margin-left", "-" + offset + "px");
                        }
                    }
                })
                .attr("src",  this.thumb);
            // var truncName = this.name.substr(0, 8) + "...";
            newElement.find(".thumb-title").text(truncate(this.name, 8));

            $("#facebook-albums").append(newElement);
            if (newElement.attr('id') == "facebook-" + $("#facebook-user-album").val()) {
                newElement.addClass("fb-album-thumb-selected");
            }
            newElement.show();
        });
    };

    var getAlbums = function() {
        cooliris.embed.facebook.callMethod("setConfig", "A," + sessionKey + "," + user);
        cooliris.embed.facebook.callMethod("getAlbumsByUser", user, onAlbumsLoaded);
    };
    
    var check_and_ask = function(permission, callback) {
      FB.Facebook.apiClient.users_hasAppPermission(permission, function(result) {
        if (result == 0) {
          FB.Connect.showPermissionDialog(permission, function(result) {
            callback(!!result);
          });
        } else {
          callback(true);
        }
      });
    };
    
    var initOpts = function() {
      expires = readCookie(app_key + "_expires");
      sessionKey = readCookie(app_key + "_session_key");
      user = readCookie(app_key + "_user");

      check_and_ask("user_photos", function(perm_granted){
        if (!perm_granted) {
          alert("You must allow Cooliris Express to access your photos to continue.");
          doLogout();
        } 
        else {
          check_and_ask("offline_access", function(perm_granted){ 
            if (!perm_granted) {
              alert("If you don't grant offline access, the wall will not be visible to anyone when you are not logged into Facebook");
            }
            expires = readCookie(app_key + "_expires");
            sessionKey = readCookie(app_key + "_session_key");
            user = readCookie(app_key + "_user");
            setupPage();
          });
        }
      });
    };
    
    var setupPage = function() {
        $("#facebook-logged-in").show();
        $("#facebook-login-button").hide();

        FB.XFBML.Host.parseDomTree();
        
        $("#facebook-opts").change(function(){
            feedType = $(this).val();
            if (feedType == 'album') {
                getAlbums();
            }
        });
        $("#facebook-opts").change();
    };
    
    var doLogout = function() {
        FB.Connect.logout(function(){
            $("#facebook-login-button").show();
            $("#facebook-logged-in").hide();
        });
    };
    
    return {
        id: id,
        displayName: 'Facebook',
        type: 'photos',
        encode: true,
        
        init: function() {
            $("#facebook-login-button").show();
            $("#facebook-logged-in").hide();
            
            $("#facebook-logout").click(function(event){
                event.preventDefault();
                doLogout();
            });
            
            $(".fb-album-thumb").live("click", function(event){
                $("#facebook-user-album").val($(this).attr('id').replace("facebook-", ""));
                $(this).siblings(".fb-album-thumb-selected").removeClass("fb-album-thumb-selected");
                $(this).addClass("fb-album-thumb-selected");
                Wall.doEmbed();
            });
            
            FB.init(
                app_key,
                "xd_receiver.htm", 
                {"ifUserConnected" : initOpts }
            );
        },
        
        setState: function(feed) {
            $("#item-tab-what-facebook").click();
            var params = explodeQueryString(decodeURIComponent(feed.replace(baseURL, "")));
            cooliris.embed.facebook.callMethod("setConfig", "A," + params["session"] + "," + params["user"]);
            if (params["album"]) {
                $("#facebook-opts").val("album");
                $("#facebook-user-album").val(params["album"]);
                setTimeout(function(){
                  $("#facebook-opts").change();
                }, 2000);
            }
        },
        
        getFeedURL: function() {
            if (!(sessionKey && user)) {
                return "";
            }
            var params = {
                session: sessionKey, 
                user: user,
                key: "A"
            };
            
            if (feedType == 'album') {
                params['album'] = $("#facebook-user-album").val();
            }
            else if (feedType == 'subject') {
                params['type'] = 'subject';
            }
            
            var feedURL = "api://www.facebook.com/" + implodeQueryParameters(params);
            return feedURL;
        },
        
        isFeedURL: function(feedURL) {
            return (feedURL.indexOf(baseURL) == 0);
            // return false;
        },
        
        initOpts: initOpts
    };
}();
