/*
 * JavaScript Custom Event Dispatcher
 * Copyright (c) 2010 Rafael Lúcio (poste9@gmail.com)
 * licensed under the GPL (GPL-LICENSE.txt) license.
 */
var EventDispatcher = function() {
    var events = {};

    function orderByPriority(a,b) {return b.priority - a.priority;}
    /**
     * Checks whether the Event object has any listeners
     * registered for a specific type of event.
     * @param type
     */
    this.hasEventListener = function(type) {
        return (typeof events[type] != 'undefined');
    }
    /**
     * Registers an event listener object.
     * @param type <code>CollectionEvent.ELEMENT_CHANGED</code>
     * @param callback
     * @param priority
     * @param scope
     */
    this.addEventListener = function(type, callback, priority, scope) {
        (!priority)&&(priority = 0);
        (typeof events[type] == 'undefined')&&(events[type]=[]);
        var eventObj = {};
        eventObj.type = type;
        eventObj.callback = callback;
        eventObj.priority = parseInt(priority);
        eventObj.scope = scope || this;
        events[type].push(eventObj);
        events[type].sort(orderByPriority);
    }

    /**
     * Removes a listener from the Event object.
     * @param type
     * @param callback
     */
    this.removeEventListener = function(type, callback) {
        var l = events[type].length;
        for(var i = 0; i < l; i++) {
            if (events[type][i].callback == callback) {
                events[type].splice(i, 1);
            }
        }
    }
    /**
     * Dispatches an event into the event flow.
     */
    this.dispatchEvent = function(event) {
        if (typeof events[event.type] == 'undefined') return;
        var l = events[event.type].length;
        for(var i = 0; i < l; i++) {
            event.target = event.currentTarget = this;
            event.toString = function() {
                return "[Event {type="+event.type+"} ]";
            }
            events[event.type][i].callback.apply(
                events[event.type][i].scope, [event]
            );
        }
    }
}
