/* ========================================
** functions.js
** Common Functions / Variables
** Copyright (c) 2005-2007 Newzbin Ltd
**=========================================*/

if (!window.opera) opera = false;
var ie = document.all ? true : false;
var firefox = (document.getElementById && !document.all) ? true : false;
var range_start = -1;
var range_end = -1;
var timeouts = new Array(); /* used in listings for the popup setTimeout() */

function addEvent(obj, evType, fn){
	if(obj.addEventListener){
		obj.addEventListener(evType, fn, false); 
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent('on'+evType, fn);
		return r;
	} else {
		return false;
	}
}

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function getObj(name)
{
	var obj;

	if (document.getElementById) {
		obj = document.getElementById(name);
	} else if (document.all) {
		obj = document.all[name];
	} else if (document.layers && document.layers[name]) {
		obj = document.layers[name];
	} else {
		obj = document.layers.testP.layers[name];
	}

	return obj;
}


function openwin(href)
{
		var winWidth = 640;
		var winHeight = 480;

	var openleft = ((screen.availWidth - winWidth) / 2).toString();
		var opentop = ((screen.availHeight - winHeight) / 2).toString();

	win = window.open(href, "newzBin",
		'top=' + opentop + ',left=' + openleft + ',width=' + winWidth + ',height=' + winHeight + ',scrollbars=1,resizable=1');
	return false;
}

function invert(name)
{
	var arr = document.getElementsByName(name);
	var l = arr.length;

	for (var i = 0; i < l ; i++)
	{
		fldObj = arr[i];

		if (fldObj.disabled == false && fldObj.type == 'checkbox')
		{
			if (fldObj.checked)
			{
				fldObj.checked = false;
			}
			else
			{
				fldObj.checked = true;
			}
		}
	}
}

var arySelectedIndexes = new Array();
var aryLen;

function already_been_processed(c)
{
	c = getObj(c);
	var a = arySelectedIndexes;
	for (var n=0;n<aryLen;n+=2)
	{
		if ( ( c>= a[n] ) && (c <= a[n+1] ) && (a[n] > 0)   )
	 		return true;
	}
	return false;
}

function invalidate_range(c)
{
	c = getObj(c);
	var a = arySelectedIndexes;
	for (var n=0;n<aryLen;n+=2)
	{
		if ( (a[n] > 0) && ( c>= a[n] ) && (c <= a[n+1] ) )
			a[n]=-1;n[n+1]=-1;
	}
}

function OldcheckRanges(f)
{
	f = getObj(f);
	var i,n,x,z;
	var range_begin=0;
	var l = f.elements.length;
	var a = arySelectedIndexes;

	for (z=0;i<l; z++)
		if (f.elements[z].type == "checkbox")
			break;

	//set up the ranges
	for (i=0;i<l; i++)
	{

		if (  f.elements[i].checked==true )
		{
			if (!already_been_processed(i))
				if (range_begin > 0)
				{
					x = arySelectedIndexes.length;
					arySelectedIndexes[x] = range_begin;
					arySelectedIndexes[x+1] = i;
					aryLen = x+1;
					for (n=range_begin;n<=i;n++)
					{
						f.elements[n].checked=true;
					}
					range_begin = 0;
				}
				else
				{
					range_begin = i;
				}
		}
		else //not checked
		{
			invalidate_range(i);
		}
	}
}

function checkRanges(name)
{
	var arr = document.getElementsByName(name);
	var l = arr.length;
	var rs = -1;
	var re = -1;
	
	for (var i = 0; i < l ; i++)
	{
		fldObj = arr[i];
		
		if (fldObj.value == range_start){rs = i}
		if (fldObj.value == range_end){re = i}
	}
	
	if (rs > re)
	{
	var tr = re;
	re = rs;
	rs = tr;
	}
	
	for (var i = rs; i < re ; i++)
	{
		fldObj = arr[i];

		if (fldObj.disabled == false && fldObj.type == 'checkbox')
		{
			fldObj.checked = true;
		}
	}
}




function OldcheckAll(field)
{
	field = getObj(field);
	l = field.elements.length;
	for (i = 0; i < l; i++)
	{
		if (field.elements[i].type == "checkbox")
		{
			field.elements[i].checked = true;
		}
	}
}

function checkAllIfNoneChecked(name)
{
	var arr = document.getElementsByName(name);
	var empty = true;
	var l = arr.length;

	for (var i = 0; i < l ; i++)
	{
		if (arr[i].disabled == false && arr[i].type == "checkbox"
			&& arr[i].checked == true)
		{
			empty = false;
			break;
		}
	}

	if ( empty == true ) {
		checkAll(name);
	}
}

function checkAll(name)
{
	var arr = document.getElementsByName(name);
	var l = arr.length;

	for (var i = 0; i < l ; i++)
	{
		if (arr[i].disabled == false && arr[i].type == "checkbox")
		{
			arr[i].checked = true;
		}
	}
}

function selectAll(form, select)
{
	field = "document."+form+".elements['"+select+"']";
	window.status = field;
	Source = eval(field);
	for(x = 0; x < Source.length; x++)
	{
		Source.options[x].selected = true;
	}
}

function uncheckAll(name)
{
	var arr = document.getElementsByName(name);
	var l = arr.length;

	for (i = 0; i < l; i++)
	{
		if (arr[i].type == "checkbox")
		{
			arr[i].checked = false;
		}
	}
}

function checkWithClass(name, withclass)
{
	var arr = document.getElementsByName(name);
	var l = arr.length;
	var match = new RegExp("\\b" + withclass + "\\b");

	for (var i = 0;i < l ; i++)
	{
		var e = arr[i];
		if (e.className.match(match))
		{
			e.checked = true;
		}
	}
}

var aCheckElements = new Array();
var objFirstElement, shiftWorking;

//see if the browser is netscape 4, as its a 'special case'
var nav4 = (navigator.appName.indexOf("Netscape") >= 0
    && parseFloat(navigator.appVersion) >= 4
    && parseFloat(navigator.appVersion) < 5) ? 1 : 0;

function fillCheckboxElements(e, objFormID)
{
	var objForm = getObj(objFormID);
	var aElements = objForm.elements;
	var index = 0;

	for (i = 0; i < objForm.length; i++) {
		if (aElements[i].type == "checkbox") {
			aCheckElements[index++] = aElements[i];
		}
	}
}

function shiftCheck(e, objThisElement, objFormID) /* {{{ */
{
	var sKey = (nav4) ? e.modifiers & Event.SHIFT_MASK : e.shiftKey;

		// No need to process if the shift key isn't pressed
		if (!sKey) {
			objFirstElement = objThisElement;
			return;
		}

		// Check to see if we're already working, if not, set it to true
		if (shiftWorking)
			return;
		else
			shiftWorking = true;

		var start = -1;
		var end = -1;
	

		if (aCheckElements.length == 0)
			fillCheckboxElements(e, objFormID);

		for (i = 0; i < aCheckElements.length; i++) {
			// Check to see if we have the first object, camparison by ID
			if (aCheckElements[i] == objFirstElement)
				start = i;

			// Check to see if we have the last object, camparison by ID
			if (aCheckElements[i] == objThisElement)
				end = i;

			// If we have both, there is no need to continue
			if (start != -1 && end != -1)
				break;
		}

		if (start != end) {
			if (start < end) {
				for (j = start; j < end; j++) {
					aCheckElements[j].checked = true;
				}
			} else {
				for (j = start; j > end; j--) {
					aCheckElements[j].checked = true;
				}
			}
	}

	// The function has finished
	shiftWorking = false;
} /* }}} */

function checkSystemTime()
{
	var date_syst = new Date();
	var date_serv = new Date();

	date_serv.setTime(ourtime*1000);

	var date_diff = (date_syst.getTime()/1000) - (date_serv.getTime()/1000);
	var date_comp = (60 * 60) * 24;

	if (date_diff > date_comp) {
		alert('Warning: Your system clock appears to be set incorrectly. Your system time (' + date_syst.toLocaleString() +
			') differs from our server time (' + date_serv.toLocaleString() + ') by over 24 hours.  You will not be able to login ' +
			'until you adjust your system time to the correct date and time.  If you believe that your time is correct, ' +
		'you may be able to solve this problem by forcing a browser refresh (SHIFT+F5 in IE, CTRL+R in FireFox.)');
		return false;
	}

	return true;
}

function setFormValue(obj, value)
{
	var obj = getObj(obj);
	obj.value = value;
}

function idFocus(id)
{
	if (e=getObj(id))
		e.focus();
}

displays = new Array();

function idHide() // (id, id, id)
{
	for (i = 0 ; i < idHide.arguments.length ; i++)
	{
		id = idHide.arguments[i];
		if (e = getObj(id))
		{
			if (e.style.display != 'none')
			{
				if (e.currentStyle)
				{
					displays[id] = e.currentStyle["display"];
				}
				else if (d = window.getComputedStyle(e, "").getPropertyValue("display"))
				{
					displays[id] = d;
				}
				e.style.display = 'none';
			}
		}
	}
}

function idShow() // (id, id, id)
{
	for (i = 0 ; i < idShow.arguments.length ; i++)
	{
		id = idShow.arguments[i];
		if (e = getObj(id))
		{
			if (displays[id])
			{
				e.style.display = displays[id];
			}
			else
			{
				e.style.display = 'block';
			}
		}
	}
}

function idToggleDisplay() // (id, id, id)
{
	for (i = 0 ; i < idToggleDisplay.arguments.length ; i++)
	{
		id = idToggleDisplay.arguments[i];
		if (e = getObj(id))
		{
			if (e.style.display == 'none')
			{
				idShow(id);
			}
			else
			{
				idHide(id);
			}
		}
	}
}

/* Pass the form, the form name of the source SELECT and the name of the target */
/* Selected options in fromname will be moved to toname */
function moveSelectOptions(form, fromname, toname)
{
	var moved = new Array;

	from = form.elements[fromname];
	to = form.elements[toname];
	while((x = from.selectedIndex) != -1)
	{
		moved.push(from.options[x].value);

		to.options[to.options.length] =
			new Option(from.options[x].text,
				from.options[x].value);
		from.options[x] = null;

	}
	return moved;
}

function changeExcludeIDs(act, type, ids)
{
	if (ids.size())
	{
		new Ajax.Request('/backend/exclude/',
		{
			method: 'post',
			parameters:
			{
				'act': act,
				'type': type,
				'ids[]': ids
			}
		});
	}
	return false;
}

function updateContainer(container, url)
{
	new Ajax.Updater({ success: $(container) }, url, { method: 'get' });

	return false;
}



/* Pair of functions to help prevent the user from accidently resubmiting a form,
   but which lets the user retry after a reasonable period. */
var lockFormAt = new Array();
var lockFormSubmitValue = new Array();
var lockFormSubmit = new Array();
var lockFormTimeout = 30000; // 30 seconds

// name = identifier, usually a string like 'login'.  Must be unique to a page
// submit = form submit element who's value should indicate a lock, or false for none
function lockForm(name, submit)
{
	now = new Date();
	if (lockFormAt[name])
	{
		if ((now.getTime() - lockFormAt[name].getTime()) > lockFormTimeout)
		{
			unlockForm(name);
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		if (submit)
		{
			lockFormSubmit[name] = submit;
			lockFormSubmitValue[name] = submit.value;
			submit.value = "Please Wait...";
		}
		lockFormAt[name] = now;
		setTimeout("unlockForm('" + name + "');", lockFormTimeout);
		return true;
	}
}

function unlockForm(name)
{
	if (lockFormSubmitValue[name])
		lockFormSubmit[name].value = lockFormSubmitValue[name];
	lockFormSubmitValue[name] = false;
	lockFormSubmit[name] = false;
	lockFormAt[name] = false;
}

/* v3 highlighting {{{ */
var checked_size_total = 0;
function toggleCheck(c)
{
	if (range_start == -1 && range_end == -1){range_start = c.value}
	if (range_start != -1 && range_end == -1){range_end = c.value}
	if (range_start != -1 && range_end != -1)
	{
		range_start = range_end;
		range_end = c.value;
	}
}

function hilight(c)
{
	var tbody = c.parentNode.parentNode.parentNode;
	/* skip if already hilighted */
	if (!(tbody.className.match(/ select/)))
	{
		tbody.className = tbody.className + " select";

		if (getObj('sz' + c.value) != null)
		{
			var box;
			var add = document.getElementById('sz' + c.value).value;
			box = document.getElementById('checked_size_total');
			checked_size_total = checked_size_total + parseInt(add);
			box.innerHTML = Math.round(checked_size_total/1048576*10)/10;

			checked_item_count += 1;
			var span=document.getElementById('checked_item_count');
			span.innerHTML = checked_item_count;
		}
	}
}

function unHilight(c)
{
	var tbody = c.parentNode.parentNode.parentNode;
	if (tbody.className.match(/ select/))
	{
		tbody.className = tbody.className.replace(/^(\S+) select/, "$1");
		
		if (getObj('sz' + c.value) != null)
		{
			var rem = document.getElementById('sz' + c.value).value;
			var box = document.getElementById('checked_size_total');
			checked_size_total = checked_size_total - parseInt(rem);
			box.innerHTML = Math.round(checked_size_total/1048576*10)/10;

			checked_item_count -= 1;
			var span=document.getElementById('checked_item_count');
			span.innerHTML = checked_item_count;
		}
	}
}
/* }}} */

function insertAtSelection(target, beforeSelText, afterSelText) {
	var len = target.textLength;
	var selStart = target.selectionStart;
	var selEnd = target.selectionEnd;
	var startText = ''; var endText = '';
	var selText = target.value.substring(selStart,selEnd);
	
	if (selStart > 0) startText = target.value.substring(0,selStart);
	if (selEnd < len) endText = target.value.substring(selEnd,len);

	target.value = startText+beforeSelText+selText+afterSelText+endText;
}

function nbcode(target, c, p) {
	var code = c.toUpperCase();
	var nbcode = c.toLowerCase();
	var param = p;

	switch(code) {
		case 'Q':
			param = prompt('Who do you want to quote?  (Enter nothing to for a general quote.)');
			break;
	}

	if ( param ) {
		param = '=' + param;
	} else {
		param = '';
	}
	
	insertAtSelection(target, '['+nbcode+param+']', '[/'+nbcode+']');

	return true;
}

function checkAjaxValidation(r)
{
	eval(r.responseText);
	updateFormValidation(res);
}

function updateFormValidation(res)
{
	if (res.valid)
	{
		$(res.type + '_result').innerHTML = '<img src="/m/i/i/progress/complete.png" alt="OK" />';
	}
	else
	{
		$(res.type + '_result').style.position = 'relative';
		$(res.type + '_result').innerHTML = '<img src="/m/i/i/unconfirmed.png" alt="BAD" title="' + res.message + '" />' +
"<div style='font-size: 90%;position: absolute;left: 20px;max-height: 1em;min-width: 250px;max-width: 600px;' class='nicetitle'>" + res.message + "</div>";
	}
}

/* these depend on prototype.js */
var showhideClassDisplay = new Object();
function showClass(klass)
{
	var elements = document.getElementsByClassName(klass);

	elements.each( function(e){
		e.style.visibility = 'visible';
		e.style.position = 'static';
	});
}

function hideClass(klass)
{
	var e = document.getElementsByClassName(klass);
	var elements = document.getElementsByClassName(klass);

	elements.each( function(e){
		e.style.visibility = 'hidden';
		e.style.position = 'absolute';
	});
}

function showId(id,display)
{
	var e = getObj(id);

	if ( display ) {
		e.style.display = display;
	} else {
		e.style.display = 'block';
	}
	e.style.visibility = 'visible';
	e.style.position = 'static';
}

function hideId(id)
{
	var e = getObj(id);
	e.style.display = 'none';
	e.style.visibility = 'hidden';
	e.style.position = 'absolute';
}

function isHidden(id)
{
	var e = getObj(id);
	return ( e.style.visibility == 'hidden' );
}

// Sidebox utility functions {{{
function sideBoxUp(num)
{
	var m = $('menu');
	var e = $('SideBox_' + num);

	// find e in m's childNode list, remembering the previous node in the list,
	// then .removeChild e and .insertBefore the previous one
	var prevNode = null;
	for (var i = 0; i < m.childNodes.length; i++)
	{
		if (m.childNodes[i] == e)
		{
			if (prevNode)
			{
				m.removeChild(e);
				// clearly .prevSibling would be better
				// assuming everyone supports it?
				m.insertBefore(e, prevNode);
				new Ajax.Request('/set/sidebox/?move=up&noret=yes&id=' + num, {method: 'get'});
				return false;
			}
			else
			{
				// already as high up as we go
				return false;
			}
		}
		prevNode = m.childNodes[i];
	}
	return false;
}

function sideBoxDown(num)
{
	var m = $('menu');
	var e = $('SideBox_' + num);

	for (var i = 0; i < m.childNodes.length; i++)
	{
		if (m.childNodes[i] == e)
		{
			if (m.lastChild != e)
			{
				m.removeChild(e);
				m.insertBefore(e, m.childNodes[i].nextSibling);
				new Ajax.Request('/set/sidebox/?move=down&noret=yes&id=' + num, {method: 'get'});
				return false;
			}
			else
			{
				// already as low as we go
				return false;
			}
		}
	}
	return false;
} // }}}

var guessWin;
function showGuess()
{
	guessWin = new Window('guessWin',
	   {
	    className: "popup",
	    title:"Sample window",
	    url:"/backend/guess_attrs/?value=" + escape($('ReportTitle').value),
	    zIndex:150,
	    resizable: true,
	    width:300, height:400
	   }
	);
	guessWin.showCenter();
}

function hideGuess()
{
	guessWin.destroy();
}

var ie_body = (document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body? document.body : null;
function clampToViewport(e, offx, offy)
{
	offx = (typeof(offx) != 'undefined' ? offx : 0);
	offy = (typeof(offy) != 'undefined' ? offy : 0);

	Position.prepare();
	var scrollx = Position.deltaX;
	var scrolly = Position.deltaY;

	var w = Element.getWidth(e);
	var h = Element.getHeight(e);
	var x = parseInt(e.style.left);
	var y = parseInt(e.style.top);
	xlim = (window.innerWidth  || (ie_body && ie_body.clientWidth) || 0) + (scrollx - w - offx);
	ylim = (window.innerHeight || (ie_body && ie_body.clientHeight) || 0) + (scrolly - h - offy);

	e.style.top = Math.min(y,ylim) + 'px';
	e.style.left = Math.min(Math.max(0,x),xlim) + 'px';
}

function onclickInfoBox(id,url,offx,offy)
{
	return showInfoBox(id,url,offx,offy,0);
}

function onkeydownInfoBox(id,url,offx,offy)
{
	return showInfoBox(id,url,offx,offy,0);
}

function onmouseoverInfoBox(id,url,offx,offy)
{
	return showInfoBox(id,url,offx,offy,200);
}

function showInfoBox(id, url, offx, offy, opendelay)
{
	if (timeouts[id]) clearTimeout(timeouts[id]);
	timeouts[id] = null;

	if (url && !timeouts[id + "_open"])
	{
		var show = function() {
			var click = "show" + id;
			var e = $(click);
			var offsets = Position.positionedOffset(e);
			$(id).style.top = (offsets[1] + offy) + 'px';
			/* $(id).style.left = (offsets[0] + offx) + 'px'; */
			$(id).style.left = 260;
			clampToViewport($(id), offx, offy);
			new Ajax.Updater({ success: id }, url,
			    { method: 'get', onComplete: function() { setTimeout(function() { clampToViewport($(id), offx, offy);}, 10) } });
			Element.show(id);
		};
		if (opendelay === null || opendelay == 0)
		{
			show();
		}
		else
		{
			timeouts[id + "_open"] = setTimeout(show, opendelay);
		}
	}

	return false;
}
function hideInfoBox(id)
{
	if (timeouts[id + "_open"]) clearTimeout(timeouts[id + "_open"]);
	timeouts[id + "_open"] = null;
	if (!(timeouts[id])) timeouts[id] = setTimeout(function() { Element.hide(id) }, 500);
}

/* used in listings */
function toggleBookmark(e)
{
	new Ajax.Request(e.href + '&close=1', {method: 'get'});

	var img = e.firstChild;
	if (e.href.match(/add/))
	{
		e.href = e.href.replace(/add/, 'remove');
		e.title = "Remove this item from your bookmarks";
		img.src = img.src.replace(/unbookmarked/, 'bookmarked');
		img.alt = "[-B]";
	}
	else
	{
		e.href = e.href.replace(/remove/, 'add');
		e.title = "Bookmark this report";
		img.src = img.src.replace(/bookmarked/, 'unbookmarked');
		img.alt = "[+B]";
	}

	return false;
}

/* toggle a saved-search from being shown in menu or not */
function toggleSSmenu(e)
{
	new Ajax.Request(e.href + '&noret=1', {method: 'get'});

	var img = e.firstChild;
	if (e.href.match(/set=1/))
	{
		e.href = e.href.replace(/set=1/, 'set=0');
		e.title = "Currently shown in sidebox; click to hide";
		img.src = img.src.replace(/crossred/, 'tickgreen');
		img.alt = "[-S]";
	}
	else
	{
		e.href = e.href.replace(/set=0/, 'set=1');
		e.title = "Not shown in sidebox; click to show";
		img.src = img.src.replace(/tickgreen/, 'crossred');
		img.alt = "[+S]";
	}

	return false;
}

/* toggle a saved-search from being shown in menu or not */
function toggleSSwatchdog(e)
{
	new Ajax.Request(e.href + '&noret=1', {method: 'get'});

	var img = e.firstChild;
	if (e.href.match(/set=1/))
	{
		e.href = e.href.replace(/set=1/, 'set=0');
		e.title = "Monitored by Watchdog; click to disable";
		img.src = img.src.replace(/crossred/, 'tickgreen');
		img.alt = "[-W]";
	}
	else
	{
		e.href = e.href.replace(/set=0/, 'set=1');
		e.title = "Not monitored by Watchdog; click to monitor";
		img.src = img.src.replace(/tickgreen/, 'crossred');
		img.alt = "[+W]";
	}

	return false;
}


function confirmURL(msg, url)
{
	if (window.confirm(msg))
	{
		window.location = url;
	}
}

function toggleBlockVis(id)
{
	var e = $(id);
	Element.visible(e) ? Element.hide(e) : Element.show(e);

	var v = Element.visible(e) ? 1 : 0;
	new Ajax.Request('/backend/storevis/?e=' + id + '&v=' + v, {method: 'get'});
}

var imgPlus = new Image();
var imgMinus = new Image();
imgPlus.src = '/m/i/i/plus.png';
imgMinus.src = '/m/i/i/minus.png';

function flipPlusMinusIcon(id)
{
	var e = $(id);
	if ( e.src.indexOf('plus.png') == -1 ) {
		e.src = imgPlus.src;
	} else {
		e.src = imgMinus.src;
	}
}

function selectSearchBox()
{
	if (window.location.href.indexOf("#") == -1)
	{
		Field.activate('qs_q');
	}

}

var menu_vis = 1;
function toggleMenu()
{
	if (menu_vis)
	{
		$('sidebar').style.display = 'none';
		$('content').style.marginLeft = '0';
		menu_vis = 0;
	}
	else
	{
		$('sidebar').style.display = 'block';
		$('content').style.marginLeft = '152px';
		menu_vis = 1;
	}
}

function prefsShow(id)
{
	prefsPages.each(function(p, x) { $(p).hide(); });
	$(id).show();
}

function onclickcreatePopup(id,url,offx,offy)
{
	return createPopup(id,url,offx,offy,0);
}

function onkeydowncreatePopup(id,url,offx,offy)
{
	return reatePopup(id,url,offx,offy,0);
}

function onmouseovercreatePopup(id,url,offx,offy)
{
	return createPopup(id,url,offx,offy,200);
}


var popup_cache = new Array();
function createPopup(id, url, offx, offy, opendelay)
{
	if (popup_cache[id])
	{
		return showInfoBox(id, url, offx, offy, opendelay);
	}

	popup_cache[id] = new Element("div", { 'id': id, 'class': 'popup' } );
	popup_cache[id].innerHTML = "<p>Wait, please &hellip;</p>";
	$('content').insert(popup_cache[id]);

	popup_cache[id].observe("mouseover",
	    function(event) { showInfoBox(id, null); } );

	popup_cache[id].observe("mouseout",
	    function(event) { hideInfoBox(id); } );

	return showInfoBox(id, url, offx, offy, opendelay);
}