"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RootInteraction = void 0;
const tslib_1 = require("tslib");
const lodash_1 = require("lodash");
const constant_1 = require("../common/constant");
const utils_1 = require("../utils");
const hide_columns_1 = require("../utils/hide-columns");
const hover_event_1 = require("../utils/interaction/hover-event");
const merge_cell_1 = require("../utils/interaction/merge-cell");
const select_event_1 = require("../utils/interaction/select-event");
const state_controller_1 = require("../utils/interaction/state-controller");
const is_mobile_1 = require("../utils/is-mobile");
const click_1 = require("./base-interaction/click");
const corner_cell_click_1 = require("./base-interaction/click/corner-cell-click");
const hover_1 = require("./base-interaction/hover");
const col_brush_selection_1 = require("./brush-selection/col-brush-selection");
const data_cell_brush_selection_1 = require("./brush-selection/data-cell-brush-selection");
const row_brush_selection_1 = require("./brush-selection/row-brush-selection");
const data_cell_multi_selection_1 = require("./data-cell-multi-selection");
const event_controller_1 = require("./event-controller");
const range_selection_1 = require("./range-selection");
const row_column_resize_1 = require("./row-column-resize");
const selected_cell_move_1 = require("./selected-cell-move");
class RootInteraction {
    constructor(spreadsheet) {
        this.interactions = new Map();
        // 用来标记需要拦截的交互，interaction 和本身的 hover 等事件可能会有冲突，有冲突时在此屏蔽
        this.intercepts = new Set();
        /**
         * hover有 keep-hover 态，是个计时器，hover后 800毫秒还在当前 cell 的情况下，该 cell 进入 keep-hover 状态
         * 在任何触发点击，或者点击空白区域时，说明已经不是 hover了，因此需要取消这个计时器。
         */
        this.hoverTimer = null;
        this.drawRafId = null;
        this.defaultState = {
            cells: [],
            force: false,
        };
        this.onTriggerInteractionsResetEffect = () => {
            this.interactions.forEach((interaction) => {
                interaction.reset();
            });
        };
        this.shouldForbidHeaderCellSelected = (selectedCells) => {
            // 禁止跨单元格选择, 这样计算出来的数据和交互没有任何意义
            return (0, lodash_1.unionBy)(selectedCells, 'type').length > 1;
        };
        /**
         * 高亮节点对应的单元格
         * @example s2.interaction.highlightNodes([node])
         */
        this.highlightNodes = (nodes = [], stateName = constant_1.InteractionStateName.HOVER) => {
            nodes.forEach((node) => {
                var _a;
                (_a = node === null || node === void 0 ? void 0 : node.belongsCell) === null || _a === void 0 ? void 0 : _a.updateByState(stateName, node.belongsCell);
            });
        };
        /**
         * 合并单元格
         * @example s2.interaction.mergeCells()
         */
        this.mergeCells = (cellsInfo, hideData) => {
            (0, merge_cell_1.mergeCell)(this.spreadsheet, cellsInfo, hideData);
        };
        /**
         * 取消合并单元格
         * @example s2.interaction.unmergeCell(mergedCell)
         */
        this.unmergeCell = (removedCell) => {
            (0, merge_cell_1.unmergeCell)(this.spreadsheet, removedCell);
        };
        this.spreadsheet = spreadsheet;
        this.registerEventController();
        this.registerInteractions();
        window.addEventListener('visibilitychange', this.onTriggerInteractionsResetEffect);
    }
    /**
     * 销毁交互
     * @example s2.interaction.destroy()
     */
    destroy() {
        this.interactions.clear();
        this.intercepts.clear();
        this.eventController.clear();
        this.clearHoverTimer();
        this.resetState();
        window.removeEventListener('visibilitychange', this.onTriggerInteractionsResetEffect);
    }
    /**
     * 重置交互
     * @example s2.interaction.reset()
     */
    reset() {
        this.clearState();
        this.clearHoverTimer();
        this.intercepts.clear();
        this.spreadsheet.hideTooltip();
    }
    /**
     * 设置交互状态
     * @example
        s2.interaction.setState({
          stateName: InteractionStateName.SELECTED,
          cells: [{
            "id": "root[&]浙江省[&]舟山市",
            "colIndex": -1,
            "rowIndex": 3,
            "type": "rowCell"
          }]
        })
     */
    setState(interactionStateInfo) {
        (0, state_controller_1.setState)(this.spreadsheet, interactionStateInfo);
    }
    /**
     * 获取交互状态
     * @example s2.interaction.getState()
     */
    getState() {
        return (this.spreadsheet.store.get(constant_1.INTERACTION_STATE_INFO_KEY) ||
            this.defaultState);
    }
    /**
     * 设置通过交互触发过更新的单元格
     * @example s2.interaction.setInteractedCells(dataCell)
     */
    setInteractedCells(cell) {
        const interactedCells = this.getInteractedCells().concat([cell]);
        const state = this.getState();
        state.interactedCells = interactedCells;
        this.setState(state);
    }
    /**
     * 获取通过交互触发过更新的单元格
     * @example s2.interaction.getInteractedCells()
     */
    getInteractedCells() {
        const currentState = this.getState();
        return (currentState === null || currentState === void 0 ? void 0 : currentState.interactedCells) || [];
    }
    /**
     * 重置交互状态
     * @example s2.interaction.resetState()
     */
    resetState() {
        this.spreadsheet.store.set(constant_1.INTERACTION_STATE_INFO_KEY, this.defaultState);
    }
    /**
     * 获取当前交互状态名
     * @example s2.interaction.getCurrentStateName()
     */
    getCurrentStateName() {
        return this.getState().stateName;
    }
    /**
     * 是否和当前状态名相同
     * @example s2.interaction.isEqualStateName(InteractionStateName.SELECTED)
     */
    isEqualStateName(stateName) {
        return this.getCurrentStateName() === stateName;
    }
    isStateOf(stateName) {
        const currentState = this.getState();
        return (currentState === null || currentState === void 0 ? void 0 : currentState.stateName) === stateName;
    }
    /**
     * 是否是选中状态 (含单选,多选,圈选,全选)
     * @example s2.interaction.isSelectedState()
     */
    isSelectedState() {
        return (this.isBrushSelectedState() ||
            [constant_1.InteractionStateName.SELECTED, constant_1.InteractionStateName.ALL_SELECTED].some((stateName) => {
                return this.isStateOf(stateName);
            }));
    }
    /**
     * 是否是刷选状态
     * @example s2.interaction.isBrushSelectedState()
     */
    isBrushSelectedState() {
        return [
            constant_1.InteractionStateName.ROW_CELL_BRUSH_SELECTED,
            constant_1.InteractionStateName.COL_CELL_BRUSH_SELECTED,
            constant_1.InteractionStateName.DATA_CELL_BRUSH_SELECTED,
        ].some((stateName) => {
            return this.isStateOf(stateName);
        });
    }
    /**
     * 是否是全选状态
     * @example s2.interaction.isAllSelectedState()
     */
    isAllSelectedState() {
        return this.isStateOf(constant_1.InteractionStateName.ALL_SELECTED);
    }
    /**
     * 是否是悬停聚焦状态
     * @example s2.interaction.isHoverFocusState()
     */
    isHoverFocusState() {
        return this.isStateOf(constant_1.InteractionStateName.HOVER_FOCUS);
    }
    /**
     * 是否是悬停状态
     * @example s2.interaction.isHoverState()
     */
    isHoverState() {
        return this.isStateOf(constant_1.InteractionStateName.HOVER);
    }
    /**
     * 是否是激活的单元格
     * @example s2.interaction.isActiveCell(cell)
     */
    isActiveCell(cell) {
        return !!this.getCells().find((meta) => cell.getMeta().id === meta.id && cell.cellType === meta.type);
    }
    /**
     * 是否是选中的单元格
     * @example s2.interaction.isSelectedCell(cell)
     */
    isSelectedCell(cell) {
        return this.isSelectedState() && this.isActiveCell(cell);
    }
    /**
     * 获取当前 interaction 记录的 Cells 元信息列表，包括不在可视区域内的格子
     * @example s2.interaction.getCells(CellType.DATA_CELL)
     */
    getCells(cellType) {
        const currentState = this.getState();
        const cells = (currentState === null || currentState === void 0 ? void 0 : currentState.cells) || [];
        if ((0, lodash_1.isNil)(cellType)) {
            return cells;
        }
        return cells.filter((cell) => cellType.includes(cell.type));
    }
    /**
     * 获取已激活单元格 (不含非可视区域)
     * @example s2.interaction.getActiveCells()
     */
    getActiveCells() {
        var _a;
        const ids = this.getCells().map((item) => item.id);
        const allCells = (_a = this.spreadsheet.facet) === null || _a === void 0 ? void 0 : _a.getCells();
        // 这里的顺序要以 ids 中的顺序为准，代表点击 cell 的顺序
        return (0, lodash_1.map)(ids, (id) => (0, lodash_1.find)(allCells, (cell) => { var _a; return ((_a = cell === null || cell === void 0 ? void 0 : cell.getMeta()) === null || _a === void 0 ? void 0 : _a.id) === id; })).filter(Boolean);
    }
    getActiveDataCells() {
        return this.getActiveCells().filter((cell) => cell.cellType === constant_1.CellType.DATA_CELL);
    }
    getActiveRowCells() {
        return this.getActiveCells().filter((cell) => cell.cellType === constant_1.CellType.ROW_CELL);
    }
    getActiveColCells() {
        return this.getActiveCells().filter((cell) => cell.cellType === constant_1.CellType.COL_CELL);
    }
    /**
     * 清除单元格交互样式
     * @example s2.interaction.clearStyleIndependent()
     */
    clearStyleIndependent() {
        if (!this.isSelectedState() &&
            !this.isHoverState() &&
            !this.isAllSelectedState()) {
            return;
        }
        this.spreadsheet.facet.getDataCells().forEach((cell) => {
            cell.hideInteractionShape();
        });
    }
    /**
     * 获取未选中的单元格 (不含非可视区域)
     * @example s2.interaction.getUnSelectedDataCells()
     */
    getUnSelectedDataCells() {
        return this.spreadsheet.facet
            .getDataCells()
            .filter((cell) => !this.isActiveCell(cell));
    }
    scrollToCellByMeta(meta, options = { animate: true }) {
        if (!meta) {
            return;
        }
        const { skipScrollEvent, animate } = options;
        const { facet } = this.spreadsheet;
        if (!facet.hRowScrollBar && !facet.hScrollBar && !facet.vScrollBar) {
            return;
        }
        this.scrollTo({
            skipScrollEvent,
            rowHeaderOffsetX: {
                value: meta.x,
                animate,
            },
            offsetX: {
                value: meta.x - (0, lodash_1.get)(facet, 'frozenGroupAreas.frozenCol.width', 0),
                animate,
            },
            offsetY: {
                value: meta.y - (0, lodash_1.get)(facet, 'frozenGroupAreas.frozenRow.height', 0),
                animate,
            },
        });
    }
    /**
     * 滚动至指定位置
     * @example
        s2.interaction.scrollTo({
          skipScrollEvent: false,
          offsetX: { value: 100, animate: true },
          offsetY: { value: 100, animate: true },
        })
     */
    scrollTo(offsetConfig) {
        const { facet } = this.spreadsheet;
        const { scrollX, scrollY, rowHeaderScrollX } = facet.getScrollOffset();
        const defaultConfig = {
            skipScrollEvent: false,
            offsetX: {
                value: scrollX,
                animate: false,
            },
            offsetY: {
                value: scrollY,
                animate: false,
            },
            rowHeaderOffsetX: {
                value: rowHeaderScrollX,
                animate: false,
            },
        };
        facet.updateScrollOffset((0, utils_1.customMerge)(defaultConfig, offsetConfig));
    }
    /**
     * 滚动至指定单元格节点
     * @example s2.interaction.scrollToNode(rowNode, { animate: true, skipScrollEvent: true })
     */
    scrollToNode(meta, options) {
        this.scrollToCellByMeta(meta, options);
    }
    /**
     * 滚动至指定单元格
     * @example s2.interaction.scrollToNode(rowCell, { animate: true, skipScrollEvent: true })
     */
    scrollToCell(cell, options) {
        this.scrollToCellByMeta(cell.getMeta(), options);
    }
    /**
     * 滚动至指定单元格 id 对应的位置
     * @example s2.interaction.scrollToCellById('root[&]四川省[&]成都市', { animate: true, skipScrollEvent: true })
     */
    scrollToCellById(id, options) {
        if (!id) {
            return;
        }
        // 兼容不在可视区域, 未实例化的行列头单元格
        const headerNodes = this.spreadsheet.facet.getHeaderNodes();
        const viewMetaList = this.spreadsheet.facet
            .getDataCells()
            .map((cell) => cell.getMeta());
        const cellMeta = [...headerNodes, ...viewMetaList].find((meta) => meta.id === id);
        if (!cellMeta) {
            return;
        }
        this.scrollToCellByMeta(cellMeta, options);
    }
    /**
     * 滚动至顶部
     * @example s2.interaction.scrollToTop({ animate: true, skipScrollEvent: true })
     */
    scrollToTop(options) {
        this.scrollTo({
            skipScrollEvent: options === null || options === void 0 ? void 0 : options.skipScrollEvent,
            offsetY: {
                value: 0,
                animate: options === null || options === void 0 ? void 0 : options.animate,
            },
        });
    }
    /**
     * 滚动至右边
     * @example s2.interaction.scrollToRight({ animate: true, skipScrollEvent: true })
     */
    scrollToRight(options) {
        this.scrollTo({
            skipScrollEvent: options === null || options === void 0 ? void 0 : options.skipScrollEvent,
            offsetX: {
                value: this.spreadsheet.facet.panelBBox.maxX,
                animate: options === null || options === void 0 ? void 0 : options.animate,
            },
        });
    }
    /**
     * 滚动至底部
     * @example s2.interaction.scrollToBottom({ animate: true, skipScrollEvent: true })
     */
    scrollToBottom(options) {
        this.scrollTo({
            skipScrollEvent: options === null || options === void 0 ? void 0 : options.skipScrollEvent,
            offsetY: {
                value: this.spreadsheet.facet.panelBBox.maxY,
                animate: options === null || options === void 0 ? void 0 : options.animate,
            },
        });
    }
    /**
     * 滚动至左边
     * @example s2.interaction.scrollToLeft({ animate: true, skipScrollEvent: true })
     */
    scrollToLeft(options) {
        this.scrollTo({
            skipScrollEvent: options === null || options === void 0 ? void 0 : options.skipScrollEvent,
            offsetX: {
                value: 0,
                animate: options === null || options === void 0 ? void 0 : options.animate,
            },
        });
    }
    /**
     * 全选
     * @example s2.interaction.selectAll()
     */
    selectAll() {
        const cells = this.spreadsheet.facet.getCells().map(select_event_1.getCellMeta);
        this.changeState({
            cells,
            stateName: constant_1.InteractionStateName.ALL_SELECTED,
        });
        this.addIntercepts([constant_1.InterceptType.HOVER]);
        this.updateCells(this.spreadsheet.facet.getCells());
    }
    /**
     * 高亮指定单元格 (可视范围内)
     * @example s2.interaction.highlightCell(dataCell, options)
     */
    highlightCell(cell, options) {
        this.changeCell(Object.assign(Object.assign({}, options), { cell, stateName: constant_1.InteractionStateName.HOVER }));
    }
    /**
     * 选中指定单元格 (可视范围内)
     * @example s2.interaction.selectCell(dataCell, options)
     */
    selectCell(cell, options) {
        this.changeCell(Object.assign(Object.assign({}, options), { cell, stateName: constant_1.InteractionStateName.SELECTED }));
    }
    /**
     * 改变指定单元格状态 (如: 选中/高亮/多选等) (可视范围内)
     * @example
       s2.interaction.changeCell({
         cell: rowCell,
         stateName: InteractionStateName.SELECTED,
         isMultiSelection: false,
         scrollIntoView: false,
         animate: true,
         skipScrollEvent: true,
      })
     */
    changeCell(options = {}) {
        var _a, _b;
        const { event, cell, stateName = constant_1.InteractionStateName.SELECTED, interactionName, scrollIntoView = true, animate = true, skipScrollEvent = true, } = options;
        if ((0, lodash_1.isEmpty)(cell)) {
            return;
        }
        const meta = (_a = cell === null || cell === void 0 ? void 0 : cell.getMeta) === null || _a === void 0 ? void 0 : _a.call(cell);
        if (!meta || (0, lodash_1.isNil)(meta === null || meta === void 0 ? void 0 : meta.x)) {
            return;
        }
        this.addIntercepts([constant_1.InterceptType.HOVER]);
        const isHierarchyTree = this.spreadsheet.isHierarchyTreeType();
        const isColCell = (cell === null || cell === void 0 ? void 0 : cell.cellType) === constant_1.CellType.COL_CELL;
        const lastState = this.getState();
        const isSelectedCell = this.isSelectedCell(cell);
        const isMultiSelected = (options === null || options === void 0 ? void 0 : options.isMultiSelection) && this.isSelectedState();
        // 如果是已选中的单元格, 则取消选中, 兼容行列多选 (含叶子节点)
        let childrenNodes = isSelectedCell
            ? []
            : this.spreadsheet.facet.getCellChildrenNodes(cell);
        let selectedCells = isSelectedCell ? [] : [(0, select_event_1.getCellMeta)(cell)];
        if (isMultiSelected) {
            selectedCells = (0, lodash_1.concat)((lastState === null || lastState === void 0 ? void 0 : lastState.cells) || [], selectedCells);
            childrenNodes = (0, lodash_1.concat)((lastState === null || lastState === void 0 ? void 0 : lastState.nodes) || [], childrenNodes);
            if (isSelectedCell) {
                selectedCells = selectedCells.filter(({ id }) => id !== meta.id);
                childrenNodes = childrenNodes.filter((node) => !(node === null || node === void 0 ? void 0 : node.id.includes(meta.id)));
            }
        }
        if ((0, lodash_1.isEmpty)(selectedCells)) {
            this.reset();
            this.emitSelectEvent({
                event,
                targetCell: cell,
                interactionName,
            });
            return;
        }
        if (this.shouldForbidHeaderCellSelected(selectedCells)) {
            return;
        }
        const nodes = (0, lodash_1.isEmpty)(childrenNodes)
            ? [cell.getMeta()]
            : childrenNodes;
        // 兼容行列多选 (高亮 行/列头 以及相对应的数值单元格)
        this.changeState({
            cells: selectedCells,
            nodes,
            stateName,
        });
        const selectedCellIds = (0, select_event_1.groupSelectedCells)(selectedCells);
        this.updateCells(this.spreadsheet.facet.getHeaderCells(selectedCellIds));
        // 平铺模式或者是树状模式下的列头单元格, 高亮子节点
        if (!isHierarchyTree || isColCell) {
            this.highlightNodes(childrenNodes, stateName);
        }
        // 如果不在可视范围, 自动滚动
        if (scrollIntoView) {
            this.scrollToCell(cell, {
                skipScrollEvent,
                animate,
            });
        }
        // 由于绘制的顺序问题, 交互背景图层展示后, 会遮挡边框, 需要让边框展示在前面.
        (_b = this.spreadsheet.facet.centerFrame) === null || _b === void 0 ? void 0 : _b.toFront();
        this.emitSelectEvent({
            event,
            targetCell: cell,
            interactionName,
        });
        return true;
    }
    /**
     * 隐藏列头
     * @example s2.interaction.hideColumns(['city'])
     */
    hideColumns() {
        return tslib_1.__awaiter(this, arguments, void 0, function* (hiddenColumnFields = [], forceRender = true) {
            yield (0, hide_columns_1.hideColumnsByThunkGroup)(this.spreadsheet, hiddenColumnFields, forceRender);
        });
    }
    getBrushSelectionInfo(brushSelection) {
        var _a, _b, _c;
        if ((0, lodash_1.isBoolean)(brushSelection)) {
            return {
                dataCellBrushSelection: brushSelection,
                rowCellBrushSelection: brushSelection,
                colCellBrushSelection: brushSelection,
            };
        }
        return {
            dataCellBrushSelection: (_a = brushSelection === null || brushSelection === void 0 ? void 0 : brushSelection.dataCell) !== null && _a !== void 0 ? _a : false,
            rowCellBrushSelection: (_b = brushSelection === null || brushSelection === void 0 ? void 0 : brushSelection.rowCell) !== null && _b !== void 0 ? _b : false,
            colCellBrushSelection: (_c = brushSelection === null || brushSelection === void 0 ? void 0 : brushSelection.colCell) !== null && _c !== void 0 ? _c : false,
        };
    }
    getDefaultInteractions() {
        const { resize, brushSelection, multiSelection, rangeSelection, selectedCellMove, } = this.spreadsheet.options.interaction;
        const { dataCellBrushSelection, rowCellBrushSelection, colCellBrushSelection, } = this.getBrushSelectionInfo(brushSelection);
        return [
            {
                key: constant_1.InteractionName.CORNER_CELL_CLICK,
                interaction: corner_cell_click_1.CornerCellClick,
            },
            {
                key: constant_1.InteractionName.DATA_CELL_CLICK,
                interaction: click_1.DataCellClick,
            },
            {
                key: constant_1.InteractionName.ROW_COLUMN_CLICK,
                interaction: click_1.RowColumnClick,
            },
            {
                key: constant_1.InteractionName.HEADER_CELL_LINK_CLICK,
                interaction: click_1.HeaderCellLinkClick,
            },
            {
                key: constant_1.InteractionName.MERGED_CELLS_CLICK,
                interaction: click_1.MergedCellClick,
            },
            {
                key: constant_1.InteractionName.PREVIEW_CLICK,
                interaction: click_1.PreviewClick,
            },
            {
                key: constant_1.InteractionName.HOVER,
                interaction: hover_1.HoverEvent,
                enable: !(0, is_mobile_1.isMobile)(),
            },
            {
                key: constant_1.InteractionName.DATA_CELL_BRUSH_SELECTION,
                interaction: data_cell_brush_selection_1.DataCellBrushSelection,
                enable: !(0, is_mobile_1.isMobile)() && dataCellBrushSelection,
            },
            {
                key: constant_1.InteractionName.ROW_CELL_BRUSH_SELECTION,
                interaction: row_brush_selection_1.RowCellBrushSelection,
                enable: !(0, is_mobile_1.isMobile)() && rowCellBrushSelection,
            },
            {
                key: constant_1.InteractionName.COL_CELL_BRUSH_SELECTION,
                interaction: col_brush_selection_1.ColCellBrushSelection,
                enable: !(0, is_mobile_1.isMobile)() && colCellBrushSelection,
            },
            {
                key: constant_1.InteractionName.COL_ROW_RESIZE,
                interaction: row_column_resize_1.RowColumnResize,
                enable: !(0, is_mobile_1.isMobile)() && resize,
            },
            {
                key: constant_1.InteractionName.DATA_CELL_MULTI_SELECTION,
                interaction: data_cell_multi_selection_1.DataCellMultiSelection,
                enable: !(0, is_mobile_1.isMobile)() && multiSelection,
            },
            {
                key: constant_1.InteractionName.RANGE_SELECTION,
                interaction: range_selection_1.RangeSelection,
                enable: !(0, is_mobile_1.isMobile)() && rangeSelection,
            },
            {
                key: constant_1.InteractionName.SELECTED_CELL_MOVE,
                interaction: selected_cell_move_1.SelectedCellMove,
                enable: !(0, is_mobile_1.isMobile)() && selectedCellMove,
            },
        ];
    }
    registerInteractions() {
        const { customInteractions } = this.spreadsheet.options.interaction;
        this.interactions.clear();
        const defaultInteractions = this.getDefaultInteractions();
        defaultInteractions.forEach(({ key, interaction: Interaction, enable }) => {
            if (enable !== false) {
                this.interactions.set(key, new Interaction(this.spreadsheet));
            }
        });
        if (!(0, lodash_1.isEmpty)(customInteractions)) {
            (0, lodash_1.forEach)(customInteractions, (customInteraction) => {
                const CustomInteractionClass = customInteraction.interaction;
                if (CustomInteractionClass) {
                    this.interactions.set(customInteraction.key, new CustomInteractionClass(this.spreadsheet));
                }
            });
        }
    }
    registerEventController() {
        this.eventController = new event_controller_1.EventController(this.spreadsheet);
    }
    draw() {
        // 每次调用前取消上一帧的未执行任务
        if (this.drawRafId !== null) {
            cancelAnimationFrame(this.drawRafId);
        }
        // 存储新请求ID
        this.drawRafId = requestAnimationFrame(() => {
            this.spreadsheet.container.render();
            // 渲染完成后重置ID
            this.drawRafId = null;
        });
    }
    clearState() {
        if ((0, state_controller_1.clearState)(this.spreadsheet)) {
            this.draw();
        }
    }
    /**
     * 改变单元格交互状态后，进行更新和重新绘制
     * @example
        s2.interaction.changeState({
          cells: [{ id: 'city', colIndex: 1, rowIndex : 2, type: 'rowCell' }],
          stateName: InteractionStateName.SELECTED,
          force: false
        })
     */
    changeState(interactionStateInfo) {
        const { interaction } = this.spreadsheet;
        const { cells = [], force, stateName, onUpdateCells, } = interactionStateInfo;
        if ((0, lodash_1.isEmpty)(cells) && stateName === constant_1.InteractionStateName.SELECTED) {
            if (force) {
                interaction.changeState({
                    cells: [],
                    stateName: constant_1.InteractionStateName.UNSELECTED,
                });
            }
            return;
        }
        // 之前是全选状态，需要清除格子的样式
        if (this.getCurrentStateName() === constant_1.InteractionStateName.ALL_SELECTED) {
            this.clearStyleIndependent();
        }
        this.clearState();
        this.setState(interactionStateInfo);
        // 更新单元格
        const update = () => {
            this.updateAllDataCells();
        };
        if (onUpdateCells) {
            onUpdateCells(this, update);
        }
        else {
            update();
        }
        this.draw();
    }
    /**
     * 更新所有数值单元格
     * @example s2.interaction.updateAllDataCells()
     */
    updateAllDataCells() {
        this.updateCells(this.spreadsheet.facet.getDataCells());
    }
    /**
     * 更新指定单元格
     * @example s2.interaction.updateCells([rowCell, dataCell])
     */
    updateCells(cells = []) {
        cells.forEach((cell) => {
            cell.update();
        });
    }
    /**
     * 添加交互拦截
     * @example s2.interaction.addIntercepts([InterceptType.HOVER])
     */
    addIntercepts(interceptTypes = []) {
        interceptTypes.forEach((interceptType) => {
            this.intercepts.add(interceptType);
        });
    }
    /**
     * 是否有指定交互拦截
     * @example s2.interaction.hasIntercepts([InterceptType.HOVER])
     */
    hasIntercepts(interceptTypes = []) {
        return interceptTypes.some((interceptType) => this.intercepts.has(interceptType));
    }
    /**
     * 移除交互拦截
     * @example s2.interaction.removeIntercepts([InterceptType.HOVER])
     */
    removeIntercepts(interceptTypes = []) {
        interceptTypes.forEach((interceptType) => {
            this.intercepts.delete(interceptType);
        });
    }
    clearHoverTimer() {
        clearTimeout(this.hoverTimer);
    }
    setHoverTimer(timer) {
        this.hoverTimer = timer;
    }
    getHoverTimer() {
        return this.hoverTimer;
    }
    getSelectedCellHighlight() {
        var _a;
        const { selectedCellHighlight } = this.spreadsheet.options.interaction;
        if ((0, lodash_1.isBoolean)(selectedCellHighlight)) {
            return {
                rowHeader: selectedCellHighlight,
                colHeader: selectedCellHighlight,
                currentRow: selectedCellHighlight,
                currentCol: selectedCellHighlight,
            };
        }
        const { rowHeader = false, colHeader = false, currentRow = false, currentCol = false, } = (_a = selectedCellHighlight) !== null && _a !== void 0 ? _a : {};
        return {
            rowHeader,
            colHeader,
            currentRow,
            currentCol,
        };
    }
    getHoverAfterScroll() {
        return this.spreadsheet.options.interaction.hoverAfterScroll;
    }
    getHoverHighlight() {
        const { hoverHighlight } = this.spreadsheet.options.interaction;
        if ((0, lodash_1.isBoolean)(hoverHighlight)) {
            return {
                rowHeader: hoverHighlight,
                colHeader: hoverHighlight,
                currentRow: hoverHighlight,
                currentCol: hoverHighlight,
            };
        }
        const { rowHeader = false, colHeader = false, currentRow = false, currentCol = false, } = hoverHighlight !== null && hoverHighlight !== void 0 ? hoverHighlight : {};
        return {
            rowHeader,
            colHeader,
            currentRow,
            currentCol,
        };
    }
    getBrushSelection() {
        const { brushSelection } = this.spreadsheet.options.interaction;
        if ((0, lodash_1.isBoolean)(brushSelection)) {
            return {
                dataCell: brushSelection,
                rowCell: brushSelection,
                colCell: brushSelection,
            };
        }
        const { dataCell = false, rowCell = false, colCell = false, } = brushSelection !== null && brushSelection !== void 0 ? brushSelection : {};
        return {
            dataCell,
            rowCell,
            colCell,
        };
    }
    updateDataCellRelevantHeaderCells(stateName, meta) {
        this.updateDataCellRelevantColCells(stateName, meta);
        this.updateDataCellRelevantRowCells(stateName, meta);
    }
    updateDataCellRelevantRowCells(stateName, meta) {
        const { rowId } = meta;
        const { facet, interaction } = this.spreadsheet;
        const isHoverState = stateName === constant_1.InteractionStateName.HOVER;
        const { rowHeader } = isHoverState
            ? interaction.getHoverHighlight()
            : interaction.getSelectedCellHighlight();
        if (rowHeader && rowId) {
            const activeRowCells = isHoverState
                ? (0, hover_event_1.getActiveHoverHeaderCells)(rowId, facet.getRowCells(), this.spreadsheet.isHierarchyTreeType())
                : (0, select_event_1.getRowCellForSelectedCell)(meta, this.spreadsheet);
            const activeSeriesNumberCells = facet
                .getSeriesNumberCells()
                .filter((seriesNumberCell) => {
                return activeRowCells.find((rowCell) => rowCell.getMeta().y === seriesNumberCell.getMeta().y);
            });
            const activeHeaderCells = [...activeSeriesNumberCells, ...activeRowCells];
            (0, lodash_1.forEach)(activeHeaderCells, (cell) => {
                cell.updateByState(stateName);
            });
        }
    }
    updateDataCellRelevantColCells(stateName, meta) {
        const { colId } = meta;
        const { facet, interaction } = this.spreadsheet;
        const { colHeader } = stateName === constant_1.InteractionStateName.HOVER
            ? interaction.getHoverHighlight()
            : interaction.getSelectedCellHighlight();
        if (colHeader && colId) {
            (0, hover_event_1.updateAllHeaderCellState)(colId, facet.getColCells(), stateName);
        }
    }
    emitSelectEvent(options) {
        const { interaction } = this.spreadsheet;
        const { cells } = options, defaultCellSelectedDetail = tslib_1.__rest(options, ["cells"]);
        const activeCells = cells || interaction.getActiveCells();
        const targetCell = (defaultCellSelectedDetail === null || defaultCellSelectedDetail === void 0 ? void 0 : defaultCellSelectedDetail.targetCell) || activeCells[0];
        const cellSelectedDetail = Object.assign(Object.assign({}, defaultCellSelectedDetail), { targetCell });
        const cellType = targetCell === null || targetCell === void 0 ? void 0 : targetCell.cellType;
        const eventName = {
            [constant_1.CellType.CORNER_CELL]: constant_1.S2Event.CORNER_CELL_SELECTED,
            [constant_1.CellType.ROW_CELL]: constant_1.S2Event.ROW_CELL_SELECTED,
            [constant_1.CellType.COL_CELL]: constant_1.S2Event.COL_CELL_SELECTED,
            [constant_1.CellType.DATA_CELL]: constant_1.S2Event.DATA_CELL_SELECTED,
        }[cellType];
        if (!eventName) {
            return;
        }
        this.spreadsheet.emit(eventName, activeCells, cellSelectedDetail);
        this.spreadsheet.emit(constant_1.S2Event.GLOBAL_SELECTED, activeCells, cellSelectedDetail);
    }
}
exports.RootInteraction = RootInteraction;
//# sourceMappingURL=root.js.map