"use strict";

var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
    void 0 === k2 && (k2 = k);
    var desc = Object.getOwnPropertyDescriptor(m, k);
    desc && !("get" in desc ? !m.__esModule : desc.writable || desc.configurable) || (desc = {
        enumerable: !0,
        get: function() {
            return m[k];
        }
    }), Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
    void 0 === k2 && (k2 = k), o[k2] = m[k];
}), __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function(o, v) {
    Object.defineProperty(o, "default", {
        enumerable: !0,
        value: v
    });
} : function(o, v) {
    o.default = v;
}), __importStar = this && this.__importStar || function(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (null != mod) for (var k in mod) "default" !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
    return __setModuleDefault(result, mod), result;
}, __rest = this && this.__rest || function(s, e) {
    var t = {};
    for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
    if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
        var i = 0;
        for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
    }
    return t;
};

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.SubTableManager = void 0;

const VTable = __importStar(require("@visactor/vtable")), utils_1 = require("./utils");

class SubTableManager {
    constructor(table, enableCheckboxCascade = !0) {
        this.table = table, this.enableCheckboxCascade = enableCheckboxCascade, this.timers = new Set, 
        this.columnRangeCache = null;
    }
    saveSubTableCheckboxState(bodyRowIndex, subTable) {
        if (!subTable.stateManager) return;
        const internalProps = (0, utils_1.getInternalProps)(this.table);
        internalProps.subTableCheckboxStates || (internalProps.subTableCheckboxStates = new Map);
        const subTableState = {
            checkedState: Object.fromEntries(Array.from(subTable.stateManager.checkedState.entries()).map((([recordKey, fieldStates]) => [ recordKey, Object.assign({}, fieldStates) ]))),
            headerCheckedState: Object.assign({}, subTable.stateManager.headerCheckedState)
        };
        internalProps.subTableCheckboxStates.set(bodyRowIndex, subTableState);
    }
    restoreSubTableCheckboxState(bodyRowIndex, subTable) {
        var _a;
        let savedState = null === (_a = (0, utils_1.getInternalProps)(this.table).subTableCheckboxStates) || void 0 === _a ? void 0 : _a.get(bodyRowIndex);
        if (subTable.stateManager) {
            if (savedState || (savedState = {
                checkedState: {},
                headerCheckedState: {}
            }), savedState.checkedState && Object.keys(savedState.checkedState).forEach((recordKey => {
                const fieldStates = savedState.checkedState[recordKey];
                subTable.stateManager.checkedState.set(recordKey, fieldStates);
            })), savedState.headerCheckedState && Object.keys(savedState.headerCheckedState).forEach((field => {
                subTable.stateManager.headerCheckedState[field] = savedState.headerCheckedState[field];
            })), this.enableCheckboxCascade) {
                const parentRowIndex = bodyRowIndex + this.table.columnHeaderLevelCount;
                if ((0, utils_1.getRecordByRowIndex)(this.table, bodyRowIndex) && this.table.stateManager) {
                    const parentDataIndex = this.table.getRecordIndexByCell(0, parentRowIndex);
                    if (null != parentDataIndex) {
                        const parentIndexKey = parentDataIndex.toString(), parentCheckedStates = this.table.stateManager.checkedState.get(parentIndexKey);
                        parentCheckedStates && Object.keys(parentCheckedStates).forEach((field => {
                            const parentState = parentCheckedStates[field];
                            if (!0 === parentState || !1 === parentState) {
                                subTable.stateManager.headerCheckedState[field] = parentState;
                                (subTable.records || []).forEach(((record, recordIndex) => {
                                    const indexKey = recordIndex.toString();
                                    let recordStates = subTable.stateManager.checkedState.get(indexKey);
                                    recordStates || (recordStates = {}, subTable.stateManager.checkedState.set(indexKey, recordStates)), 
                                    recordStates[field] = parentState, record[field] = parentState;
                                }));
                            }
                        }));
                    }
                }
            }
            this.safeSetTimeout((() => {
                this.updateSubTableCheckboxVisualState(subTable);
            }), 0);
        }
    }
    safeSetTimeout(callback, delay) {
        const id = setTimeout((() => {
            this.timers.delete(id);
            try {
                callback();
            } catch (error) {}
        }), delay);
        return this.timers.add(id), id;
    }
    cleanupAllTimers() {
        this.timers.forEach((id => clearTimeout(id))), this.timers.clear();
    }
    updateSubTableCheckboxVisualState(subTable, savedState) {
        if (!subTable.stateManager) return;
        const headerStates = (null == savedState ? void 0 : savedState.headerCheckedState) || subTable.stateManager.headerCheckedState, recordStates = (null == savedState ? void 0 : savedState.checkedState) || {};
        Object.keys(headerStates).forEach((field => {
            const headerState = headerStates[field], checkboxCol = (0, utils_1.findCheckboxColumnIndex)(subTable, field);
            if (-1 !== checkboxCol) {
                const headerRow = 0;
                subTable.isHeader(checkboxCol, headerRow) && subTable.scenegraph.updateHeaderCheckboxCellState(checkboxCol, headerRow, headerState);
            }
        })), (null == savedState ? void 0 : savedState.checkedState) ? Object.keys(recordStates).forEach((recordKey => {
            const fieldStates = recordStates[recordKey], recordIndex = Number(recordKey);
            Object.keys(fieldStates).forEach((field => {
                const checkboxState = fieldStates[field], checkboxCol = (0, utils_1.findCheckboxColumnIndex)(subTable, field);
                if (-1 !== checkboxCol) for (let row = subTable.columnHeaderLevelCount; row < subTable.rowCount; row++) {
                    if (subTable.getRecordIndexByCell(checkboxCol, row) === recordIndex) {
                        (0, utils_1.setCellCheckboxStateByAttribute)(checkboxCol, row, checkboxState, subTable);
                        break;
                    }
                }
            }));
        })) : subTable.stateManager.checkedState.forEach(((fieldStates, recordKey) => {
            const recordIndex = Number(recordKey);
            Object.keys(fieldStates).forEach((field => {
                const checkboxState = fieldStates[field], checkboxCol = (0, utils_1.findCheckboxColumnIndex)(subTable, field);
                if (-1 !== checkboxCol) for (let row = subTable.columnHeaderLevelCount; row < subTable.rowCount; row++) {
                    if (subTable.getRecordIndexByCell(checkboxCol, row) === recordIndex) {
                        (0, utils_1.setCellCheckboxStateByAttribute)(checkboxCol, row, checkboxState, subTable);
                        break;
                    }
                }
            }));
        }));
    }
    renderSubTable(bodyRowIndex, childrenData, getDetailConfig) {
        var _a;
        const internalProps = (0, utils_1.getInternalProps)(this.table), record = (0, utils_1.getRecordByRowIndex)(this.table, bodyRowIndex);
        if (!record) return;
        if (!childrenData || 0 === childrenData.length) return;
        const detailConfig = getDetailConfig(record, bodyRowIndex), childViewBox = this.calculateSubTableViewBox(bodyRowIndex, detailConfig);
        if (!childViewBox) return;
        const containerWidth = childViewBox.x2 - childViewBox.x1, containerHeight = childViewBox.y2 - childViewBox.y1, parentOptions = this.table.options, baseSubTableOptions = {
            viewBox: childViewBox,
            canvas: this.table.canvas,
            records: childrenData,
            columns: (null == detailConfig ? void 0 : detailConfig.columns) || [],
            widthMode: "adaptive",
            showHeader: !0,
            canvasWidth: containerWidth,
            canvasHeight: containerHeight,
            theme: parentOptions.theme
        }, _b = detailConfig || {}, {style: _style} = _b, userDetailConfig = __rest(_b, [ "style" ]), subTableOptions = Object.assign(Object.assign({}, baseSubTableOptions), userDetailConfig), subTable = new VTable.ListTable(this.table.container, subTableOptions);
        internalProps.subTableInstances.set(bodyRowIndex, subTable), this.restoreSubTableCheckboxState(bodyRowIndex, subTable);
        const afterRenderHandler = () => {
            internalProps.subTableInstances && internalProps.subTableInstances.has(bodyRowIndex) && subTable.render();
        };
        this.table.on("after_render", afterRenderHandler), subTable.__afterRenderHandler = afterRenderHandler, 
        this.setupScrollEventIsolation(subTable), this.setupUnifiedSelectionManagement(bodyRowIndex, subTable), 
        this.setupSubTableCanvasClipping(subTable, bodyRowIndex), this.setupAntiFlickerMechanism(subTable), 
        this.setupSubTableEventForwarding(bodyRowIndex, subTable), subTable.render(), "auto" === (null === (_a = null == detailConfig ? void 0 : detailConfig.style) || void 0 === _a ? void 0 : _a.height) && this.handleAutoHeightAfterRender(bodyRowIndex, subTable, detailConfig);
    }
    handleAutoHeightAfterRender(bodyRowIndex, subTable, detailConfig) {
        var _a;
        try {
            const actualContentHeight = this.calculateSubTableContentHeight(subTable), [marginTop, , marginBottom] = (0, 
            utils_1.parseMargin)(null === (_a = null == detailConfig ? void 0 : detailConfig.style) || void 0 === _a ? void 0 : _a.margin), totalRequiredHeight = actualContentHeight + marginTop + marginBottom;
            this.onAutoHeightCalculated && this.onAutoHeightCalculated(bodyRowIndex, totalRequiredHeight);
        } catch (error) {}
    }
    calculateSubTableContentHeight(subTable) {
        try {
            const contentHeight = subTable.getAllRowsHeight();
            let frameExtraHeight = 0;
            const theme = subTable.theme;
            if (null == theme ? void 0 : theme.frameStyle) {
                const frameStyle = theme.frameStyle;
                let borderTopWidth = 0, borderBottomWidth = 0;
                if (frameStyle.borderLineWidth) if ("number" == typeof frameStyle.borderLineWidth) borderTopWidth = borderBottomWidth = frameStyle.borderLineWidth; else if (Array.isArray(frameStyle.borderLineWidth)) {
                    const borders = frameStyle.borderLineWidth;
                    borderTopWidth = borders[0] || 0, borderBottomWidth = borders[2] || 0;
                }
                let shadowTopHeight = 0, shadowBottomHeight = 0;
                if (frameStyle.shadowBlur) if ("number" == typeof frameStyle.shadowBlur) shadowTopHeight = shadowBottomHeight = frameStyle.shadowBlur; else if (Array.isArray(frameStyle.shadowBlur)) {
                    const shadows = frameStyle.shadowBlur;
                    shadowTopHeight = shadows[0] || 0, shadowBottomHeight = shadows[2] || 0;
                }
                frameStyle.innerBorder || (frameExtraHeight = borderTopWidth + borderBottomWidth + shadowTopHeight + shadowBottomHeight);
            }
            return contentHeight + frameExtraHeight;
        } catch (error) {
            return 300;
        }
    }
    setAutoHeightCallback(callback) {
        this.onAutoHeightCalculated = callback;
    }
    getColumnRange() {
        if (this.columnRangeCache) return this.columnRangeCache;
        const frozenColCount = this.table.frozenColCount || 0, rightFrozenColCount = this.table.rightFrozenColCount || 0, totalColCount = this.table.colCount;
        let startCol = frozenColCount, endCol = totalColCount - rightFrozenColCount - 1;
        return 0 === frozenColCount && 0 === rightFrozenColCount && (startCol = 0, endCol = totalColCount - 1), 
        startCol >= totalColCount || endCol < startCol ? null : (this.columnRangeCache = {
            startCol: startCol,
            endCol: endCol
        }, this.columnRangeCache);
    }
    calculateSubTableViewBox(bodyRowIndex, detailConfig, height) {
        var _a, _b, _c;
        const rowIndex = bodyRowIndex + this.table.columnHeaderLevelCount, detailRowRect = this.table.getCellRangeRelativeRect({
            col: 0,
            row: rowIndex
        });
        if (!detailRowRect) return null;
        const originalHeight = (null === (_a = (0, utils_1.getInternalProps)(this.table).originalRowHeights) || void 0 === _a ? void 0 : _a.get(bodyRowIndex)) || 0, columnRange = this.getColumnRange();
        if (!columnRange) return null;
        const {startCol: startCol, endCol: endCol} = columnRange, firstColRect = this.table.getCellRangeRelativeRect({
            col: startCol,
            row: rowIndex
        }), lastColRect = this.table.getCellRangeRelativeRect({
            col: endCol,
            row: rowIndex
        });
        if (!firstColRect || !lastColRect) return null;
        const [marginTop, marginRight, marginBottom, marginLeft] = (0, utils_1.parseMargin)(null === (_b = null == detailConfig ? void 0 : detailConfig.style) || void 0 === _b ? void 0 : _b.margin), configHeight = height || ((null === (_c = null == detailConfig ? void 0 : detailConfig.style) || void 0 === _c ? void 0 : _c.height) || 300);
        let actualHeight;
        if (actualHeight = "auto" === configHeight ? 300 : "number" == typeof configHeight ? configHeight : 300, 
        actualHeight <= marginTop + marginBottom) return {
            x1: firstColRect.left + marginLeft,
            y1: detailRowRect.top + originalHeight,
            x2: lastColRect.right - marginRight,
            y2: detailRowRect.top + originalHeight
        };
        const viewBox = {
            x1: firstColRect.left + marginLeft,
            y1: detailRowRect.top + originalHeight + marginTop,
            x2: lastColRect.right - marginRight,
            y2: detailRowRect.top + originalHeight - marginBottom + actualHeight
        };
        return viewBox.x2 <= viewBox.x1 || viewBox.y2 <= viewBox.y1 ? null : viewBox;
    }
    removeSubTable(bodyRowIndex) {
        var _a;
        const internalProps = (0, utils_1.getInternalProps)(this.table), subTable = null === (_a = internalProps.subTableInstances) || void 0 === _a ? void 0 : _a.get(bodyRowIndex);
        if (subTable) {
            if (this.saveSubTableCheckboxState(bodyRowIndex, subTable), this.cleanupSubTableEventHandlers(subTable), 
            "function" == typeof subTable.release) try {
                subTable.release();
            } catch (error) {}
            internalProps.subTableInstances.delete(bodyRowIndex);
        }
    }
    cleanupSubTableEventHandlers(subTable) {
        var _a, _b, _c, _d;
        this.cleanupSubTableEventForwarding(subTable);
        const afterRenderHandler = subTable.__afterRenderHandler;
        afterRenderHandler && (this.table.off("after_render", afterRenderHandler), delete subTable.__afterRenderHandler);
        const selectionHandler = subTable.__selectionHandler;
        selectionHandler && (subTable.off("click_cell", selectionHandler), delete subTable.__selectionHandler);
        const extendedSubTable = subTable;
        (null === (_b = null === (_a = subTable.scenegraph) || void 0 === _a ? void 0 : _a.stage) || void 0 === _b ? void 0 : _b.defaultLayer) && extendedSubTable.__originalRenderMethod && (subTable.scenegraph.stage.defaultLayer.render = extendedSubTable.__originalRenderMethod, 
        delete extendedSubTable.__originalRenderMethod), (null === (_d = null === (_c = subTable.scenegraph) || void 0 === _c ? void 0 : _c.stage) || void 0 === _d ? void 0 : _d.defaultLayer) && extendedSubTable.__originalDrawMethod && (subTable.scenegraph.stage.defaultLayer.draw = extendedSubTable.__originalDrawMethod, 
        delete extendedSubTable.__originalDrawMethod);
        const scrollHandler = extendedSubTable.__scrollHandler;
        scrollHandler && (this.table.off("can_scroll", scrollHandler), delete extendedSubTable.__scrollHandler);
        const subTableScrollHandler = extendedSubTable.__subTableScrollHandler;
        subTableScrollHandler && (subTable.off("can_scroll", subTableScrollHandler), delete extendedSubTable.__subTableScrollHandler);
        const clipInterval = extendedSubTable.__clipInterval;
        clipInterval && (clearInterval(clipInterval), delete extendedSubTable.__clipInterval);
        const antiFlickerHandler = extendedSubTable.__antiFlickerHandler;
        antiFlickerHandler && (this.table.off("after_render", antiFlickerHandler), delete extendedSubTable.__antiFlickerHandler);
        const checkboxHandler = extendedSubTable.__checkboxHandler;
        checkboxHandler && (subTable.off("checkbox_state_change", checkboxHandler), delete extendedSubTable.__checkboxHandler);
    }
    setupScrollEventIsolation(subTable) {
        const isMouseInChildTableArea = event => {
            const rect = this.table.canvas.getBoundingClientRect(), x = event.clientX - rect.left, y = event.clientY - rect.top, currentViewBox = subTable.options.viewBox;
            if (!currentViewBox) return !1;
            return x >= currentViewBox.x1 && x <= currentViewBox.x2 && y >= currentViewBox.y1 && y <= currentViewBox.y2;
        }, shouldSubTableScroll = event => {
            if (!(event && event instanceof WheelEvent)) return !0;
            const deltaY = event.deltaY, isScrollingDown = deltaY > 0, isScrollingUp = deltaY < 0;
            return !(subTable.scrollTop <= 0 && isScrollingUp) && (!(() => {
                const totalContentHeight = subTable.getAllRowsHeight(), viewportHeight = subTable.scenegraph.height, scrollTop = subTable.scrollTop;
                if (totalContentHeight <= viewportHeight) return !0;
                const maxScrollTop = totalContentHeight - viewportHeight;
                return Math.abs(scrollTop - maxScrollTop) <= 1;
            })() || !isScrollingDown);
        };
        let subTableCanScroll = !1;
        const handleParentScroll = parentArgs => {
            const args = parentArgs;
            return args.event && isMouseInChildTableArea(args.event) && shouldSubTableScroll(args.event) ? (subTableCanScroll = !0, 
            !1) : (subTableCanScroll = !1, !0);
        };
        this.table.on("can_scroll", handleParentScroll);
        const handleSubTableScroll = parentArgs => void 0 === parentArgs.event || subTableCanScroll;
        subTable.on("can_scroll", handleSubTableScroll);
        const extendedSubTable = subTable;
        extendedSubTable.__scrollHandler = handleParentScroll, extendedSubTable.__subTableScrollHandler = handleSubTableScroll;
    }
    setupUnifiedSelectionManagement(bodyRowIndex, subTable) {
        const selectionHandler = () => {
            this.clearAllSelectionsExcept(bodyRowIndex);
        };
        subTable.on("click_cell", selectionHandler), subTable.__selectionHandler = selectionHandler;
    }
    calculateGroupLevelOffset(rowIndex) {
        try {
            const recordIndex = this.table.getRecordShowIndexByCell(0, rowIndex), indexKey = this.table.dataSource.getIndexKey(recordIndex);
            if (!Array.isArray(indexKey) || indexKey.length <= 1) return 0;
            let totalOffset = 0;
            for (let r = this.table.columnHeaderLevelCount; r < rowIndex; r++) try {
                const record = this.table.getRecordByCell(0, r);
                if (record && "object" == typeof record && "vtableMergeName" in record) {
                    const groupRecordIndex = this.table.getRecordShowIndexByCell(0, r), groupIndexKey = this.table.dataSource.getIndexKey(groupRecordIndex), normalizedGroupKey = Array.isArray(groupIndexKey) ? groupIndexKey : [ groupIndexKey ];
                    this.isAncestorGroup(normalizedGroupKey, indexKey) && (totalOffset += this.table.getRowHeight(r));
                }
            } catch (e) {}
            return totalOffset;
        } catch (error) {
            return 0;
        }
    }
    isAncestorGroup(groupKey, targetKey) {
        if (groupKey.length >= targetKey.length) return !1;
        for (let i = 0; i < groupKey.length; i++) if (groupKey[i] !== targetKey[i]) return !1;
        return !0;
    }
    setupSubTableCanvasClipping(subTable, bodyRowIndex) {
        var _a;
        if (!(null === (_a = subTable.scenegraph) || void 0 === _a ? void 0 : _a.stage)) return;
        const stage = subTable.scenegraph.stage, extendedSubTable = subTable, calculateClipRegion = () => {
            var _a;
            try {
                const rowIndex = bodyRowIndex + this.table.columnHeaderLevelCount, frozenRowsHeight = this.table.getFrozenRowsHeight(), frozenColsWidth = this.table.getFrozenColsWidth(), rightFrozenColsWidth = this.table.getRightFrozenColsWidth(), bottomFrozenRowsHeight = this.table.getBottomFrozenRowsHeight(), tableWidth = this.table.tableNoFrameWidth, tableHeight = this.table.tableNoFrameHeight, isFrozenDataRow = rowIndex < this.table.frozenRowCount && rowIndex >= this.table.columnHeaderLevelCount, isBottomFrozenDataRow = rowIndex >= this.table.rowCount - this.table.bottomFrozenRowCount, groupLevelOffset = this.calculateGroupLevelOffset(rowIndex), record = (0, 
                utils_1.getRecordByRowIndex)(this.table, bodyRowIndex), detailConfig = record && this.getDetailConfigForRecord ? this.getDetailConfigForRecord(record, bodyRowIndex) : null, [, marginRight, , marginLeft] = (0, 
                utils_1.parseMargin)(null === (_a = null == detailConfig ? void 0 : detailConfig.style) || void 0 === _a ? void 0 : _a.margin);
                let clipY = 0;
                let clipHeight = tableHeight;
                return isFrozenDataRow ? (clipY = groupLevelOffset, clipHeight = tableHeight - bottomFrozenRowsHeight - groupLevelOffset) : isBottomFrozenDataRow ? (clipY = groupLevelOffset, 
                clipHeight = tableHeight - groupLevelOffset) : (clipY = frozenRowsHeight + groupLevelOffset, 
                clipHeight = tableHeight - frozenRowsHeight - bottomFrozenRowsHeight - groupLevelOffset), 
                {
                    clipX: frozenColsWidth + marginLeft,
                    clipY: clipY,
                    clipWidth: tableWidth - frozenColsWidth - rightFrozenColsWidth - marginLeft / 2 - marginRight / 2,
                    clipHeight: clipHeight
                };
            } catch (error) {
                return null;
            }
        }, window = stage.window;
        if (!window || "function" != typeof window.getContext) return;
        const context = window.getContext();
        if (!context) return;
        const wrapRenderMethod = (obj, methodName, originalMethodKey) => {
            const originalMethod = obj[methodName];
            "function" == typeof originalMethod && (extendedSubTable[originalMethodKey] = originalMethod, 
            obj[methodName] = function(...args) {
                context.save();
                try {
                    const clipRegion = calculateClipRegion();
                    if (clipRegion && clipRegion.clipWidth > 0 && clipRegion.clipHeight > 0) {
                        const dpr = window.dpr || window.devicePixelRatio || 1;
                        context.beginPath(), context.rect(clipRegion.clipX * dpr, clipRegion.clipY * dpr, clipRegion.clipWidth * dpr, clipRegion.clipHeight * dpr), 
                        context.clip();
                    }
                    return originalMethod.apply(this, args);
                } finally {
                    context.restore();
                }
            });
        };
        stage.defaultLayer && (wrapRenderMethod(stage.defaultLayer, "render", "__originalRenderMethod"), 
        wrapRenderMethod(stage.defaultLayer, "draw", "__originalDrawMethod"));
    }
    setupAntiFlickerMechanism(subTable) {
        var _a;
        try {
            const originalUpdateNextFrame = null === (_a = subTable.scenegraph) || void 0 === _a ? void 0 : _a.updateNextFrame;
            if (!originalUpdateNextFrame) return;
            const parentTable = this.table, syncRender = () => {
                subTable && originalUpdateNextFrame && originalUpdateNextFrame.call(subTable.scenegraph);
            };
            parentTable.on("after_render", syncRender);
            subTable.__antiFlickerHandler = syncRender;
        } catch (error) {}
    }
    updateSubTablePositionsForRowResize() {
        const internalProps = (0, utils_1.getInternalProps)(this.table);
        internalProps.subTableInstances && (internalProps.subTableInstances.forEach(((subTable, bodyRowIndex) => {
            try {
                const rowIndex = bodyRowIndex + this.table.columnHeaderLevelCount, scenegraph = this.table.scenegraph;
                let cellGroup = null;
                scenegraph && "function" == typeof scenegraph.highPerformanceGetCell ? cellGroup = scenegraph.highPerformanceGetCell(0, rowIndex) : scenegraph && "function" == typeof scenegraph.getCell && (cellGroup = scenegraph.getCell(0, rowIndex));
                const cellHeight = cellGroup && cellGroup.attribute && "number" == typeof cellGroup.attribute.height ? cellGroup.attribute.height : -1;
                internalProps.originalRowHeights && "number" == typeof cellHeight && -1 !== cellHeight && internalProps.originalRowHeights.set(bodyRowIndex, cellHeight);
            } catch (e) {}
        })), this.recalculateAllSubTablePositions());
    }
    recalculateAllSubTablePositions(start, end, getDetailConfig) {
        var _a;
        this.columnRangeCache = null;
        const internalProps = (0, utils_1.getInternalProps)(this.table);
        null === (_a = internalProps.subTableInstances) || void 0 === _a || _a.forEach(((subTable, bodyRowIndex) => {
            var _a, _b;
            if (void 0 !== start && bodyRowIndex < start) return;
            if (void 0 !== end && bodyRowIndex > end) return;
            const record = (0, utils_1.getRecordByRowIndex)(this.table, bodyRowIndex), detailConfig = getDetailConfig ? getDetailConfig(record, bodyRowIndex) : this.getDetailConfigForRecord ? this.getDetailConfigForRecord(record, bodyRowIndex) : null, rowIndex = bodyRowIndex + this.table.columnHeaderLevelCount, originalHeight = (null === (_a = internalProps.originalRowHeights) || void 0 === _a ? void 0 : _a.get(bodyRowIndex)) || 0, detailHeight = this.table.getRowHeight(rowIndex) - originalHeight, newViewBox = this.calculateSubTableViewBox(bodyRowIndex, detailConfig, detailHeight);
            if (newViewBox) {
                const newContainerWidth = newViewBox.x2 - newViewBox.x1, newContainerHeight = newViewBox.y2 - newViewBox.y1;
                subTable.options.viewBox = newViewBox;
                const subTableOptions = subTable.options;
                subTableOptions.canvasWidth === newContainerWidth && subTableOptions.canvasHeight === newContainerHeight || (subTableOptions.canvasWidth = newContainerWidth, 
                subTableOptions.canvasHeight = newContainerHeight, subTable.resize()), (null === (_b = subTable.scenegraph) || void 0 === _b ? void 0 : _b.stage) && subTable.scenegraph.stage.setViewBox(newViewBox, !1);
            }
        }));
    }
    cleanup() {
        if (!this.table) return;
        this.cleanupAllTimers();
        const internalProps = (0, utils_1.getInternalProps)(this.table);
        internalProps && internalProps.subTableInstances && (internalProps.subTableInstances.forEach(((subTable, bodyRowIndex) => {
            this.removeSubTable(bodyRowIndex);
        })), internalProps.subTableInstances.clear()), this.columnRangeCache = null, this.getDetailConfigForRecord = void 0, 
        this.table = null;
    }
    getAllSubTableInstances() {
        return (0, utils_1.getInternalProps)(this.table).subTableInstances;
    }
    getSubTableInstance(bodyRowIndex) {
        var _a;
        return (null === (_a = (0, utils_1.getInternalProps)(this.table).subTableInstances) || void 0 === _a ? void 0 : _a.get(bodyRowIndex)) || null;
    }
    setCallbacks(callbacks) {
        this.getDetailConfigForRecord = callbacks.getDetailConfigForRecord;
    }
    setupSubTableEventForwarding(bodyRowIndex, subTable) {
        const masterRowIndex = bodyRowIndex + this.table.columnHeaderLevelCount;
        Object.values(VTable.TABLE_EVENT_TYPE).forEach((eventType => {
            var _a;
            if (eventType) {
                const handler = (...args) => {
                    this.forwardSubTableEvent(eventType, bodyRowIndex, masterRowIndex, subTable, args);
                };
                subTable.on(eventType, handler);
                const subTableWithHandlers = subTable;
                subTableWithHandlers.__eventHandlers || (subTableWithHandlers.__eventHandlers = new Map);
                const handlers = subTableWithHandlers.__eventHandlers;
                handlers.has(eventType) || handlers.set(eventType, []), null === (_a = handlers.get(eventType)) || void 0 === _a || _a.push(handler);
            }
        }));
    }
    forwardSubTableEvent(eventType, bodyRowIndex, masterRowIndex, subTable, originalArgs) {
        const subTableEventInfo = {
            eventType: eventType,
            masterBodyRowIndex: bodyRowIndex,
            masterRowIndex: masterRowIndex,
            subTable: subTable,
            originalEventArgs: originalArgs
        };
        this.table.fireListeners(VTable.TABLE_EVENT_TYPE.PLUGIN_EVENT, {
            plugin: {
                name: "Master Detail Plugin"
            },
            event: originalArgs[0],
            pluginEventInfo: subTableEventInfo
        });
    }
    clearMainTableSelectionInternal() {
        "function" == typeof this.table.clearSelected && this.table.clearSelected();
    }
    clearAllSelectionsExcept(exceptRecordIndex) {
        var _a;
        this.clearMainTableSelectionInternal();
        null === (_a = (0, utils_1.getInternalProps)(this.table).subTableInstances) || void 0 === _a || _a.forEach(((subTable, rowIndex) => {
            rowIndex !== exceptRecordIndex && subTable && "function" == typeof subTable.clearSelected && subTable.clearSelected();
        }));
    }
    cleanupSubTableEventForwarding(subTable) {
        const subTableWithHandlers = subTable;
        if (subTableWithHandlers.__eventHandlers) {
            for (const [eventType, handlers] of subTableWithHandlers.__eventHandlers) for (const handler of handlers) subTable.off(eventType, handler);
            delete subTableWithHandlers.__eventHandlers;
        }
    }
}

exports.SubTableManager = SubTableManager;
//# sourceMappingURL=subtable.js.map