export class TableEventRelay {
    constructor(vtableSheet) {
        this._tableEventMap = {}, this.boundSheets = new Set, this.cleanupCallbacks = new Map, 
        this.vtableSheet = vtableSheet;
    }
    onTableEvent(type, callback) {
        this._tableEventMap[type] || (this._tableEventMap[type] = []);
        this._tableEventMap[type].some((item => item.callback === callback)) || (this._tableEventMap[type].push({
            callback: callback,
            wrappedCallbacks: new Map
        }), this.bindToAllSheets(type));
    }
    offTableEvent(type, callback) {
        if (this._tableEventMap[type]) if (callback) {
            const index = this._tableEventMap[type].findIndex((h => h.callback === callback));
            if (index >= 0) {
                const handler = this._tableEventMap[type][index];
                this.cleanupWrappedCallbacks(handler, type), this._tableEventMap[type].splice(index, 1), 
                0 === this._tableEventMap[type].length && (delete this._tableEventMap[type], this.unbindFromAllSheets(type));
            }
        } else {
            this._tableEventMap[type].forEach((handler => {
                this.cleanupWrappedCallbacks(handler, type);
            })), delete this._tableEventMap[type], this.unbindFromAllSheets(type);
        }
    }
    cleanupWrappedCallbacks(handler, eventType) {
        handler.wrappedCallbacks.forEach(((wrappedCallback, sheetKey) => {
            const worksheet = this.vtableSheet.workSheetInstances.get(sheetKey);
            (null == worksheet ? void 0 : worksheet.tableInstance) && worksheet.tableInstance.off(eventType, wrappedCallback);
        })), handler.wrappedCallbacks.clear();
    }
    bindSheetEvents(sheetKey, tableInstance) {
        if (this.boundSheets.has(sheetKey)) return;
        for (const eventType in this._tableEventMap) this.bindSheetEvent(sheetKey, tableInstance, eventType);
        this.boundSheets.add(sheetKey);
        this.cleanupCallbacks.set(sheetKey, (() => {
            this.unbindSheetEvents(sheetKey, tableInstance), this.boundSheets.delete(sheetKey), 
            this.cleanupCallbacks.delete(sheetKey);
        }));
    }
    bindSheetEvent(sheetKey, tableInstance, eventType) {
        (this._tableEventMap[eventType] || []).forEach((handler => {
            if (handler.wrappedCallbacks.has(sheetKey)) {
                const oldCallback = handler.wrappedCallbacks.get(sheetKey);
                tableInstance.off(eventType, oldCallback);
            }
            const wrappedCallback = (...args) => {
                const enhancedEvent = Object.assign({
                    sheetKey: sheetKey
                }, args[0]);
                handler.callback(enhancedEvent);
            };
            handler.wrappedCallbacks.set(sheetKey, wrappedCallback), tableInstance.on(eventType, wrappedCallback);
        }));
    }
    bindToAllSheets(eventType) {
        this.vtableSheet.workSheetInstances.forEach(((worksheet, sheetKey) => {
            worksheet.tableInstance && this.bindSheetEvent(sheetKey, worksheet.tableInstance, eventType);
        }));
    }
    unbindSheetEvents(sheetKey, tableInstance) {
        for (const eventType in this._tableEventMap) {
            (this._tableEventMap[eventType] || []).forEach((handler => {
                const wrappedCallback = handler.wrappedCallbacks.get(sheetKey);
                wrappedCallback && (tableInstance.off(eventType, wrappedCallback), handler.wrappedCallbacks.delete(sheetKey));
            }));
        }
        this.boundSheets.delete(sheetKey), this.cleanupCallbacks.delete(sheetKey);
    }
    unbindFromAllSheets(eventType) {
        this.vtableSheet.workSheetInstances.forEach(((worksheet, sheetKey) => {
            if (worksheet.tableInstance) {
                (this._tableEventMap[eventType] || []).forEach((handler => {
                    const wrappedCallback = handler.wrappedCallbacks.get(sheetKey);
                    wrappedCallback && (worksheet.tableInstance.off(eventType, wrappedCallback), handler.wrappedCallbacks.delete(sheetKey));
                }));
            }
        }));
    }
    getRegisteredEventTypes() {
        return Object.keys(this._tableEventMap);
    }
    getListenerCount(type) {
        var _a;
        return (null === (_a = this._tableEventMap[type]) || void 0 === _a ? void 0 : _a.length) || 0;
    }
    clearAllListeners() {
        for (const cleanup of this.cleanupCallbacks.values()) cleanup();
        this.vtableSheet.workSheetInstances.forEach(((worksheet, sheetKey) => {
            worksheet.tableInstance && this.unbindSheetEvents(sheetKey, worksheet.tableInstance);
        })), this._tableEventMap = {}, this.boundSheets.clear(), this.cleanupCallbacks.clear();
    }
    destroy() {
        this.clearAllListeners();
    }
}
//# sourceMappingURL=table-event-relay.js.map