// ----- configuration values -----

var hiddenBoxLockTime = 500;
var hiddenBoxDecreaseLockTime = 10;
var hiddenBoxDefaultLeft = 20;
var hiddenBoxDefaultTop = -20;

// ----- the singleton pattern -----

HiddenBox.instances = new Array();

HiddenBox.getInstance = function(boxNodeId)
{
    if (HiddenBox.instances[boxNodeId] == null)
    {
        HiddenBox.instances[boxNodeId] = new HiddenBox(boxNodeId);
    }

    return HiddenBox.instances[boxNodeId];
}

HiddenBox.getAllInstances = function()
{
    return HiddenBox.instances;
}


// ----- the class -----

function HiddenBox(boxNodeId)
{
    this.boxNodeId = boxNodeId;

    var boxNode = document.getElementById(boxNodeId);

    if (boxNode != null)
    {
        ObjectUtil.call(this, boxNode);
    }
    else
    {
        alert("Could not find box with Id: " + boxNodeId);
    }

    this.hiddenBoxLockTime = hiddenBoxLockTime;
    this.openerLocked = false;
    this.boxLocked = false;
}

HiddenBox.prototype = new ObjectUtil();
HiddenBox.prototype.display = _hiddenBox_Display;
HiddenBox.prototype.hide = _hiddenBox_Hide;
HiddenBox.prototype.isDisplayed = _hiddenBox_isDisplayed;
HiddenBox.prototype.openerLock = _hiddenBox_OpenerLock;
HiddenBox.prototype.openerUnLock = _hiddenBox_OpenerUnLock;
HiddenBox.prototype.boxLock = _hiddenBox_BoxLock;
HiddenBox.prototype.boxUnLock = _hiddenBox_BoxUnLock;


function _hiddenBox_Display(opener, left, top)
{
    var allHiddenBoxes = HiddenBox.getAllInstances();

    for (var hiddenBoxId in allHiddenBoxes)
    {
        var hiddenBox = allHiddenBoxes[hiddenBoxId];

        if (typeof hiddenBox == "object")
        {
            hiddenBox.hide(true);
        }
    }

    this.hiddenBoxLockTime = hiddenBoxLockTime;

    if (! this.isDisplayed())
    {
        this.getObject().onmouseover =
            new Function("", "HiddenBox.getInstance(this.id).boxLock();");
        this.getObject().onmouseout =
            new Function("", "HiddenBox.getInstance(this.id).boxUnLock();");

        if (left == null)
        {
            left = hiddenBoxDefaultLeft;
        }

        if (top == null)
        {
            top = hiddenBoxDefaultTop;
        }

        this.getObject().style.left = mousePositionX + left;
        this.getObject().style.top = mousePositionY + top;
        this.getObject().style.display = "block";

        window.setTimeout(
            "HiddenBox.getInstance('" + this.boxNodeId + "').hide()",
            hiddenBoxDecreaseLockTime);
    }

    if (opener != null)
    {
        opener.onmouseout = new Function("",
            "HiddenBox.getInstance('" + this.boxNodeId + "').openerUnLock();");

        this.openerLock();
    }
}

function _hiddenBox_Hide(forceHide)
{
    if (! this.boxLocked && ! this.openerLocked)
    {
        this.hiddenBoxLockTime -= hiddenBoxDecreaseLockTime;
    }

    if (this.hiddenBoxLockTime <= 0 ||
        (forceHide !== null && forceHide == true))
    {
        this.getObject().style.display = "none";

        this.hiddenBoxLockTime = 0;
    }
    else
    {
        window.setTimeout(
            "HiddenBox.getInstance('" + this.boxNodeId + "').hide()",
            hiddenBoxDecreaseLockTime);
    }
}

function _hiddenBox_isDisplayed()
{
    return this.getObject().style.display == "block";
}

function _hiddenBox_OpenerLock()
{
    this.openerLocked = true;
}

function _hiddenBox_OpenerUnLock()
{
    this.openerLocked = false;
}

function _hiddenBox_BoxLock()
{
    this.boxLocked = true;
}

function _hiddenBox_BoxUnLock()
{
    this.boxLocked = false;
}
