/// <reference path="leaf.ts" />
var Leaf;
(function (Leaf) {
    var EventEmitter = (function () {
        function EventEmitter() {
            this.events = {};
        }
        EventEmitter.prototype.addEventListener = function (event, handler) {
            this.on(event, handler);
            return this;
        };
        EventEmitter.prototype.on = function (event, handler) {
            var ehs = this.getOrCreateEventHandlers(event);
            ehs.push({
                once: false,
                handler: handler
            });
            return this;
        };
        EventEmitter.prototype.once = function (event, handler) {
            var ehs = this.getOrCreateEventHandlers(event);
            ehs.push({
                once: true,
                handler: handler
            });
            return this;
        };
        EventEmitter.prototype.listenByOnce = function (who, event, handler) {
            var ehs = this.getOrCreateEventHandlers(event);
            ehs.push({
                owner: who,
                once: true,
                handler: handler
            });
            return this;
        };
        EventEmitter.prototype.listenBy = function (who, event, handler) {
            var ehs = this.getOrCreateEventHandlers(event);
            ehs.push({
                owner: who,
                once: false,
                handler: handler
            });
            return this;
        };
        EventEmitter.prototype.stopListenBy = function (who, event, handler) {
            if (event) {
                var ehs = this.getOrCreateEventHandlers(event);
                ehs = ehs.filter(function (eh) {
                    if (eh.owner === who && (!handler || handler === eh.handler))
                        return false;
                    return true;
                });
                this.events[event] = ehs;
            }
            else {
                if (!who) {
                    return;
                }
                var _loop_1 = function (name_1) {
                    var ehs = this_1.events[name_1];
                    var change = false;
                    ehs = ehs.filter(function (eh) {
                        if (eh.owner === who && (!handler || handler === eh.handler)) {
                            change = true;
                            return false;
                        }
                        return true;
                    });
                    if (change) {
                        this_1.events[name_1] = ehs;
                    }
                };
                var this_1 = this;
                for (var name_1 in this.events) {
                    _loop_1(name_1);
                }
            }
            return this;
        };
        EventEmitter.prototype.removeEventListener = function (event, handler) {
            if (!event) {
                this.events = {};
            }
            if (!handler) {
                this.events[event] = [];
                return this;
            }
            var ehs = this.getOrCreateEventHandlers(event);
            var change = false;
            ehs = ehs.filter(function (eh) {
                if (!eh.owner && (!handler || handler === eh.handler)) {
                    change = true;
                    return false;
                }
                return true;
            });
            if (change) {
                this.events[event] = ehs;
            }
            return this;
        };
        EventEmitter.prototype.emit = function (event) {
            var values = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                values[_i - 1] = arguments[_i];
            }
            var todo = [];
            var ehs = this.getOrCreateEventHandlers(event);
            var change = false;
            ehs = ehs.filter(function (eh) {
                if (eh.owner)
                    todo.push(eh.handler.bind(eh.owner));
                else
                    todo.push(eh.handler);
                if (eh.once) {
                    change = true;
                    return false;
                }
                return true;
            });
            if (change) {
                this.events[event] = ehs;
            }
            todo.forEach(function (handler) {
                handler.apply(void 0, values);
            });
            return this;
        };
        EventEmitter.prototype.getOrCreateEventHandlers = function (event) {
            var ehs = this.events[event];
            if (!ehs) {
                ehs = this.events[event] = [];
            }
            return ehs;
        };
        return EventEmitter;
    }());
    Leaf.EventEmitter = EventEmitter;
})(Leaf || (Leaf = {}));
//# sourceMappingURL=events.js.map