function mklink(uri, text) {
	text = text.replace(/ /g, "&nbsp;");
	return '&bull;&nbsp;<a style="color: #2222dd" href="'+uri+'">'+text+'</a><br />';
}

function local_details_popup(target, text, width) {
	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 = 'sites-div';
	//arr... this be a hack, matey
	if(width) { div.style.width = width+'px'; };
	div.innerHTML = text;
	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 );
	};
}

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;

// convert dec to hex (used by fade())
var hD="0123456789ABCDEF";
function d2h(d) {
  var h = hD.substr(d&15,1);
  while(d>15) {d>>=4;h=hD.substr(d&15,1)+h;}
  return h;
}

function fade( id, text, pct, inc) {
  var elem = document.getElementById(id);
  var hexpct = (100-pct) * 255 / 100;
  hexpct = d2h(hexpct);
  if(hexpct.length == 1) { hexpct = "0"+hexpct; };
  elem.innerHTML = "<span style=\"color: #"+hexpct+""+hexpct+""+hexpct+"\">"+text+"</span>";
  if(pct > 0) {
    self.setTimeout("fade('"+id+"', '"+text+"', "+(pct-inc)+", "+inc+")", 20);
  } else {
    elem.innerHTML = "";
  }
}

// make a new DataRequestor that prints out the given status messages
// in the object identified by id. optionally, it will also disable
// a select box, etc. with id to_disable_id
//   usage example in asubscription-source/mason/group/view
function make_work_req ( id, work, ok, fail, to_disable_id ) {
  var where = document.getElementById(id);
  where.innerHTML = work;
  var to_disable = ( to_disable_id ) ? document.getElementById(to_disable_id) : false;
  if(to_disable) { to_disable.disabled = true; };
  var req = new DataRequestor();
  req.onload = function ( data ) {
    if(to_disable) { to_disable.disabled = false; };
    where.innerHTML = ok;
    self.setTimeout('fade( "'+id+'", "'+ok+'", 100, 1)', 500);
  }
  req.onfail = function ( data ) {
    if(to_disable) { to_disable.disabled = false; };
    where.innerHTML = fail;
  }
  return req;
}
