import ansiEscapes from 'ansi-escapes';
const showCursorEscape = '\u001B[?25h';
const hideCursorEscape = '\u001B[?25l';
export { showCursorEscape, hideCursorEscape };
/**
Compare two cursor positions. Returns true if they differ.
*/
export const cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y;
/**
Build escape sequence to move cursor from bottom of output to the target position and show it.
When hasTrailingNewline is true the terminal cursor sits at (col 0, line visibleLineCount)
— i.e. just after the last output line. When false (fullscreen mode) it sits at the END
of the last visible line (line visibleLineCount - 1), so one fewer cursorUp is needed.
*/
export const buildCursorSuffix = (visibleLineCount, cursorPosition, hasTrailingNewline = true) => {
    if (!cursorPosition) {
        return '';
    }
    const moveUp = (hasTrailingNewline ? visibleLineCount : visibleLineCount - 1) - cursorPosition.y;
    return ((moveUp > 0 ? ansiEscapes.cursorUp(moveUp) : '') +
        ansiEscapes.cursorTo(cursorPosition.x) +
        showCursorEscape);
};
/**
Build escape sequence to move cursor from previousCursorPosition back to the bottom of output.
This must be done before eraseLines or any operation that assumes cursor is at the bottom.
*/
export const buildReturnToBottom = (previousLineCount, previousCursorPosition) => {
    if (!previousCursorPosition) {
        return '';
    }
    // previousLineCount is lines.length from str.split('\n'), which already
    // includes the trailing empty element when the output ends with '\n'.
    // The bottom line is therefore always previousLineCount - 1 regardless
    // of whether a trailing newline was present.
    const down = previousLineCount - 1 - previousCursorPosition.y;
    return ((down > 0 ? ansiEscapes.cursorDown(down) : '') + ansiEscapes.cursorTo(0));
};
/**
Build the escape sequence for cursor-only updates (output unchanged, cursor moved).
Hides cursor if it was previously shown, returns to bottom, then repositions.
*/
export const buildCursorOnlySequence = (input) => {
    const hidePrefix = input.cursorWasShown ? hideCursorEscape : '';
    const returnToBottom = buildReturnToBottom(input.previousLineCount, input.previousCursorPosition);
    const cursorSuffix = buildCursorSuffix(input.visibleLineCount, input.cursorPosition, input.hasTrailingNewline);
    return hidePrefix + returnToBottom + cursorSuffix;
};
/**
Build the prefix that hides cursor and returns to bottom before erasing or rewriting.
Returns empty string if cursor was not shown.
*/
export const buildReturnToBottomPrefix = (cursorWasShown, previousLineCount, previousCursorPosition) => {
    if (!cursorWasShown) {
        return '';
    }
    return (hideCursorEscape +
        buildReturnToBottom(previousLineCount, previousCursorPosition));
};
//# sourceMappingURL=cursor-helpers.js.map