'use strict';

var events = require('../../../../../../../_virtual/events2.js');
var ral = require('./ral.js');

var hasRequiredEvents;

function requireEvents () {
	if (hasRequiredEvents) return events.__exports;
	hasRequiredEvents = 1;
	/* --------------------------------------------------------------------------------------------
	 * Copyright (c) Microsoft Corporation. All rights reserved.
	 * Licensed under the MIT License. See License.txt in the project root for license information.
	 * ------------------------------------------------------------------------------------------ */
	Object.defineProperty(events.__exports, "__esModule", { value: true });
	events.__exports.Emitter = events.__exports.Event = void 0;
	const ral_1 = ral.__require();
	var Event;
	(function (Event) {
	    const _disposable = { dispose() { } };
	    Event.None = function () { return _disposable; };
	})(Event || (events.__exports.Event = Event = {}));
	class CallbackList {
	    add(callback, context = null, bucket) {
	        if (!this._callbacks) {
	            this._callbacks = [];
	            this._contexts = [];
	        }
	        this._callbacks.push(callback);
	        this._contexts.push(context);
	        if (Array.isArray(bucket)) {
	            bucket.push({ dispose: () => this.remove(callback, context) });
	        }
	    }
	    remove(callback, context = null) {
	        if (!this._callbacks) {
	            return;
	        }
	        let foundCallbackWithDifferentContext = false;
	        for (let i = 0, len = this._callbacks.length; i < len; i++) {
	            if (this._callbacks[i] === callback) {
	                if (this._contexts[i] === context) {
	                    // callback & context match => remove it
	                    this._callbacks.splice(i, 1);
	                    this._contexts.splice(i, 1);
	                    return;
	                }
	                else {
	                    foundCallbackWithDifferentContext = true;
	                }
	            }
	        }
	        if (foundCallbackWithDifferentContext) {
	            throw new Error('When adding a listener with a context, you should remove it with the same context');
	        }
	    }
	    invoke(...args) {
	        if (!this._callbacks) {
	            return [];
	        }
	        const ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0);
	        for (let i = 0, len = callbacks.length; i < len; i++) {
	            try {
	                ret.push(callbacks[i].apply(contexts[i], args));
	            }
	            catch (e) {
	                // eslint-disable-next-line no-console
	                (0, ral_1.default)().console.error(e);
	            }
	        }
	        return ret;
	    }
	    isEmpty() {
	        return !this._callbacks || this._callbacks.length === 0;
	    }
	    dispose() {
	        this._callbacks = undefined;
	        this._contexts = undefined;
	    }
	}
	class Emitter {
	    constructor(_options) {
	        this._options = _options;
	    }
	    /**
	     * For the public to allow to subscribe
	     * to events from this Emitter
	     */
	    get event() {
	        if (!this._event) {
	            this._event = (listener, thisArgs, disposables) => {
	                if (!this._callbacks) {
	                    this._callbacks = new CallbackList();
	                }
	                if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {
	                    this._options.onFirstListenerAdd(this);
	                }
	                this._callbacks.add(listener, thisArgs);
	                const result = {
	                    dispose: () => {
	                        if (!this._callbacks) {
	                            // disposable is disposed after emitter is disposed.
	                            return;
	                        }
	                        this._callbacks.remove(listener, thisArgs);
	                        result.dispose = Emitter._noop;
	                        if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {
	                            this._options.onLastListenerRemove(this);
	                        }
	                    }
	                };
	                if (Array.isArray(disposables)) {
	                    disposables.push(result);
	                }
	                return result;
	            };
	        }
	        return this._event;
	    }
	    /**
	     * To be kept private to fire an event to
	     * subscribers
	     */
	    fire(event) {
	        if (this._callbacks) {
	            this._callbacks.invoke.call(this._callbacks, event);
	        }
	    }
	    dispose() {
	        if (this._callbacks) {
	            this._callbacks.dispose();
	            this._callbacks = undefined;
	        }
	    }
	}
	events.__exports.Emitter = Emitter;
	Emitter._noop = function () { };
	return events.__exports;
}

exports.__require = requireEvents;
