// ==UserScript==

// @name           Twitter Expand Tiny URLs

// @namespace      danlester.twitter

// @description    Expands Tiny URL (etc) links on Twitter pages
// @include        http://twitter.com/*

// @include        http://*.twitter.com/*
// @exclude        http://twitter.com/devices*
// @exclude        http://twitter.com/account*
// @exclude        http://twitter.com/logout*
// @exclude        http://help.twitter.com/*
// ==/UserScript==


(function() {
// Closure

var reqLinks = Array();
var reqInd = 0;


var processSpan = function(spanobj) {
   // spanobj.style.backgroundColor = 'yellow';

   var allas = spanobj.getElementsByTagName('a');

   var thisA;

   for (var i=0 ; i < allas.length ; i++) {
      thisA = allas[i];
      reqLinks[reqInd++] = thisA;
   }

};

var transmitLinks = function(reqLinks) {
   var reqStr = '';
   for (var i=0 ; i < reqLinks.length ; ++i) {
      reqStr += 'url'+i+'='+encodeURI(reqLinks[i].href)+"&";
   }

   var serviceurl = GM_getValue('serviceurl', 'http://www.danlester.com/gm/expandtinyurls.php');
   // 'http://localhost/danlester/gm/expandtinyurls.php'

   GM_log(reqStr);

   GM_xmlhttpRequest({
      method: 'POST',
      url: serviceurl,
      headers: {
          'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
          'Accept': 'application/xml',
          'Content-type' : 'application/x-www-form-urlencoded'
      },
      onload: function(responseDetails) {
        GM_log(responseDetails.responseText);
        var parser = new DOMParser();
        var dom = parser.parseFromString(responseDetails.responseText,
            "application/xml");
        var entries = dom.getElementsByTagName('entry');

        var key;
        var tinyurl;
        var realurl;
        var texturl;

        GM_log('entries.length = '+entries.length);

        for (var i = 0; i < entries.length; i++) {
            key = entries[i].getElementsByTagName('key')[0].textContent;
            tinyurl = entries[i].getElementsByTagName('tinyurl')[0].textContent;
            realurl = entries[i].getElementsByTagName('realurl')[0].textContent;

            aobj = reqLinks[key];

            if (aobj.href == tinyurl && realurl != '' && realurl != tinyurl) {
               GM_log("Setting "+key+" to "+realurl+" from "+aobj.href);

               aobj.href = realurl;
               texturl = realurl;
               if (texturl.length > 28) {
                  texturl = texturl.substr(0,27)+'...';
               }

               aobj.innerHTML = texturl;
            }

        }

        var newserviceurl = dom.getElementsByTagName('newserviceurl');
        if (newserviceurl.length > 0) {
           GM_setValue('serviceurl', newserviceurl[0].textContent);
        }

      },
      data: reqStr
   });

};


var timeline_table = document.getElementById('timeline');

if (timeline_table) {
   GM_log("Found timeline_table");

   var allTRs = timeline_table.getElementsByTagName('tr');
   var thisTR;

   // Collect all links from main timeline body
   for (var i=0 ; i < allTRs.length ; i++ ) {
      // GM_log("Cycle through trs "+i);
      thisTR = allTRs[i];
      var allTDs = thisTR.getElementsByTagName('td');
      // GM_log("allTDs.length "+allTDs.length); 

      if (allTDs.length == 2 || allTDs.length == 3) {  // 3 for home, 2 on profile
         var allSpans = allTDs[allTDs.length-2].getElementsByTagName('span');
         if (allSpans.length >= 2) {
            // GM_log("processSpan "+allSpans.length);
            processSpan(allSpans[0]);
         }

      }
   }

   // Now try to get most recent status update if we're on a profile page
   var follow_control = document.getElementById('follow-control');
   if (follow_control) {
      var statusp = follow_control.nextSibling.nextSibling.firstChild.nextSibling.firstChild.nextSibling;
                    //   div      .   #text   .    div    .  #text   .    DIV    .   #text  .    P
      if (statusp && statusp.nodeName == 'P') {
         GM_log("Found most recent status update - must be on profile");
         processSpan(statusp);
      }
   }


   if (reqLinks.length > 0) {
      // Send links for processing
      transmitLinks(reqLinks);
   }
   else {
      GM_log('No links found to expand. Nothing to transmit to server.');
   }

}


// End closure
})();

