"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.yfmTableControlsPlugin = exports.tableControlsPluginKey = void 0;
const prosemirror_model_1 = require("prosemirror-model");
const prosemirror_state_1 = require("prosemirror-state");
const prosemirror_utils_1 = require("prosemirror-utils");
const prosemirror_view_1 = require("prosemirror-view");
const lodash_1 = require("../../../../../lodash.js");
const table_utils_1 = require("../../../../../table-utils/index.js");
const utils_1 = require("../../../../../utils/index.js");
const YfmTableSpecs_1 = require("../../YfmTableSpecs/index.js");
const view_1 = require("./view.js");
const yfmTableCellView_1 = require("./yfmTableCellView.js");
exports.tableControlsPluginKey = new prosemirror_state_1.PluginKey('TableControlsPlugin');
function shouldUpdateState(prev, curr) {
    if (prev === null && curr === null)
        return false;
    if (prev === null || curr === null)
        return true;
    if (prev.left.from === curr.left.from &&
        prev.left.to === curr.left.to &&
        prev.upper.from === curr.upper.from &&
        prev.upper.to === curr.upper.to)
        return false;
    return true;
}
// TODO: split: plus buttons extension & cell controls extension
const yfmTableControlsPlugin = () => new prosemirror_state_1.Plugin({
    key: exports.tableControlsPluginKey,
    state: {
        init: () => null,
        apply: (tr, prev) => {
            const meta = tr.getMeta(exports.tableControlsPluginKey);
            return meta === undefined ? prev : meta;
        },
    },
    props: {
        nodeViews: {
            [YfmTableSpecs_1.YfmTableNode.Table]: view_1.yfmTableView,
            [YfmTableSpecs_1.YfmTableNode.Cell]: yfmTableCellView_1.yfmTableCellView,
        },
        decorations(state) {
            const pluginState = exports.tableControlsPluginKey.getState(state);
            const parent = (0, prosemirror_utils_1.findParentNode)(table_utils_1.isTableNode)(state.selection) ||
                (0, prosemirror_utils_1.findSelectedNodeOfType)(state.schema.nodes.yfm_table)(state.selection);
            if (!parent)
                return null;
            const decs = [
                prosemirror_view_1.Decoration.node(parent.pos, parent.pos + parent.node.nodeSize, {
                    class: (0, view_1.viewB)('buttons-visible'),
                }),
            ];
            if (pluginState) {
                const { upper, left } = pluginState;
                decs.unshift(prosemirror_view_1.Decoration.node(left.from, left.to, {
                    class: (0, yfmTableCellView_1.yfmTableCellCn)('left-visible'),
                }), prosemirror_view_1.Decoration.node(upper.from, upper.to, {
                    class: (0, yfmTableCellView_1.yfmTableCellCn)('upper-visible'),
                }));
            }
            return prosemirror_view_1.DecorationSet.create(state.doc, decs);
        },
        handleDOMEvents: {
            mousemove: (0, lodash_1.throttle)((view, e) => {
                const prevState = exports.tableControlsPluginKey.getState(view.state);
                const pos = view.posAtCoords({ left: e.x, top: e.y });
                if (!pos)
                    return false;
                const $pos = view.state.doc.resolve(pos.pos);
                const cell = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, table_utils_1.isTableCellNode);
                const row = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, table_utils_1.isTableRowNode);
                const tbody = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, table_utils_1.isTableBodyNode);
                let state = null;
                if (cell && row && tbody) {
                    const cellIndex = (0, utils_1.getChildrenOfNode)(row.node).findIndex((child) => child.node === cell.node);
                    const firstRowCell = (0, utils_1.getChildrenOfNode)(tbody.node.firstChild || prosemirror_model_1.Fragment.empty)[cellIndex];
                    if (firstRowCell) {
                        const upperFrom = tbody.pos + 2 + firstRowCell.offset;
                        const upperTo = upperFrom + firstRowCell.node.nodeSize;
                        const leftFrom = row.pos;
                        const leftTo = row.pos + row.node.nodeSize;
                        state = {
                            upper: { from: upperFrom, to: upperTo },
                            left: { from: leftFrom, to: leftTo },
                        };
                    }
                }
                if (shouldUpdateState(prevState, state)) {
                    view.dispatch(view.state.tr.setMeta(exports.tableControlsPluginKey, state));
                }
                return false;
            }, 100),
        },
    },
});
exports.yfmTableControlsPlugin = yfmTableControlsPlugin;
//# sourceMappingURL=buttons.js.map
