export class GDispatcher {
    /**
     * 事件回调池
     */
    private static callbackPool: any = {};

    /**
     * 事件作用域池
     */
    private static thisObjPool: any = {};

    /**
     * 
     * @param name 事件名
     * @param callback 回调
     * @param thisObj 作用域
     */
    public static addEvent(name: string, callback, thisObj?: any): void {
        if (!this.callbackPool[name]) {
            this.callbackPool[name] = [];
            this.thisObjPool[name] = [];
        }

        const index: number = this.callbackPool[name].indexOf(callback);
        if (index != -1) {
            this.callbackPool[name][index] = callback;
            this.thisObjPool[name][index] = thisObj;
        } else {
            this.callbackPool[name].push(callback);
            this.thisObjPool[name].push(thisObj);
        }
    }

    /**
     * 
     * @param name 事件名
     * @param callback 回调
     * @param thisObj 作用域
     */
    public static removeEvent(name: string, callback, thisObj?: any): void {
        if (this.callbackPool[name]) {
            var len = this.callbackPool[name].length;
            for (let i = len - 1; i >= 0; i--) {
                if (this.callbackPool[name][i] === callback && this.thisObjPool[name][i] == thisObj) {
                    this.callbackPool[name].splice(i, 1);
                    this.thisObjPool[name].splice(i, 1);
                }
            }
            // const index: number = this.callbackPool[name].indexOf(callback);
            // if (index != -1) {
            //     this.callbackPool[name].splice(index, 1);
            //     this.thisObjPool[name].splice(index, 1);
            // }
        }
    }

    /**
     * 派发事件
     * @param name 事件名
     * @param args 任意参数
     */
    public static dispatchEvent(name: string, ...args): void {
        const callbacks: Function[] = this.callbackPool[name];
        const thisObjs: any = this.thisObjPool[name];
        if (callbacks) {
            let i = 0;
            const len: number = callbacks.length;
            for (i; i < len; i++) {
                callbacks[i].apply(thisObjs[i], args);
            }
        }
    }
}