import { eventOptionsKey } from './event-option-key';
var TargetEventHandlers = (function () {
    function TargetEventHandlers(target) {
        this.target = target;
        this.events = {};
    }
    TargetEventHandlers.prototype.add = function (eventName, listener, options) {
        var _this = this;
        var eventHandlers = this.getEventHandlers(eventName, options);
        ensureCanMutateNextEventHandlers(eventHandlers);
        var nextHandlers = eventHandlers.nextHandlers;
        if (nextHandlers.length === 0) {
            eventHandlers.handleEvent = this.handleEvent.bind(this, eventName, options);
            var target = this.target;
            target.addEventListener(eventName, eventHandlers.handleEvent, options);
        }
        if (nextHandlers.indexOf(listener) === -1) {
            nextHandlers.push(listener);
        }
        var isSubscribed = true;
        var unsubscribe = function () {
            if (!isSubscribed) {
                return;
            }
            isSubscribed = false;
            ensureCanMutateNextEventHandlers(eventHandlers);
            var nextHandlers = eventHandlers.nextHandlers;
            var index = nextHandlers.indexOf(listener);
            nextHandlers.splice(index, 1);
            if (nextHandlers.length === 0) {
                var target = _this.target;
                if (target) {
                    target.removeEventListener(eventName, eventHandlers.handleEvent, options);
                }
                eventHandlers.handleEvent = undefined;
            }
        };
        return unsubscribe;
    };
    TargetEventHandlers.prototype.getEventHandlers = function (eventName, options) {
        var key = eventName + " " + eventOptionsKey(options);
        if (!this.events[key]) {
            this.events[key] = {
                handlers: [],
                handleEvent: undefined,
            };
            this.events[key].nextHandlers = this.events[key].handlers;
        }
        return this.events[key];
    };
    TargetEventHandlers.prototype.handleEvent = function (eventName, options, event) {
        var eventHandlers = this.getEventHandlers(eventName, options);
        eventHandlers.handlers = eventHandlers.nextHandlers;
        eventHandlers.handlers.forEach(function (handler) {
            handler(event);
        });
    };
    return TargetEventHandlers;
}());
export { TargetEventHandlers };
function ensureCanMutateNextEventHandlers(eventHandlers) {
    if (eventHandlers.handlers === eventHandlers.nextHandlers) {
        eventHandlers.nextHandlers = eventHandlers.handlers.slice();
    }
}
