function details_popup ( uri, target, key, created_stamp, mod_stamp ) {
  if ( target._details_div ) {
    target._details_div.style.display = 'block';
    return;
  }
  var div = document.createElement ( 'div' );
  target.parentNode.insertBefore ( div, target );
  div.style.display = 'none';
  div.style.position = 'absolute';
  div.className = 'details';
  div.innerHTML = "fetching ...";
  match_position ( target, div, 0, 4 );
  var top = div.style.top.replace ( 'px', '' );
  div.style.top = (parseInt(top) + parseInt(target.offsetHeight)) + 'px';
  div.style.display = 'block';
  target.onmouseout = function() { 
    div.tid = setTimeout ( function(){ div.style.display='none' }, 250 ); 
  };
  div.onmouseover = function() { 
    if ( div.tid ) { clearTimeout ( div.tid ) }; 
  };
  div.onmouseout = function() { 
    div.tid = setTimeout ( function(){ div.style.display='none' }, 250 ); 
  };

  var req = new DataRequestor();
  req.onload = function ( data ) {
    div.innerHTML = data;
    target._details_div = div;
  }
  req.addArg ( _GET, 'key', key );
  req.addArg ( _GET, 'created_ago', tx_ago.ago(created_stamp) );
  req.addArg ( _GET, 'changed_ago', tx_ago.ago(mod_stamp) );
  req.getURL ( uri );
}

function login_widget ( id, widget_url ) {
  var req = new DataRequestor();
  req.onload = function (data) {
    var link = document.getElementById ( id );
    var div = document.createElement ( 'div' );
    div.id = 'login-widget';
    link.parentNode.insertBefore ( div, link );
    div.style.position = 'absolute';
    div.style.display = 'none';
    div.innerHTML = data;

    var logged_in = data.match ( /<!-- login-link-text (.*) -->/ );
    if ( logged_in ) {
      link.innerHTML = logged_in[1];
    
      link.onclick = function() { return false; };
      link.onmouseover = function() {
        if ( div.style.display == 'none' ) {
          match_position ( link, div, 0, 4 );
          var top = div.style.top.replace ( 'px', '' );
          div.style.top = (parseInt(top) + parseInt(link.offsetHeight)) + 'px';
          div.style.display = 'block';
          link.onmouseout = function() { 
            div.tid = setTimeout(function(){ div.style.display='none' }, 250); 
          };
          div.onmouseover = function() { 
            if ( div.tid ) { clearTimeout ( div.tid ) }; 
          };
          div.onmouseout = function() {
            div.tid = setTimeout (function(){ div.style.display='none' },250); 
          };
        } else {
          if ( div.tid ) { clearTimeout ( div.tid ) }; 
        }
      }
    } else {
      // set the "from_uri" argument to the login link, so that nothing
      // dynamic needs to happen inside template nav components
      link.href = link.href + '?from_uri=' + document.location;
    }
  }
  req.getURL ( widget_url );
}

function logged_in_dont_show ( id, widget_url ) {
  var req = new DataRequestor();
  req.onload = function ( data ) {
    var logged_in = data.match ( /<!-- logged in -->/ );    
    if ( logged_in ) {
      var link = document.getElementById ( id );
      link.style.display = "none";
    }
  }
  req.getURL( widget_url );
}

function match_position ( el, target, x, y ) {
  x += el.offsetLeft;
  y += el.offsetTop;
  if ( el.offsetParent ) {
    return match_position ( el.offsetParent, target, x, y );
  } else {
    target.style.left = x + 'px';
    target.style.top = y + 'px';
  }
}

function mark_placeholder_links () {
  var els = document.getElementsByName ( "gadget-cleanup-wikilink" );
  _mark_placeholder_links_rpc ( els, 0 );
}
function _mark_placeholder_links_rpc ( els, index ) {
  if ( index >= els.length ) { return; }
  var el = els[index];
  var req = new DataRequestor();
  req.addArg ( _POST, 'rpc', 'true' );
  req.onload = 
    function ( data, obj ) { 
      //alert ( data + 'for ' + el.href );
      if ( data.indexOf('not found') > -1 ) {
        el.className = 'placeholder-link';
      }
      _mark_placeholder_links_rpc ( els, index+1 );
    };
  req.getURL ( el.href );
}

// Nelson's "ago" code. Modified to take so as to be created from
// Mason as an object with a list of translated string

// Turn a Unix seconds-since-epoch timestamp into a human friendly string
// such as "3 days ago" or "an hour ago". Format this clientside in Javascript
// rather than serverside so that the info looks right even if page is cached.
//
// By Nelson Minar <nelson@monkey.org>. License: public domain.
// http://www.nelson.monkey.org/~nelson/weblog/
//
// ref: the reference time you're evaluating. Seconds since epoch.
// now: optional parameter, current time. Leave blank to evaluate ref
//   according to browser's current time. Used by test suite
//
// Example: ago(1125580859) == "5 days ago" (or whatever, this is relative)
//          ago(1125580859 - 60 * 3, 1125580859) == "3 minutes ago"

function ago (ref, now) {
  if (typeof(now) == "undefined") {
    now = Math.floor(new Date().getTime() / 1000);
  }
  delta = now - ref;
  if (delta < 0) {
    return this.strings[0];
  } else if (delta == 0) {
    return this.strings[1];
  } else if (delta < 60) {
    return this.strings[2];
  } else if (delta < 120) {
    return "1 " + this.strings[3] + " " + this.strings[14];
  } else if (delta < 3600) {
    minutes = Math.floor(delta / 60);
    return minutes + " " + this.strings[4] + " " + this.strings[14];
  } else if (delta < 7200) {
    return "1 " + this.strings[5] + " " + this.strings[14];
  } else if (delta < 86400) {
    hour = Math.floor(delta / 3600);
    return hour + " " + this.strings[6] + " " + this.strings[14];
  } else if (delta < 172800) {
    return "1 " + this.strings[7] + " " + this.strings[14];
  } else if (delta <  1209600) {
    day = Math.floor(delta / 86400);
    return day + " " + this.strings[8] + " " + this.strings[14];
  } else if (delta < 2592000) {
    week = Math.floor(delta / 604800);
    return week + " " + this.strings[9] + " " + this.strings[14];
  } else if (delta < 5184000) {
    return "1 " + this.strings[10] + " " + this.strings[14];
  } else if (delta < 31536000) {
    month = Math.floor(delta / 2592000);
    return month + " " + this.strings[11] + " " + this.strings[14];
  } else if (delta < 63072000) {
    return "1 " + this.strings[12] + " " + this.strings[14];
  } else {
    year = Math.floor(delta / 31536000);
    return year + " " + this.strings[13] + " " + this.strings[14];
  }
}

function Ago ( strings ) {
  this.strings = strings;
}
Ago.prototype.ago = ago;


