import * as VTable from "@visactor/vtable";

export class EventManager {
    constructor(table) {
        this.table = table, this.expandedRows = [], this.eventHandlers = [], this.allExpandedRowsBeforeMove = new Set, 
        this.isCleanedUp = !1;
    }
    bindEventHandlers() {
        const scrollHandler = () => this.onUpdateSubTablePositions(), resizeRowHandler = () => this.onUpdateSubTablePositionsForRow();
        this.table.on(VTable.TABLE_EVENT_TYPE.SCROLL, scrollHandler), this.table.on(VTable.TABLE_EVENT_TYPE.RESIZE_ROW, resizeRowHandler), 
        this.eventHandlers.push({
            type: VTable.TABLE_EVENT_TYPE.SCROLL,
            handler: scrollHandler
        }, {
            type: VTable.TABLE_EVENT_TYPE.RESIZE_ROW,
            handler: resizeRowHandler
        }), this.wrapTableResizeMethod(), this.bindTreeHierarchyStateChange(), this.bindRowMoveEvents();
    }
    wrapTableResizeMethod() {
        const originalResize = this.table.resize.bind(this.table);
        this.originalResize = originalResize, this.table.resize = () => {
            originalResize(), this.onUpdateSubTablePositions();
        };
    }
    handleAfterUpdateCellContentWidth(eventData) {
        var _a;
        const {col: col, row: row, cellGroup: cellGroup, cellHeight: cellHeight, padding: padding, textBaseline: textBaseline} = eventData;
        if (this.isCustomMergeCell(col, row)) return void this.fixCustomMergeCellTextPosition(cellGroup, padding);
        let effectiveCellHeight = cellHeight;
        if (void 0 !== cellGroup.col && void 0 !== cellGroup.row) try {
            const recordIndex = this.table.getRecordShowIndexByCell(cellGroup.col, cellGroup.row);
            if (void 0 !== recordIndex) {
                const originalHeight = (null === (_a = this.getOriginalRowHeight) || void 0 === _a ? void 0 : _a.call(this, recordIndex)) || 0;
                if (originalHeight > 0) {
                    effectiveCellHeight = originalHeight;
                    const newHeight = effectiveCellHeight - (padding[0] + padding[2]);
                    cellGroup.forEachChildren((child => {
                        "rect" !== child.type && "chart" !== child.type && "custom-container" !== child.name && ("mark" === child.name ? child.setAttribute("y", 0) : "middle" === textBaseline ? child.setAttribute("y", padding[0] + (newHeight - child.AABBBounds.height()) / 2) : "bottom" === textBaseline ? child.setAttribute("y", padding[0] + newHeight - child.AABBBounds.height()) : child.setAttribute("y", padding[0]));
                    }));
                }
            }
        } catch (error) {}
    }
    fixCustomMergeCellTextPosition(cellGroup, padding) {
        const {col: col, row: row} = cellGroup, table = this.table, customMerge = table.getCustomMerge(col, row);
        if (!customMerge || !customMerge.style || !customMerge.range) return;
        const configuredTextAlign = customMerge.style.textAlign || "left", {start: start, end: end} = customMerge.range;
        let totalMergeWidth = 0, mergeStartX = 0;
        for (let c = start.col; c <= end.col; c++) totalMergeWidth += table.getColWidth(c);
        for (let c = 0; c < start.col; c++) mergeStartX += table.getColWidth(c);
        cellGroup.forEachChildren((child => {
            if ("text" === child.name || "content" === child.name) {
                let xPosition;
                xPosition = "center" === configuredTextAlign ? mergeStartX + padding[3] + (totalMergeWidth - padding[1] - padding[3]) / 2 : "right" === configuredTextAlign ? mergeStartX + totalMergeWidth - padding[1] : mergeStartX + padding[3], 
                child.setAttribute("x", xPosition), child.setAttribute("textAlign", configuredTextAlign);
            }
        }));
    }
    isCustomMergeCell(col, row) {
        try {
            const table = this.table;
            if (table && table.getCustomMerge) {
                return !!table.getCustomMerge(col, row);
            }
        } catch (error) {}
        return !1;
    }
    handleAfterUpdateSelectBorderHeight(eventData) {
        var _a, _b;
        const {startRow: startRow, endRow: endRow, selectComp: selectComp} = eventData, isSingleCellSelection = startRow === endRow, isLastRowExpanded = this.expandedRows.includes(endRow);
        if (isSingleCellSelection) {
            const bodyRowIndex = startRow - (this.table.columnHeaderLevelCount || 0), originalHeight = (null === (_a = this.getOriginalRowHeight) || void 0 === _a ? void 0 : _a.call(this, bodyRowIndex)) || 0;
            if (originalHeight > 0 && originalHeight !== eventData.currentHeight && (selectComp.rect.setAttributes({
                height: originalHeight
            }), selectComp.fillhandle)) {
                const currentY = selectComp.rect.attribute.y;
                selectComp.fillhandle.setAttributes({
                    y: currentY + originalHeight
                });
            }
        } else if (isLastRowExpanded) {
            const lastRowBodyIndex = endRow - (this.table.columnHeaderLevelCount || 0), lastRowOriginalHeight = (null === (_b = this.getOriginalRowHeight) || void 0 === _b ? void 0 : _b.call(this, lastRowBodyIndex)) || 0;
            if (lastRowOriginalHeight > 0) {
                const lastRowCurrentHeight = this.table.getRowHeight(endRow), adjustedTotalHeight = eventData.currentHeight - lastRowCurrentHeight + lastRowOriginalHeight;
                if (selectComp.rect.setAttributes({
                    height: adjustedTotalHeight
                }), selectComp.fillhandle) {
                    const currentY = selectComp.rect.attribute.y;
                    selectComp.fillhandle.setAttributes({
                        y: currentY + adjustedTotalHeight
                    });
                }
            }
        }
    }
    executeMasterDetailBeforeSort() {
        const table = this.table;
        if (table.internalProps.expandedRecordIndices && table.internalProps.expandedRecordIndices.length > 0 && (table.internalProps._tempExpandedRecordIndices = [ ...table.internalProps.expandedRecordIndices ]), 
        this.expandedRows.length > 0) {
            [ ...this.expandedRows ].forEach((rowIndex => {
                var _a, _b;
                try {
                    const tableOptions = table.options;
                    tableOptions && tableOptions.pagination ? null === (_a = this.onCollapseRowToNoRealRecordIndex) || void 0 === _a || _a.call(this, rowIndex) : null === (_b = this.onCollapseRow) || void 0 === _b || _b.call(this, rowIndex);
                } catch (e) {}
            }));
        }
    }
    executeMasterDetailAfterSort() {
        const table = this.table, tempExpandedRecordIndices = table.internalProps._tempExpandedRecordIndices;
        if (tempExpandedRecordIndices && tempExpandedRecordIndices.length > 0) {
            [ ...tempExpandedRecordIndices ].forEach((recordIndex => {
                var _a;
                const bodyRowIndex = table.getBodyRowIndexByRecordIndex(recordIndex);
                if (bodyRowIndex >= 0) try {
                    const targetRowIndex = bodyRowIndex + table.columnHeaderLevelCount;
                    null === (_a = this.onExpandRow) || void 0 === _a || _a.call(this, targetRowIndex);
                } catch (e) {}
            })), delete table.internalProps._tempExpandedRecordIndices;
        }
    }
    getExpandedRows() {
        return this.expandedRows;
    }
    setExpandedRows(rows) {
        this.expandedRows = rows;
    }
    addExpandedRow(rowIndex) {
        this.expandedRows.includes(rowIndex) || this.expandedRows.push(rowIndex);
    }
    removeExpandedRow(rowIndex) {
        const index = this.expandedRows.indexOf(rowIndex);
        index > -1 && this.expandedRows.splice(index, 1);
    }
    isRowExpanded(rowIndex) {
        return this.expandedRows.includes(rowIndex);
    }
    bindTreeHierarchyStateChange() {
        const hierarchyStateChangeHandler = args => {
            var _a;
            const {col: col, row: row} = args, record = this.getRecordByRowIndex(row - this.table.columnHeaderLevelCount);
            record && "object" == typeof record && "children" in record && !0 === record.children || null === (_a = this.onToggleRowExpand) || void 0 === _a || _a.call(this, row, col);
        };
        this.table.on(VTable.TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, hierarchyStateChangeHandler), 
        this.eventHandlers.push({
            type: VTable.TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE,
            handler: hierarchyStateChangeHandler
        });
    }
    getRecordByRowIndex(bodyRowIndex) {
        try {
            const table = this.table, recordIndex = table.getRecordShowIndexByCell(0, bodyRowIndex + table.columnHeaderLevelCount);
            return table.dataSource.get(recordIndex);
        } catch (error) {
            return null;
        }
    }
    bindRowMoveEvents() {
        const moveStartHandler = args => {
            var _a, _b;
            if (!args || "number" != typeof args.col || "number" != typeof args.row) return;
            const {col: col, row: row} = args;
            if (!("rowHeader" === this.table.getCellLocation(col, row) || (null === (_b = (_a = this.table.internalProps.layoutMap).isSeriesNumberInBody) || void 0 === _b ? void 0 : _b.call(_a, col, row)))) return;
            this.allExpandedRowsBeforeMove.clear();
            const currentExpandedRows = [ ...this.expandedRows ];
            currentExpandedRows.forEach((rowIndex => {
                this.allExpandedRowsBeforeMove.add(rowIndex);
            })), currentExpandedRows.forEach((rowIndex => {
                var _a;
                null === (_a = this.onCollapseRow) || void 0 === _a || _a.call(this, rowIndex);
            }));
        }, moveSuccessHandler = args => {
            var _a;
            if (0 === this.allExpandedRowsBeforeMove.size) return;
            const columnMoveState = null === (_a = this.table.stateManager) || void 0 === _a ? void 0 : _a.columnMove, {colSource: colSource, rowSource: rowSource, colTarget: colTarget, rowTarget: rowTarget} = columnMoveState;
            setTimeout((() => {
                const sourceRowIndex = rowSource, targetRowIndex = rowTarget, moveDirection = targetRowIndex > sourceRowIndex ? "down" : "up";
                this.allExpandedRowsBeforeMove.forEach((originalRowIndex => {
                    var _a;
                    let newRowIndex = originalRowIndex;
                    sourceRowIndex === originalRowIndex ? newRowIndex = targetRowIndex : "down" === moveDirection ? originalRowIndex <= targetRowIndex && originalRowIndex > sourceRowIndex && (newRowIndex = originalRowIndex - 1) : "up" === moveDirection && originalRowIndex >= targetRowIndex && originalRowIndex < sourceRowIndex && (newRowIndex = originalRowIndex + 1), 
                    null === (_a = this.onExpandRow) || void 0 === _a || _a.call(this, newRowIndex);
                })), this.allExpandedRowsBeforeMove.clear();
            }), 0);
        }, moveFailHandler = args => {
            0 !== this.allExpandedRowsBeforeMove.size && setTimeout((() => {
                this.allExpandedRowsBeforeMove.forEach((originalRowIndex => {
                    var _a;
                    null === (_a = this.onExpandRow) || void 0 === _a || _a.call(this, originalRowIndex);
                })), this.allExpandedRowsBeforeMove.clear();
            }), 0);
        };
        this.table.on(VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION_START, moveStartHandler), 
        this.table.on(VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION, moveSuccessHandler), 
        this.table.on(VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION_FAIL, moveFailHandler), 
        this.eventHandlers.push({
            type: VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION_START,
            handler: moveStartHandler
        }, {
            type: VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION,
            handler: moveSuccessHandler
        }, {
            type: VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION_FAIL,
            handler: moveFailHandler
        });
    }
    cleanup() {
        if (!this.isCleanedUp) {
            if (this.isCleanedUp = !0, this.expandedRows.length = 0, this.allExpandedRowsBeforeMove.clear(), 
            this.originalResize && this.table) try {
                this.table.resize = this.originalResize, this.originalResize = void 0;
            } catch (error) {}
            try {
                this.table && (this.eventHandlers.forEach((({type: type, handler: handler}) => {
                    try {
                        this.table.off(type, handler);
                    } catch (error) {}
                })), this.eventHandlers.length = 0);
            } catch (error) {}
            this.onUpdateSubTablePositions = void 0, this.onUpdateSubTablePositionsForRow = void 0, 
            this.onExpandRow = void 0, this.onCollapseRow = void 0, this.onCollapseRowToNoRealRecordIndex = void 0, 
            this.onToggleRowExpand = void 0, this.getOriginalRowHeight = void 0, this.table = null;
        }
    }
    setCallbacks(callbacks) {
        this.onUpdateSubTablePositions = callbacks.onUpdateSubTablePositions, this.onUpdateSubTablePositionsForRow = callbacks.onUpdateSubTablePositionsForRow, 
        this.onExpandRow = callbacks.onExpandRow, this.onCollapseRow = callbacks.onCollapseRow, 
        this.onCollapseRowToNoRealRecordIndex = callbacks.onCollapseRowToNoRealRecordIndex, 
        this.onToggleRowExpand = callbacks.onToggleRowExpand, this.getOriginalRowHeight = callbacks.getOriginalRowHeight;
    }
}
//# sourceMappingURL=events.js.map