document.write('<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US" type="text/javascript"></script>');

// get a batch of Facebook photo information, given vcards for Facebook users
function get_facebook_photos_batch(vcards) {
    if (!vcards || !vcards.length) return;
    var futures = [];
    var sequencer = new FB.BatchSequencer();
    for (var ii = 0; ii < vcards.length; ii++) {
        var vcard = vcards[ii];
        var id = vcard.account_id;

        var subquery = '(SELECT pid FROM photo_tag WHERE subject='+id+')';
        var query = ('SELECT src, link, caption FROM photo '+
                     'WHERE pid IN '+subquery+' '+
                     'order by created desc limit '+
                     knx_max_photos_per_person);

        futures.push(FB.Facebook.apiClient.fql_query(query, sequencer));
    }
    debugLog('querying for photos for '+vcards.length+' vcards');

    sequencer.execute(function() {
        debugLog('got photo query results');
        for (var ii=0; ii < futures.length; ii++) {
            var photostream = photostream_div_for(vcards[ii]);

            // This next `if` line is to catch the case where we fired
            // off two separate fetches of photos for the same vcard,
            // which is wasteful and hopefully won't happen, but
            // could.
            if (photostream) {
                debugLog("hmm, already a photostream for "+
                         vcard_unique_id(vcards[ii]));
                continue;
            }

            for (var jj = 0; jj < futures[ii].result.length; jj++) {
                var query_result = futures[ii].result[jj];
                add_to_photostream(vcards[ii], {
                    href: query_result.link.replace(/&amp;/g, "&"),
                    src: query_result.src,
                    title: query_result.caption
                });
            }
        }
    });
    debugLog('hoping for query result someday');
}

// get photos for up to 20 Facebook users
function get_facebook_photos(vcards) {
    var facebook_vcards = [];
    for (var ii = 0; ii < vcards.length; ii++) {
        var vcard = vcards[ii];

        if (vcard.socnet !== 'facebook') continue;
        // Don't refetch photos if already present.
        if (photostream_div_for(vcards[ii])) continue;

        facebook_vcards.push(vcard);
    }
    var max_batch_size = 20;
    get_facebook_photos_batch(facebook_vcards.slice(0, max_batch_size));
}

knx_facebook_is_connected = false;
knx_facebook_connect_channel = new Channel();

function get_facebook_photos_for_displayed_vcards() {
    get_facebook_photos(currently_displayed_vcards);
}

currently_displayed_vcard_channel.on_change(function() {
    if (knx_facebook_is_connected) {
        get_facebook_photos_for_displayed_vcards();
    } else {
        knx_facebook_connect_channel.on_change(get_facebook_photos_for_displayed_vcards);
    }
});

function facebook_attempt_fetch(socnet) {
    if (socnet.state() === state.unknown) {
        if (FB.Connect.get_loggedInUser() === null) return;
        socnet.set_state(state.loading);
        var fql = 'SELECT name, first_name, last_name, pic_square, uid, birthday_date, username, website, profile_blurb, status from user where uid IN (SELECT uid2 FROM friend WHERE uid1 = '+FB.Connect.get_loggedInUser()+') OR uid = '+FB.Connect.get_loggedInUser();
        debugLog("Querying Facebook...");
        FBIntern.Flash.decode = function (a) {if(a&&a.length&&typeof a!="string")a=a[0];if(!a||typeof a!="string")return a;a=a.replace(/\&custom_lt\;/g,"<");a=a.replace(/\&custom_gt\;/g,">");a=a.replace(/\&custom_backslash\;'/g,'\'');a=a.replace(/\&custom_backslash\;/g,'\\');a=a.replace(/\\0/g,"\0");return a;}
        FB.Facebook.apiClient.fql_query(fql, parse_FQL_result(socnet));
    }
}

function onConnected() {
  debugLog('onConnected()');
  facebook_attempt_fetch(addr_book.socnet('facebook'));
  knx_facebook_is_connected = true;
  knx_facebook_connect_channel.changed();
}

function parse_FQL_result(socnet) {
    return function(result, ex) {

        if (!result || !result.length) {
            debugLog(ex.name + ': ' + ex.message + '\n' + ex.fileName + ':' + ex.lineNumber);
            /* Do we need a failed state? */
            socnet.set_state(state.unknown);
            return;
        }

        var vcards = [];

        for (var i=0; i<result.length; i++) {
            var res = result[i]
                var vcard = {
                'fn'         : res.name,
                'given-name' : res.first_name,
                'family-name': res.last_name,
                'photo'      : res.pic_square,
                'socnet'     : 'facebook',
                'favicon'    : 'http://www.facebook.com/favicon.ico',
                'url'        : (res.username ? 'http://www.facebook.com/'+res.username
                                             : 'http://www.facebook.com/profile.php?id='+res.uid),
                'bday'       : res.birthday_date,
                'nickname'   : res.username,
                'account_id' : res.uid
            };
            /* repair birthdates that exist without years */
            if (vcard.bday) {
                if (vcard.bday == '00/00/0000') {
                    delete vcard.bday;
                } else {
                    vcard.bday = (vcard.bday.substring(6,10) ? vcard.bday.substring(6,10) : '-') +
                                  '-' + parseInt(vcard.bday.substring(0,2),10) +
                                  '-' + parseInt(vcard.bday.substring(3,5),10);
                }
            }
            /* repair text string of websites into an array of URLs */
            if (res.website) {
                vcard.websites = [];
                foreach(res.website.split(/,?\s+/), function(website) {
                    if (!starts_with('http://', website)) website = 'http://' + website;
                    vcard.websites.push(website);
                });
            }
            if (res.profile_blurb) vcard.profile_blurb = res.profile_blurb;
            if (res.status) {
                var tmp = new Date(res.status.time * 1000);
                vcard.lastTweet = {text: res.status.message.replace(/&amp;/g, "&"),
                                   created_at: tmp.toString(),
                                   id: res.status.status_id};
            }
            vcards.push(vcard);
        }

        if (vcards.length) {
            socnet.add_vcards(vcards);
            socnet.set_state(state.loaded);
            // "I am not a number, I am a free man"
            var uid = FB.Connect.get_loggedInUser();
            for (var i=0; i<vcards.length; i++) {
                if (vcards[i].account_id == uid) {
                    socnet.add_me(vcards[i].fn);
                    break;
                }
            }
        } else {
            socnet.set_state(state.unknown);
        }
    };
}

knx_fb_api_key = "2a2806da8abe66693e14bbbcbe9c0c64";
function resetFacebook() {
    addr_book.socnet('facebook').set_state(state.unknown);
    resetFacebookConnect();
}

function resetFacebookConnect() {
  FB.ensureInit(function() {
    FB.Connect.get_status().waitUntilReady( function( status ) {
      switch ( status ) {
        case FB.ConnectState.connected:
               FB.Connect.logoutAndRedirect(location.href);
               break;
        case FB.ConnectState.appNotAuthorized:
        case FB.ConnectState.userNotLoggedIn:
               location.reload();
               break;
      }
    })
  });
}                
                   
function fetchFromFacebook() {
  debugLog('entering fetchFromFacebook()');
  FB.init(knx_fb_api_key, "xd_receiver.html", {"ifUserConnected" : onConnected, "ifUserNotConnected": onNotConnected});
  FB.ensureInit( function () {
    FB.Connect.requireSession(function () { 
      debugLog('requireSession callback'); onConnected();
    }, false);
  });
}

function onNotConnected() {
  debugLog('onNotConnected()');
  FB.Connect.requireSession(function () { debugLog('requireSession callback'); onConnected();}, false)
}

knx.register_plugin({
    initialize: function () {
        FB.init(knx_fb_api_key, "xd_receiver.html",
                {"ifUserConnected" : onConnected});
        addr_book.refetch_when_stale('facebook', facebook_attempt_fetch);
    },
    reset: resetFacebookConnect
});
