import { EventDispatcher } from "./EventDispatcher";
import { Listener, ListenerParameter } from "./listener";

export class EventDispatcherImpl implements EventDispatcher {
    /** Contains listeners from wrapped callbacks. */
    private listeners: { [key: string]: Listener[] };

    /** Contains callbacks from SFS2X. */
    private callbacks: Array<[SFS2X.SFSEvent, (params: ListenerParameter) => void]>;

    public constructor(private readonly dispatcher: SFS2X.EventDispatcher) {
        this.listeners = {};
        this.callbacks = [];
    }

    private getListeners(type: SFS2X.SFSEvent): Listener[] {
        if (this.listeners[type]) {
            return this.listeners[type];
        }
        const callback = (params: ListenerParameter) => {
            const listeners = this.listeners[type];
            listeners.forEach(item => item.onEvent(params));
        };
        this.callbacks.push([type, callback]);
        this.dispatcher.addEventListener(type, callback);
        this.listeners[type] = [];
        return this.listeners[type];
    }

    public addListener(listener: Listener): boolean {
        const listeners = this.getListeners(listener.type);
        const index = listeners.indexOf(listener);
        if (index !== -1) {
            return false;
        }
        listeners.push(listener);
        return true;
    }

    public removeListener(listener: Listener): boolean {
        const listeners = this.getListeners(listener.type);
        const index = listeners.indexOf(listener);
        if (index === -1) {
            return false;
        }
        listeners.splice(index, 1);
        return true;
    }

    public destroy(): void {
        this.callbacks.forEach(([type, callback]) => this.dispatcher.removeEventListener(type, callback));
        this.listeners = {};
    }
}