"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const strings = require("../../../base/common/strings.js");
const replaceCommand = require("../commands/replaceCommand.js");
const cursorCommon = require("../cursorCommon.js");
const cursorColumns = require("../core/cursorColumns.js");
const cursorMoveOperations = require("./cursorMoveOperations.js");
const range = require("../core/range.js");
const position = require("../core/position.js");
class DeleteOperations {
  static deleteRight(prevEditOperationType, config, model, selections) {
    const commands = [];
    let shouldPushStackElementBefore = prevEditOperationType !== 3;
    for (let i = 0, len = selections.length; i < len; i++) {
      const selection = selections[i];
      let deleteSelection = selection;
      if (deleteSelection.isEmpty()) {
        const position2 = selection.getPosition();
        const rightOfPosition = cursorMoveOperations.MoveOperations.right(config, model, position2);
        deleteSelection = new range.Range(rightOfPosition.lineNumber, rightOfPosition.column, position2.lineNumber, position2.column);
      }
      if (deleteSelection.isEmpty()) {
        commands[i] = null;
        continue;
      }
      if (deleteSelection.startLineNumber !== deleteSelection.endLineNumber) {
        shouldPushStackElementBefore = true;
      }
      commands[i] = new replaceCommand.ReplaceCommand(deleteSelection, "");
    }
    return [shouldPushStackElementBefore, commands];
  }
  static isAutoClosingPairDelete(autoClosingDelete, autoClosingBrackets, autoClosingQuotes, autoClosingPairsOpen, model, selections, autoClosedCharacters) {
    if (autoClosingBrackets === "never" && autoClosingQuotes === "never") {
      return false;
    }
    if (autoClosingDelete === "never") {
      return false;
    }
    for (let i = 0, len = selections.length; i < len; i++) {
      const selection = selections[i];
      const position2 = selection.getPosition();
      if (!selection.isEmpty()) {
        return false;
      }
      const lineText = model.getLineContent(position2.lineNumber);
      if (position2.column < 2 || position2.column >= lineText.length + 1) {
        return false;
      }
      const character = lineText.charAt(position2.column - 2);
      const autoClosingPairCandidates = autoClosingPairsOpen.get(character);
      if (!autoClosingPairCandidates) {
        return false;
      }
      if (cursorCommon.isQuote(character)) {
        if (autoClosingQuotes === "never") {
          return false;
        }
      } else {
        if (autoClosingBrackets === "never") {
          return false;
        }
      }
      const afterCharacter = lineText.charAt(position2.column - 1);
      let foundAutoClosingPair = false;
      for (const autoClosingPairCandidate of autoClosingPairCandidates) {
        if (autoClosingPairCandidate.open === character && autoClosingPairCandidate.close === afterCharacter) {
          foundAutoClosingPair = true;
        }
      }
      if (!foundAutoClosingPair) {
        return false;
      }
      if (autoClosingDelete === "auto") {
        let found = false;
        for (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {
          const autoClosedCharacter = autoClosedCharacters[j];
          if (position2.lineNumber === autoClosedCharacter.startLineNumber && position2.column === autoClosedCharacter.startColumn) {
            found = true;
            break;
          }
        }
        if (!found) {
          return false;
        }
      }
    }
    return true;
  }
  static _runAutoClosingPairDelete(config, model, selections) {
    const commands = [];
    for (let i = 0, len = selections.length; i < len; i++) {
      const position2 = selections[i].getPosition();
      const deleteSelection = new range.Range(position2.lineNumber, position2.column - 1, position2.lineNumber, position2.column + 1);
      commands[i] = new replaceCommand.ReplaceCommand(deleteSelection, "");
    }
    return [true, commands];
  }
  static deleteLeft(prevEditOperationType, config, model, selections, autoClosedCharacters) {
    if (this.isAutoClosingPairDelete(config.autoClosingDelete, config.autoClosingBrackets, config.autoClosingQuotes, config.autoClosingPairs.autoClosingPairsOpenByEnd, model, selections, autoClosedCharacters)) {
      return this._runAutoClosingPairDelete(config, model, selections);
    }
    const commands = [];
    let shouldPushStackElementBefore = prevEditOperationType !== 2;
    for (let i = 0, len = selections.length; i < len; i++) {
      const deleteRange = DeleteOperations.getDeleteRange(selections[i], model, config);
      if (deleteRange.isEmpty()) {
        commands[i] = null;
        continue;
      }
      if (deleteRange.startLineNumber !== deleteRange.endLineNumber) {
        shouldPushStackElementBefore = true;
      }
      commands[i] = new replaceCommand.ReplaceCommand(deleteRange, "");
    }
    return [shouldPushStackElementBefore, commands];
  }
  static getDeleteRange(selection, model, config) {
    if (!selection.isEmpty()) {
      return selection;
    }
    const position2 = selection.getPosition();
    if (config.useTabStops && position2.column > 1) {
      const lineContent = model.getLineContent(position2.lineNumber);
      const firstNonWhitespaceIndex = strings.firstNonWhitespaceIndex(lineContent);
      const lastIndentationColumn = firstNonWhitespaceIndex === -1 ? (
        /* entire string is whitespace */
        lineContent.length + 1
      ) : firstNonWhitespaceIndex + 1;
      if (position2.column <= lastIndentationColumn) {
        const fromVisibleColumn = config.visibleColumnFromColumn(model, position2);
        const toVisibleColumn = cursorColumns.CursorColumns.prevIndentTabStop(fromVisibleColumn, config.indentSize);
        const toColumn = config.columnFromVisibleColumn(model, position2.lineNumber, toVisibleColumn);
        return new range.Range(position2.lineNumber, toColumn, position2.lineNumber, position2.column);
      }
    }
    return range.Range.fromPositions(DeleteOperations.getPositionAfterDeleteLeft(position2, model), position2);
  }
  static getPositionAfterDeleteLeft(position$1, model) {
    if (position$1.column > 1) {
      const idx = strings.getLeftDeleteOffset(position$1.column - 1, model.getLineContent(position$1.lineNumber));
      return position$1.with(void 0, idx + 1);
    } else if (position$1.lineNumber > 1) {
      const newLine = position$1.lineNumber - 1;
      return new position.Position(newLine, model.getLineMaxColumn(newLine));
    } else {
      return position$1;
    }
  }
  static cut(config, model, selections) {
    const commands = [];
    let lastCutRange = null;
    selections.sort((a, b) => position.Position.compare(a.getStartPosition(), b.getEndPosition()));
    for (let i = 0, len = selections.length; i < len; i++) {
      const selection = selections[i];
      if (selection.isEmpty()) {
        if (config.emptySelectionClipboard) {
          const position2 = selection.getPosition();
          let startLineNumber, startColumn, endLineNumber, endColumn;
          if (position2.lineNumber < model.getLineCount()) {
            startLineNumber = position2.lineNumber;
            startColumn = 1;
            endLineNumber = position2.lineNumber + 1;
            endColumn = 1;
          } else if (position2.lineNumber > 1 && (lastCutRange === null || lastCutRange === void 0 ? void 0 : lastCutRange.endLineNumber) !== position2.lineNumber) {
            startLineNumber = position2.lineNumber - 1;
            startColumn = model.getLineMaxColumn(position2.lineNumber - 1);
            endLineNumber = position2.lineNumber;
            endColumn = model.getLineMaxColumn(position2.lineNumber);
          } else {
            startLineNumber = position2.lineNumber;
            startColumn = 1;
            endLineNumber = position2.lineNumber;
            endColumn = model.getLineMaxColumn(position2.lineNumber);
          }
          const deleteSelection = new range.Range(startLineNumber, startColumn, endLineNumber, endColumn);
          lastCutRange = deleteSelection;
          if (!deleteSelection.isEmpty()) {
            commands[i] = new replaceCommand.ReplaceCommand(deleteSelection, "");
          } else {
            commands[i] = null;
          }
        } else {
          commands[i] = null;
        }
      } else {
        commands[i] = new replaceCommand.ReplaceCommand(selection, "");
      }
    }
    return new cursorCommon.EditOperationResult(0, commands, {
      shouldPushStackElementBefore: true,
      shouldPushStackElementAfter: true
    });
  }
}
exports.DeleteOperations = DeleteOperations;
