function get_flickr_photos_from_url(vcard, url, max, callback) {
    if (max <= 0) return;
    debugLog('fetching from Flickr: '+url);

    $.getJSON(url, function(data) {
        foreach(data.items, function(item) {
            if (max-- <= 0) return; // limit to `max` photos per person
            add_to_photostream(vcard, {href: item.link, src: item.media.m, title: item.title});
        });
        callback(vcard, max);
    });
}

function nop() { }

function get_more_flickr_photos(vcard, max) {
    var id = vcard.account_id;
    var url = 'http://api.flickr.com/services/feeds/photos_public.gne?id='+id+'&format=json&jsoncallback=?';
    get_flickr_photos_from_url(vcard, url, max, nop);
}

function get_flickr_photos_for(vcard) {
    knxassert(vcard.socnet === 'flickr', "can't get flickr photos for " + $.toJSON(vcard));
    if (photostream_div_for(vcard)) return;

    var id = vcard.account_id;
    var me_url = 'http://api.flickr.com/services/feeds/photos_public.gne?tags=me&id='+id+'&format=json&jsoncallback=?';

    get_flickr_photos_from_url(vcard, me_url, knx_max_photos_per_person, get_more_flickr_photos);
}

function get_flickr_photos(vcards) {
    var gotten = 0;
    var max_batch_size = 20;

    for (var ii = 0; ii < vcards.length; ii++) {
        var vcard = vcards[ii];

        if (vcard.socnet !== 'flickr') continue;
        if (photostream_div_for(vcard)) continue;

        get_flickr_photos_for(vcard);
        gotten++;
        if (gotten === max_batch_size) break;
    }
}

currently_displayed_vcard_channel.on_change(function() {
    get_flickr_photos(currently_displayed_vcards);
});        

function checkFrobCookie() {
  var knx_flickr_frob =readCookie('knx_flickr_frob');
  if (knx_flickr_frob) {
    clearInterval(window.flickrCheckr);
    window.flickrCheckr = null;
    onFrob(knx_flickr_frob);
  }
}

function flickrApiRequest(parameters) {
    addr_book.socnet('flickr').set_state(state.loading); // XXX must fix this for refetch
    $.getJSON('getFlickrApiSig.php?' + parameters, function(result) {
        inject_script_failsafe('http://api.flickr.com/services/rest/?' + result.api_sig,
                               'flickr',
                               resetFlickr);
    });
}

function onFrob(theFrob) {
  debugLog('onFrob("'+theFrob+'")');
  eraseCookie('knx_flickr_frob');
  flickrApiRequest( 'format=json' +
                   '&frob='+theFrob + 
                   '&jsoncallback=onToken' +
                   '&method=flickr.auth.getToken');
}

function onToken(response) {
  inject_script_ack('flickr');
  if (response.stat && (response.stat == "fail")) {
    debugLog('Flickr onToken() error: ' + response.message);
    eraseCookie('knx_flickr_frob');
  } else {
    if (response.auth) {
      token = response.auth.token._content;
      createCookie('knx_flickr_token', token, 365*2);
      getContacts(token);
    }
  }
}

function getContacts(token) {
  debugLog('getContacts('+token+')');
  flickrApiRequest( 'auth_token='+token +
                   '&format=json' +
                   '&jsoncallback=onContacts' +
                   '&method=flickr.contacts.getList');
}

function onContacts(response) {
  inject_script_ack('flickr');
  if (response.stat && (response.stat == "fail")) {
    errMsg = 'Flickr onContacts() error: ' + response.message;
    debugLog(errMsg);
    eraseCookie('knx_flickr_token');
  } else {
    if (response.contacts) {
      var vcards = [];
      for (var i=0; i<response.contacts.total; i++) {
        var friend = response.contacts.contact[i];

        var stringname = (friend.realname || 
                          friend.username || 
                          friend.path_alias || 
                          '');
        var guessed_names = guess_names_from_string(stringname);

        var path = (friend.path_alias || (friend.nsid + '/'));

        vcards.push({
          fn:         stringname,
          'given-name':  guessed_names['given-name'],
          'family-name': guessed_names['family-name'],
          adr:        friend.location,
          url:       'http://www.flickr.com/people/'+path,
          rss:       'http://api.flickr.com/services/feeds/photos_public.gne?id='+friend.nsid,
          nickname:   friend.username,
          socnet:    'flickr',
          favicon:   'http://www.flickr.com/favicon.ico',
          account_id: friend.nsid
        });
      }
    }
  }
  if (vcards && vcards.length) {
    var socnet = addr_book.socnet('flickr');
    socnet.add_vcards(vcards);
    socnet.set_state(state.loaded);
  }
}

function resetFlickr() {
  eraseCookie('knx_flickr_token');
  eraseCookie('knx_flickr_frob');
  addr_book.socnet('flickr').set_state(state.unknown);
}

function attemptFetchFromFlickr() {
  if (addr_book.socnet('flickr').state() !== state.unknown) return;
  var knx_flickr_token = readCookie('knx_flickr_token');
  if (knx_flickr_token) {
    getContacts(knx_flickr_token);
  }
}

function flickr_credentials_exist() {
    return readCookie('knx_flickr_token') ? 1 : 0;
}

function fetchFromFlickrNeedsAuth() {
  if (!flickr_credentials_exist()) {
    eraseCookie('knx_flickr_frob');
    var d = new Date();
    createCookie('knx_windowid', d.getTime());
    window.flickrCheckr = setInterval(checkFrobCookie, 100);
    return true;
  } else {
    attemptFetchFromFlickr();
  }
  return false;
}

function fetchFromFlickr() {
  if (fetchFromFlickrNeedsAuth()) {
    /* @@ TODO : No longer should be called .php -- it's a plain static HTML file now */
    flickr_login = "flickrCallback.php?"+Math.round(Math.random()*100000);
    window.open(flickr_login, "flickrAuth", "height=600,width=800,toolbar=0,location=1,directory=0,resizable=1");
  }
}

// Yahoo frame-busts. Can't use an internal iframe or dialog box.
//document.write('<iframe name="flickrAuth" style="width:500;height:500;" ></iframe>');

knx.register_plugin({initialize: attemptFetchFromFlickr, reset: resetFlickr});
