var XHTML_NS = "http://www.w3.org/1999/xhtml";
var refBlock = document.createElementNS(XHTML_NS, "div");

refBlock.timeoutID;
refBlock.setAttribute("id", "refBlock");
refBlock.setAttribute("style",
        "display: none;" +
        "position: absolute;" +
        "border: 0.0625em solid #000;" +
        "padding: 0.5125em;" +
        "background: #deffff");
refBlock.addEventListener("mouseover", persist, false);
refBlock.addEventListener("mouseout", delayHide, false);

function persist(evt)
{
    clearTimeout(refBlock.timeoutID);
}

function delayHide(evt)
{
    refBlock.timeoutID = setTimeout("refBlock.style.display = 'none';", 250);
}

function showReference(htmlElem)
{
    // if it's already visible, let it stay visible
    persist();

    var x = 0;
    var y = 0;

    // get the location of the triggering element
    for (var obj = htmlElem; obj != null; obj = obj.offsetParent)
    {
        x += obj.offsetLeft;
        y += obj.offsetTop;
    }

    // show the reference
    refBlock.style.display = "";

    // right of link, top aligned with top of element or
    // bottom aligned with body bottom, whichever is higher
    if (x + htmlElem.offsetWidth + refBlock.offsetWidth <=
            document.body.scrollWidth)
    {
        refBlock.style.left = (x + htmlElem.offsetWidth) + "px";
        refBlock.style.top = Math.min(y,
                document.body.scrollHeight - refBlock.offsetHeight) + "px";
        return;
    }

    // below link, left edge aligned with left edge of element or
    // right edge aligned with body right edge, whichever is leftmost
    if (y + htmlElem.offsetHeight + refBlock.offsetHeight <=
            document.body.scrollHeight)
    {
        refBlock.style.left = Math.min(x,
                document.body.scrollWidth - refBlock.offsetWidth) + "px";
        refBlock.style.top = (y + htmlElem.offsetHeight) + "px";
        return;
    }

    // left of link, top aligned with top of element or
    // bottom aligned with body bottom, whichever is higher
    if (x >= refBlock.offsetWidth)
    {
        refBlock.style.left = (x - refBlock.offsetWidth) + "px";
        refBlock.style.top = Math.min(y,
                document.body.scrollHeight - refBlock.offsetHeight) + "px";
        return;
    }

    // above link, left edge aligned with left edge of element or
    // right edge aligned with body right edge, whichever is leftmost
    if (y >= refBlock.offsetHeight)
    {
        refBlock.style.left = Math.min(x,
                document.body.scrollWidth - refBlock.offsetWidth) + "px";
        refBlock.style.top = (y - refBlock.offsetHeight) + "px";
        return;
    }

    // when all else fails
    refBlock.style.left = Math.max(
            document.body.scrollWidth - refBlock.offsetWidth, 0) + "px";
    refBlock.style.top = Math.max(
            document.body.scrollHeight - refBlock.offsetHeight, 0) + "px";
}

function initRefBlock()
{
    document.body.appendChild(refBlock);
}
