// ==UserScript==
// @name          LJ User Multilink
// @namespace     http://hacks.atrus.org/greasemonkey/
// @description   Makes all LJ user links into a "multilink" to their userinfo, journal, celcius data, rydberg data, and six degrees
// @include       http://*.livejournal.com/*
// ==/UserScript==

// LJ User Multilink
// 
// Copyright (C) 2005 Nikolas Coukouma
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function setupMultilink() {
  // this CSS stylesheet gets insertead into the head
  var css = "span.multilink {\
              position: relative;\
             }\
             span.multilink div.multilink {\
              display: none;\
              position: absolute;\
              left: 20px;\
              top: 1em;\
              width: 7em;\
              z-index: 99;\
              background-color: white;\
              opacity: 0.7;\
            }\
            \
            span.multilink:hover div.multilink {\
              display: block;\
            }";
  var style = document.createElement( "style" );
  style.appendChild( document.createTextNode( css ) );
  var head = document.getElementsByTagName( "head" )[0];
  head.appendChild( style );
};

// make an element into a multilink
// the array passed in should be in the form:
// [ [ "http://domain.tld/path/page.html", "label" ] ]
function makeMultilink( node, links ) {
  var wrapper = document.createElement( "span" );
  // for styling
  wrapper.className = "multilink";
  
  var multilink = document.createElement( "div" );
  // for styling
  multilink.className = "multilink";
  
  var a = null;
  for( var i = 0; i < links.length; i++ ) {
    a = document.createElement( "a" );
    a.appendChild( document.createTextNode( links[ i ][ 1 ] ) );
    a.href = links[ i ][ 0 ];
    
    multilink.appendChild( a );
    // line break!
    multilink.appendChild( document.createElement( "br" ) );
  }

  node.parentNode.replaceChild( wrapper, node );
  wrapper.appendChild( node );
  wrapper.appendChild( multilink );
};

(function(){
  //insert needed CSS
  setupMultilink();
  var s;
  var toMulti = [];
  var links = [];
  var toUser = "";
  
  // extract the current username from the cookie
  var varName = "ljsession="
  var cookie = document.cookie;
  var start = cookie.indexOf( varName ) + varName.length;
  start = cookie.indexOf( ":", start )+1;
  var end = cookie.indexOf( ":", start );
  var fromUser = cookie.substring( start, end );
  
  // get all span elements
  var resolver = document.createNSResolver( document );
  var spans = document.evaluate( "//span[@class=\"ljuser\"]", document, resolver, 0, null );
  // look for lj user links
  try {
    while( s = spans.iterateNext() ) {
      // all lj user links have exactly two children
      if( s.childNodes.length == 2 ) {
          // strip the original two links by replacing them
          // with their first child. This really only makes sense
          // because LJ links have one child (first an image, and then a bold
          //if( s.childNodes[ 0 ].nodeName == "A" ) {
          //  s.replaceChild( s.childNodes[ 0 ].childNodes[ 0 ],
          //                  s.childNodes[ 0 ] );
          //}
          //if( s.childNodes[ 1 ].nodeName == "A" ) {
          //  s.replaceChild( s.childNodes[ 1 ].childNodes[ 0 ],
          //                  s.childNodes[ 1 ] );
          //}
          //if( s.childNodes[ 1 ].nodeName == "B" ) {
          if( s.childNodes[ 1 ].nodeName == "A" ) {
             //toUser = s.childNodes[ 1 ].childNodes[ 0 ].data;
             toUser = s.childNodes[ 1 ].childNodes[ 0 ].childNodes[ 0 ].data;
          }
          links = [ [ "http://www.livejournal.com/userinfo.bml?user="+toUser,
                      "User info" ],
                    [ "http://www.livejournal.com/allpics.bml?user="+toUser,
                      "User pics" ],
                    [ "http://www.livejournal.com/users/"+toUser,
                      "Journal" ],
                    [ "http://splorg.org:8080/people/tobin/projects/livejournal/celsius2.cgi?A="+fromUser+"&B="+toUser,
                      "Celsius" ],
                    [ "http://splorg.org:8080/people/tobin/projects/livejournal/rydberg.cgi?username="+toUser,
                      "Rydberg" ],
                    [ "http://www.livejournal.com/tools/sixdegrees.bml?from="+fromUser+"&to="+toUser,
                      "Six Degrees" ] ];
         toMulti.push( [ s, links ] );
      }
    }
  } catch( Exception ) {
    // do nothing .. we expect one
  }
  // do a second pass to avoid an infinite loop
  // - makeMultilink fiddles with tree
  var el;
  while( toMulti.length > 0 ) {
      el = toMulti.pop();
      makeMultilink( el[0], el[1] );
  }
})();