// traverse a path of tagnames down into an XML element.
function linkedin_xml_path(element, path) {
    if (!element) return undefined;
    for (var ii = 0; ii < path.length; ii++) {
        element = element.getElementsByTagName(path[ii])[0];
        if (element === undefined) return undefined;
    }
    if (!element) return undefined;
    return element.textContent ? element.textContent : element.text;
}

// Keeps track of how many queries have been sent out to LinkedIn and
// not come back yet.
unanswered_linkedin_queries = 0;

function addLIContactsToAddrBookXML(xmlDoc) {
    debugLog('parsing LI contacts XML');
    unanswered_linkedin_queries -= 1;

    var persons = xmlDoc.getElementsByTagName('person');

    var data = [];
    for (var i=0; i<persons.length; i++) {
        var p = persons[i];
        var url = linkedin_xml_path(p, ['site-standard-profile-request', 
                                        'url']);
        var account_id = linkedin_xml_path(p, ['id']);
        var item = {
          socnet:        'linkedin',
          favicon:       'http://www.linkedin.com/favicon.ico',
          url:           url,
          account_id:    account_id,
          'given-name':  linkedin_xml_path(p, ['first-name']),
          'family-name': linkedin_xml_path(p, ['last-name'])
        };

        item['fn'] = item['given-name'] + ' ' + item['family-name'];

        var photo = linkedin_xml_path(p, ['picture-url']);
        if (photo) item['photo'] = photo;

        var comment = linkedin_xml_path(p, ['headline']);
        if (comment) item['comment'] = comment;

        var locality = linkedin_xml_path(p, ['location', 'name']);
        if (locality) item['locality'] = locality;

        var category = linkedin_xml_path(p, ['industry']);
        if (category) item['category'] = category;

        var lastTweet = linkedin_xml_path(p, ['current-status']);
        if (lastTweet) {
            var lastTweetTimestamp = linkedin_xml_path(p, ['current-status-timestamp']);
            var lastTweetDate = new Date(parseInt(lastTweetTimestamp)).toString();
            item['lastTweet'] = {text: lastTweet, 
                                 created_at: lastTweetDate,
                                 id: '' + account_id + lastTweetTimestamp};
        }

        var websites = linkedin_xml_path(p, ['member-url-resources']);
        if (websites) {
            item['websites'] = [];
            foreach(websites.split(/,?\s+/), function(website) {
                if (starts_with('http://', website)) 
                    item['websites'].push(website);
                });
        }

        data.push(item);
    }
    debugLog('done parsing LI contacts XML');

    var socnet = addr_book.socnet('linkedin');
    if (socnet.state() === state.unknown) {
        socnet.set_state(state.loading);
    }

    socnet.add_vcards(data);
    if (unanswered_linkedin_queries === 0) socnet.set_state(state.loaded);
}

function getLIContacts(knx_linkedin_auth_token) {
  var socnet = addr_book.socnet('linkedin');
  /* we need to ensure there's only one pending ajax request at a time */
  if (socnet.state() === state.unknown) {
    socnet.set_state(state.loading);
    var method = 'linkedinAuthCallback.php?method=people&suffix=';
    var fields = escape(':(id,first-name,last-name,site-standard-profile-request,picture-url,current-status,current-status-timestamp,headline,location,industry,member-url-resources)');
    $.get(method + escape('~/connections') + fields, null, addLIContactsToAddrBookXML, 'xml');
    $.get(method + escape('~')             + fields, null, addLIContactsToAddrBookXML, 'xml');
    unanswered_linkedin_queries += 2;
  }
}

function onLIStatus(data) {
    debugLog('parsing LI profile XML');
    unanswered_linkedin_queries -= 1;
    /* following is purely for debugging purposes so far */
    window.li_status = data;
}

function statusFromLinkedIn(uid) {
    var method = 'linkedinAuthCallback.php?method=people&suffix=';
    var fields = escape(':(summary,specialities,positions)');
    $.get(method + escape('id='+uid) + fields, null, onLIStatus, 'xml');
    unanswered_linkedin_queries += 1;
}

function check_linkedin_auth_token() {
  var knx_linkedin_auth_token = readCookie('knx_linkedin_auth_token');
  if (knx_linkedin_auth_token) {
    clearInterval(window.liCheckr);
    window.liCheckr = null;
    attemptFetchFromLinkedIn();
  }
}

function resetLinkedIn() {
  eraseCookie('knx_linkedin_auth_token_s');
  eraseCookie('knx_linkedin_auth_token');
  addr_book.socnet('linkedin').set_state(state.unknown);
}

function attemptFetchFromLinkedIn() {
  var knx_linkedin_auth_token = readCookie('knx_linkedin_auth_token');  
  if (knx_linkedin_auth_token) {
    getLIContacts(knx_linkedin_auth_token);
  }
}

function fetchFromLinkedInNeedsAuth() {
  var knx_linkedin_auth_token = readCookie('knx_linkedin_auth_token');
  debugLog('knx_linkedin_auth_token found: ' + knx_linkedin_auth_token);
  if (!knx_linkedin_auth_token) {
    var d = new Date();
    createCookie('knx_windowid', d.getTime());
    window.liCheckr = setInterval(check_linkedin_auth_token, 100);
    return true;
  } else {
    attemptFetchFromLinkedIn();
  }
  return false;
}

function fetchFromLinkedInAPI() {
  if (fetchFromLinkedInNeedsAuth()) {
    li_login = "linkedinAuthCallback.php?"+Math.round(Math.random()*100000);
    window.open(li_login, "liAuth", "height=450,width=825,toolbar=0,location=1,directory=0,resizable=1");
  }
}

knx.register_plugin({initialize: attemptFetchFromLinkedIn, reset: resetLinkedIn});
