export interface IEmitter {
    on: (name: string, callback: any) => void;
    off: (name: string, callback: any) => void;
    emit: (name: string, args?: any) => void;
    register: (callback: any) => void;
    unRegister: (callback: any) => void;
    removeEvent(): void;
    removeEvents(): void;
}

interface IListeners extends Array<any> {
    [index: number]: any;
}

class Emitter implements IEmitter {
    public listeners: IListeners = [];
    public onListeners: any = {};

    constructor() {
        return;
    }

    public on = (name: string, callback: any) => {
        if (!this.onListeners[name]) {
            this.onListeners[name] = [];
        }
        this.onListeners[name].push(callback);
    };

    public off = (name: string, callback: any) => {
        if (!this.onListeners[name]) {
            return;
        }
        let i: number = this.onListeners[name].indexOf(callback);
        if (i > -1) {
            this.onListeners[name].splice(i, 1);
        }
    };

    public register = (callback: any): void => {
        this.listeners.push(callback);
    };

    public unRegister(callback: any): void {
        let i: number = this.listeners.indexOf(callback);
        if (i > -1) {
            this.listeners.splice(i, 1);
        }
    }

    public emit(name: string, args?: any): void {
        this.listeners.forEach(cb => {
            cb(name, args);
        });
        if (this.onListeners[name]) {
            let length: number = this.onListeners[name].length * 1;
            for (let i = 0; i < length; i++) {
                if (this.onListeners[name] && this.onListeners[name][i]) {
                    this.onListeners[name][i](args);
                }
            }
        }
    }

    public removeEvent(): void {
        this.listeners = [];
        this.onListeners = {};
    }
    public removeEvents(): void {
        this.removeEvent();
    }
}
export default Emitter;
