"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backToCutTitle = exports.removeCut = exports.exitFromCutTitle = exports.liftEmptyBlockFromCut = void 0;
const prosemirror_model_1 = require("prosemirror-model");
const prosemirror_state_1 = require("prosemirror-state");
const nodes_1 = require("../../../utils/nodes.js");
const schema_1 = require("../../../utils/schema.js");
const selection_1 = require("../../../utils/selection.js");
const base_1 = require("../../base/index.js");
const const_1 = require("./const.js");
const liftEmptyBlockFromCut = (state, dispatch) => {
    const { selection, schema } = state;
    if (!(0, selection_1.isTextSelection)(selection))
        return false;
    const { $cursor } = selection;
    // cursor should be inside an empty textblock
    if (!$cursor || $cursor.parent.content.size)
        return false;
    if ($cursor.depth > 2 && // yfm_cut -> yfm_cut_content -> <textblock>, depth must be at least 3
        (0, schema_1.isSameNodeType)($cursor.node(-1), (0, const_1.cutContentType)(schema)) &&
        (0, schema_1.isSameNodeType)($cursor.node(-2), (0, const_1.cutType)(schema)) &&
        $cursor.node(-1).childCount > 1) {
        // current texblock is last child of yfm_cut_content
        if ($cursor.after() === $cursor.end(-1)) {
            if (dispatch) {
                dispatch(state.tr.lift($cursor.blockRange(), $cursor.depth - 3).scrollIntoView());
            }
            return true;
        }
    }
    return false;
};
exports.liftEmptyBlockFromCut = liftEmptyBlockFromCut;
const exitFromCutTitle = (state, dispatch) => {
    const { selection, schema } = state;
    if (!(0, selection_1.isTextSelection)(selection))
        return false;
    const { $cursor } = selection;
    if (!$cursor)
        return false;
    if (!(0, schema_1.isSameNodeType)($cursor.parent, (0, const_1.cutTitleType)(schema)) ||
        !(0, schema_1.isSameNodeType)($cursor.node(-1), (0, const_1.cutType)(schema))) {
        return false;
    }
    const cutNode = $cursor.node(-1);
    const cutContentFirstTextblockChild = (0, nodes_1.findFirstTextblockChild)(cutNode.lastChild);
    if (!cutContentFirstTextblockChild)
        return false;
    const cutContentPos = $cursor.start(-1) + cutNode.firstChild.nodeSize + 1;
    const targetPos = cutContentPos + cutContentFirstTextblockChild.offset;
    dispatch?.(state.tr.setSelection(prosemirror_state_1.TextSelection.create(state.doc, targetPos)));
    return true;
};
exports.exitFromCutTitle = exitFromCutTitle;
/**
 * Deletes the cut if the cursor is at the beginning of the title.
 * Cut will be replaced with his title converted to paragraph and his content.
 */
const removeCut = (state, dispatch, view) => {
    const { selection, schema } = state;
    if (!(0, selection_1.isTextSelection)(selection))
        return false;
    const { $cursor } = selection;
    if (!$cursor)
        return false;
    if (!(0, schema_1.isSameNodeType)($cursor.parent, (0, const_1.cutTitleType)(schema)) ||
        !(0, schema_1.isSameNodeType)($cursor.node(-1), (0, const_1.cutType)(schema))) {
        return false;
    }
    if (view?.endOfTextblock('backward', state)) {
        if (dispatch) {
            const cutTitleNode = $cursor.parent;
            const cutNode = $cursor.node(-1);
            const cutContentNode = cutNode.lastChild; // cut always have 2 child: title and content; see schema
            const content = prosemirror_model_1.Fragment.from((0, base_1.pType)(schema).create(null, cutTitleNode.content)).append(cutContentNode.content);
            const from = $cursor.before(-1);
            const to = from + cutNode.nodeSize;
            const tr = state.tr.replaceWith(from, to, content);
            dispatch(tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, from + 1)));
        }
        return true;
    }
    return false;
};
exports.removeCut = removeCut;
/**
 * If the cursor is at the beginning of the first paragraph in cut's content,
 * moves the cursor to the end of the cut's title.
 */
const backToCutTitle = (state, dispatch, view) => {
    const { selection, schema } = state;
    if (!(0, selection_1.isTextSelection)(selection))
        return false;
    const { $cursor } = selection;
    if (!$cursor)
        return false;
    if (!(0, schema_1.isSameNodeType)($cursor.parent, (0, base_1.pType)(schema)) ||
        !(0, schema_1.isSameNodeType)($cursor.node(-1), (0, const_1.cutContentType)(schema)) ||
        !(0, schema_1.isSameNodeType)($cursor.node(-2), (0, const_1.cutType)(schema))) {
        return false;
    }
    const cutNode = $cursor.node(-2);
    const cutContentNode = $cursor.node(-1);
    if ($cursor.parent !== cutContentNode.firstChild)
        return false;
    if (view?.endOfTextblock('backward', state)) {
        if (dispatch) {
            const cutTitleNode = cutNode.firstChild;
            dispatch(state.tr.setSelection(prosemirror_state_1.TextSelection.create(state.doc, $cursor.before(-2) + cutTitleNode.nodeSize)));
        }
        return true;
    }
    return false;
};
exports.backToCutTitle = backToCutTitle;
//# sourceMappingURL=commands.js.map
