"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const strings = require("../../../base/common/strings.js");
const position = require("../core/position.js");
const prefixSumComputer = require("./prefixSumComputer.js");
class MirrorTextModel {
  constructor(uri, lines, eol, versionId) {
    this._uri = uri;
    this._lines = lines;
    this._eol = eol;
    this._versionId = versionId;
    this._lineStarts = null;
    this._cachedTextValue = null;
  }
  dispose() {
    this._lines.length = 0;
  }
  get version() {
    return this._versionId;
  }
  getText() {
    if (this._cachedTextValue === null) {
      this._cachedTextValue = this._lines.join(this._eol);
    }
    return this._cachedTextValue;
  }
  onEvents(e) {
    if (e.eol && e.eol !== this._eol) {
      this._eol = e.eol;
      this._lineStarts = null;
    }
    const changes = e.changes;
    for (const change of changes) {
      this._acceptDeleteRange(change.range);
      this._acceptInsertText(new position.Position(change.range.startLineNumber, change.range.startColumn), change.text);
    }
    this._versionId = e.versionId;
    this._cachedTextValue = null;
  }
  _ensureLineStarts() {
    if (!this._lineStarts) {
      const eolLength = this._eol.length;
      const linesLength = this._lines.length;
      const lineStartValues = new Uint32Array(linesLength);
      for (let i = 0; i < linesLength; i++) {
        lineStartValues[i] = this._lines[i].length + eolLength;
      }
      this._lineStarts = new prefixSumComputer.PrefixSumComputer(lineStartValues);
    }
  }
  /**
   * All changes to a line's text go through this method
   */
  _setLineText(lineIndex, newValue) {
    this._lines[lineIndex] = newValue;
    if (this._lineStarts) {
      this._lineStarts.setValue(lineIndex, this._lines[lineIndex].length + this._eol.length);
    }
  }
  _acceptDeleteRange(range) {
    if (range.startLineNumber === range.endLineNumber) {
      if (range.startColumn === range.endColumn) {
        return;
      }
      this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1) + this._lines[range.startLineNumber - 1].substring(range.endColumn - 1));
      return;
    }
    this._setLineText(range.startLineNumber - 1, this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1) + this._lines[range.endLineNumber - 1].substring(range.endColumn - 1));
    this._lines.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber);
    if (this._lineStarts) {
      this._lineStarts.removeValues(range.startLineNumber, range.endLineNumber - range.startLineNumber);
    }
  }
  _acceptInsertText(position2, insertText) {
    if (insertText.length === 0) {
      return;
    }
    const insertLines = strings.splitLines(insertText);
    if (insertLines.length === 1) {
      this._setLineText(position2.lineNumber - 1, this._lines[position2.lineNumber - 1].substring(0, position2.column - 1) + insertLines[0] + this._lines[position2.lineNumber - 1].substring(position2.column - 1));
      return;
    }
    insertLines[insertLines.length - 1] += this._lines[position2.lineNumber - 1].substring(position2.column - 1);
    this._setLineText(position2.lineNumber - 1, this._lines[position2.lineNumber - 1].substring(0, position2.column - 1) + insertLines[0]);
    const newLengths = new Uint32Array(insertLines.length - 1);
    for (let i = 1; i < insertLines.length; i++) {
      this._lines.splice(position2.lineNumber + i - 1, 0, insertLines[i]);
      newLengths[i - 1] = insertLines[i].length + this._eol.length;
    }
    if (this._lineStarts) {
      this._lineStarts.insertValues(position2.lineNumber, newLengths);
    }
  }
}
exports.MirrorTextModel = MirrorTextModel;
