Notifier = new Object();
Notifier._objects = new Array();

Notifier.addOnloadListener = function(action)
{
    if (window.onload && (!window.onload._listenerId))
    {
        var previous = window.onload;
        window.onload = null;
        Notifier.addListener(window, "onload", previous);
    }

    Notifier.addListener(window, "onload", action);
}

Notifier.addListener = function(source, name, action)
{
    if (typeof(source) == 'string')
    {
        source = document.getElementById(source);
    }
    listener = Notifier._getListener(source, name, true);
    listener.list[listener.list.length] = action;
}

Notifier._getListener = function(source, name, create)
{
    var listener = null;

    if (source[name])
    {
        var id = source[name]._listenerId;
        listener = Notifier._objectById(id);
    }
    else if (create)
    {
        listener = Notifier._createListener(source, name);
    }

    return(listener);
}

Notifier._createListener = function(source, name, id)
{
   var listener = new Object();
   listener.list = new Array()
   listener.single = null;
   var id = Notifier._assignId(listener);
   var handler = Notifier._addClosure(id);
   source[name] = handler;
   source[name]._listenerId = id;

   return(listener);
}

Notifier._addClosure = function(id)
{
    var closure = function(arg)
    {
        var listener = Notifier._objectById(id);
        var list = listener.list;
        for (var i = 0; i < list.length; i++)
        {
            var callback = list[i];
            if (callback)
            {
                if (typeof(callback) == 'string')
                {
                    eval(callback);
                }
                else
                {
                    callback(arg, this);
                }
            }
        }
        if (listener.single)
        {
            var callback = listener.single;
            if (typeof(callback) == 'string')
            {
                eval(callback);
            }
            else
            {
                callback(arg, this);
            }
        }
    }

    return(closure);
}

Notifier._assignId = function(obj)
{
    var id = Notifier._objects.length;
    Notifier._objects[id] = obj;
    return id;
}

Notifier._objectById = function(id)
{
    return(Notifier._objects[id]);
}
