"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const fastDomNode = require("../../../../base/browser/fastDomNode.js");
const strings = require("../../../../base/common/strings.js");
const domFontInfo = require("../../config/domFontInfo.js");
const editorOptions = require("../../../common/config/editorOptions.js");
const position = require("../../../common/core/position.js");
const range = require("../../../common/core/range.js");
const mouseCursor = require("../../../../base/browser/ui/mouseCursor/mouseCursor.js");
class ViewCursorRenderData {
  constructor(top, left, width, height, textContent, textContentClassName) {
    this.top = top;
    this.left = left;
    this.width = width;
    this.height = height;
    this.textContent = textContent;
    this.textContentClassName = textContentClassName;
  }
}
class ViewCursor {
  constructor(context) {
    this._context = context;
    const options = this._context.configuration.options;
    const fontInfo = options.get(
      44
      /* fontInfo */
    );
    this._cursorStyle = options.get(
      24
      /* cursorStyle */
    );
    this._lineHeight = options.get(
      59
      /* lineHeight */
    );
    this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth;
    this._lineCursorWidth = Math.min(options.get(
      27
      /* cursorWidth */
    ), this._typicalHalfwidthCharacterWidth);
    this._isVisible = true;
    this._domNode = fastDomNode.createFastDomNode(document.createElement("div"));
    this._domNode.setClassName(`cursor ${mouseCursor.MOUSE_CURSOR_TEXT_CSS_CLASS_NAME}`);
    this._domNode.setHeight(this._lineHeight);
    this._domNode.setTop(0);
    this._domNode.setLeft(0);
    domFontInfo.applyFontInfo(this._domNode, fontInfo);
    this._domNode.setDisplay("none");
    this._position = new position.Position(1, 1);
    this._lastRenderedContent = "";
    this._renderData = null;
  }
  getDomNode() {
    return this._domNode;
  }
  getPosition() {
    return this._position;
  }
  show() {
    if (!this._isVisible) {
      this._domNode.setVisibility("inherit");
      this._isVisible = true;
    }
  }
  hide() {
    if (this._isVisible) {
      this._domNode.setVisibility("hidden");
      this._isVisible = false;
    }
  }
  onConfigurationChanged(e) {
    const options = this._context.configuration.options;
    const fontInfo = options.get(
      44
      /* fontInfo */
    );
    this._cursorStyle = options.get(
      24
      /* cursorStyle */
    );
    this._lineHeight = options.get(
      59
      /* lineHeight */
    );
    this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth;
    this._lineCursorWidth = Math.min(options.get(
      27
      /* cursorWidth */
    ), this._typicalHalfwidthCharacterWidth);
    domFontInfo.applyFontInfo(this._domNode, fontInfo);
    return true;
  }
  onCursorPositionChanged(position2) {
    this._position = position2;
    return true;
  }
  /**
   * If `this._position` is inside a grapheme, returns the position where the grapheme starts.
   * Also returns the next grapheme.
   */
  _getGraphemeAwarePosition() {
    const { lineNumber, column } = this._position;
    const lineContent = this._context.viewModel.getLineContent(lineNumber);
    const [startOffset, endOffset] = strings.getCharContainingOffset(lineContent, column - 1);
    return [new position.Position(lineNumber, startOffset + 1), lineContent.substring(startOffset, endOffset)];
  }
  _prepareRender(ctx) {
    let textContent = "";
    const [position2, nextGrapheme] = this._getGraphemeAwarePosition();
    if (this._cursorStyle === editorOptions.TextEditorCursorStyle.Line || this._cursorStyle === editorOptions.TextEditorCursorStyle.LineThin) {
      const visibleRange = ctx.visibleRangeForPosition(position2);
      if (!visibleRange || visibleRange.outsideRenderedLine) {
        return null;
      }
      let width2;
      if (this._cursorStyle === editorOptions.TextEditorCursorStyle.Line) {
        width2 = dom.computeScreenAwareSize(this._lineCursorWidth > 0 ? this._lineCursorWidth : 2);
        if (width2 > 2) {
          textContent = nextGrapheme;
        }
      } else {
        width2 = dom.computeScreenAwareSize(1);
      }
      let left = visibleRange.left;
      if (width2 >= 2 && left >= 1) {
        left -= 1;
      }
      const top2 = ctx.getVerticalOffsetForLineNumber(position2.lineNumber) - ctx.bigNumbersDelta;
      return new ViewCursorRenderData(top2, left, width2, this._lineHeight, textContent, "");
    }
    const visibleRangeForCharacter = ctx.linesVisibleRangesForRange(new range.Range(position2.lineNumber, position2.column, position2.lineNumber, position2.column + nextGrapheme.length), false);
    if (!visibleRangeForCharacter || visibleRangeForCharacter.length === 0) {
      return null;
    }
    const firstVisibleRangeForCharacter = visibleRangeForCharacter[0];
    if (firstVisibleRangeForCharacter.outsideRenderedLine || firstVisibleRangeForCharacter.ranges.length === 0) {
      return null;
    }
    const range$1 = firstVisibleRangeForCharacter.ranges[0];
    const width = range$1.width < 1 ? this._typicalHalfwidthCharacterWidth : range$1.width;
    let textContentClassName = "";
    if (this._cursorStyle === editorOptions.TextEditorCursorStyle.Block) {
      const lineData = this._context.viewModel.getViewLineData(position2.lineNumber);
      textContent = nextGrapheme;
      const tokenIndex = lineData.tokens.findTokenIndexAtOffset(position2.column - 1);
      textContentClassName = lineData.tokens.getClassName(tokenIndex);
    }
    let top = ctx.getVerticalOffsetForLineNumber(position2.lineNumber) - ctx.bigNumbersDelta;
    let height = this._lineHeight;
    if (this._cursorStyle === editorOptions.TextEditorCursorStyle.Underline || this._cursorStyle === editorOptions.TextEditorCursorStyle.UnderlineThin) {
      top += this._lineHeight - 2;
      height = 2;
    }
    return new ViewCursorRenderData(top, range$1.left, width, height, textContent, textContentClassName);
  }
  prepareRender(ctx) {
    this._renderData = this._prepareRender(ctx);
  }
  render(ctx) {
    if (!this._renderData) {
      this._domNode.setDisplay("none");
      return null;
    }
    if (this._lastRenderedContent !== this._renderData.textContent) {
      this._lastRenderedContent = this._renderData.textContent;
      this._domNode.domNode.textContent = this._lastRenderedContent;
    }
    this._domNode.setClassName(`cursor ${mouseCursor.MOUSE_CURSOR_TEXT_CSS_CLASS_NAME} ${this._renderData.textContentClassName}`);
    this._domNode.setDisplay("block");
    this._domNode.setTop(this._renderData.top);
    this._domNode.setLeft(this._renderData.left);
    this._domNode.setWidth(this._renderData.width);
    this._domNode.setLineHeight(this._renderData.height);
    this._domNode.setHeight(this._renderData.height);
    return {
      domNode: this._domNode.domNode,
      position: this._position,
      contentLeft: this._renderData.left,
      height: this._renderData.height,
      width: 2
    };
  }
}
exports.ViewCursor = ViewCursor;
