export default class ListenerHandler extends EventTarget {
	constructor() {
		super();
		this.listeners = {};
	}

	addEventListener(type, cb, options) {
		// add the listener type to listeners object
		if (!(type in this.listeners)) this.listeners[type] = [];

		const stack = this.listeners[type];

		// push the callback
		stack.push({ cb, options });

		const replaceableIndexes = [];

		// check for any replaceable callbacks
		stack.forEach((element, index) => {
			if (element.options && element.options.replaceable)
				replaceableIndexes.push(index);
		});

		// should always be 1 replaceable callback remaining
		replaceableIndexes.pop();

		// delete the other replaceable callbacks
		replaceableIndexes.forEach(index => stack.splice(index, 1));
	}

	// eslint-disable-next-line consistent-return
	removeEventListener(type, cb) {
		if (!(type in this.listeners)) return true; // event type doesn't exist

		const stack = this.listeners[type];

		stack.forEach((element, index) => {
			if (element.cb === cb) stack.splice(index, 1);
		});
	}

	dispatchEvent(event) {
		if (!(event.type in this.listeners)) return true; // event type doesn't exist

		const stack = this.listeners[event.type].slice();

		stack.forEach(element => element.cb.call(this, event));

		return !event.defaultPrevented;
	}
}
