"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../base/browser/dom.js");
const selection = require("../common/core/selection.js");
const fastDomNode = require("../../base/browser/fastDomNode.js");
const errors = require("../../base/common/errors.js");
const pointerHandler = require("./controller/pointerHandler.js");
const textAreaHandler = require("./controller/textAreaHandler.js");
const viewController = require("./view/viewController.js");
const viewUserInputEvents = require("./view/viewUserInputEvents.js");
const viewOverlays = require("./view/viewOverlays.js");
const viewPart = require("./view/viewPart.js");
const contentWidgets = require("./viewParts/contentWidgets/contentWidgets.js");
const currentLineHighlight = require("./viewParts/currentLineHighlight/currentLineHighlight.js");
const decorations = require("./viewParts/decorations/decorations.js");
const editorScrollbar = require("./viewParts/editorScrollbar/editorScrollbar.js");
const glyphMargin = require("./viewParts/glyphMargin/glyphMargin.js");
const indentGuides = require("./viewParts/indentGuides/indentGuides.js");
const lineNumbers = require("./viewParts/lineNumbers/lineNumbers.js");
const viewLines = require("./viewParts/lines/viewLines.js");
const linesDecorations = require("./viewParts/linesDecorations/linesDecorations.js");
const margin = require("./viewParts/margin/margin.js");
const marginDecorations = require("./viewParts/marginDecorations/marginDecorations.js");
const minimap = require("./viewParts/minimap/minimap.js");
const overlayWidgets = require("./viewParts/overlayWidgets/overlayWidgets.js");
const decorationsOverviewRuler = require("./viewParts/overviewRuler/decorationsOverviewRuler.js");
const overviewRuler = require("./viewParts/overviewRuler/overviewRuler.js");
const rulers = require("./viewParts/rulers/rulers.js");
const scrollDecoration = require("./viewParts/scrollDecoration/scrollDecoration.js");
const selections = require("./viewParts/selections/selections.js");
const viewCursors = require("./viewParts/viewCursors/viewCursors.js");
const viewZones = require("./viewParts/viewZones/viewZones.js");
const position = require("../common/core/position.js");
const range = require("../common/core/range.js");
const renderingContext = require("./view/renderingContext.js");
const viewContext = require("../common/viewModel/viewContext.js");
const viewLinesViewportData = require("../common/viewLayout/viewLinesViewportData.js");
const viewEventHandler = require("../common/viewEventHandler.js");
const themeService = require("../../platform/theme/common/themeService.js");
const mouseTarget = require("./controller/mouseTarget.js");
class View extends viewEventHandler.ViewEventHandler {
  constructor(commandDelegate, configuration, colorTheme, model, userInputEvents, overflowWidgetsDomNode) {
    super();
    this._selections = [new selection.Selection(1, 1, 1, 1)];
    this._renderAnimationFrame = null;
    const viewController$1 = new viewController.ViewController(configuration, model, userInputEvents, commandDelegate);
    this._context = new viewContext.ViewContext(configuration, colorTheme, model);
    this._context.addEventHandler(this);
    this._viewParts = [];
    this._textAreaHandler = new textAreaHandler.TextAreaHandler(this._context, viewController$1, this._createTextAreaHandlerHelper());
    this._viewParts.push(this._textAreaHandler);
    this._linesContent = fastDomNode.createFastDomNode(document.createElement("div"));
    this._linesContent.setClassName("lines-content monaco-editor-background");
    this._linesContent.setPosition("absolute");
    this.domNode = fastDomNode.createFastDomNode(document.createElement("div"));
    this.domNode.setClassName(this._getEditorClassName());
    this.domNode.setAttribute("role", "code");
    this._overflowGuardContainer = fastDomNode.createFastDomNode(document.createElement("div"));
    viewPart.PartFingerprints.write(
      this._overflowGuardContainer,
      3
      /* OverflowGuard */
    );
    this._overflowGuardContainer.setClassName("overflow-guard");
    this._scrollbar = new editorScrollbar.EditorScrollbar(this._context, this._linesContent, this.domNode, this._overflowGuardContainer);
    this._viewParts.push(this._scrollbar);
    this._viewLines = new viewLines.ViewLines(this._context, this._linesContent);
    this._viewZones = new viewZones.ViewZones(this._context);
    this._viewParts.push(this._viewZones);
    const decorationsOverviewRuler$1 = new decorationsOverviewRuler.DecorationsOverviewRuler(this._context);
    this._viewParts.push(decorationsOverviewRuler$1);
    const scrollDecoration$1 = new scrollDecoration.ScrollDecorationViewPart(this._context);
    this._viewParts.push(scrollDecoration$1);
    const contentViewOverlays = new viewOverlays.ContentViewOverlays(this._context);
    this._viewParts.push(contentViewOverlays);
    contentViewOverlays.addDynamicOverlay(new currentLineHighlight.CurrentLineHighlightOverlay(this._context));
    contentViewOverlays.addDynamicOverlay(new selections.SelectionsOverlay(this._context));
    contentViewOverlays.addDynamicOverlay(new indentGuides.IndentGuidesOverlay(this._context));
    contentViewOverlays.addDynamicOverlay(new decorations.DecorationsOverlay(this._context));
    const marginViewOverlays = new viewOverlays.MarginViewOverlays(this._context);
    this._viewParts.push(marginViewOverlays);
    marginViewOverlays.addDynamicOverlay(new currentLineHighlight.CurrentLineMarginHighlightOverlay(this._context));
    marginViewOverlays.addDynamicOverlay(new glyphMargin.GlyphMarginOverlay(this._context));
    marginViewOverlays.addDynamicOverlay(new marginDecorations.MarginViewLineDecorationsOverlay(this._context));
    marginViewOverlays.addDynamicOverlay(new linesDecorations.LinesDecorationsOverlay(this._context));
    marginViewOverlays.addDynamicOverlay(new lineNumbers.LineNumbersOverlay(this._context));
    const margin$1 = new margin.Margin(this._context);
    margin$1.getDomNode().appendChild(this._viewZones.marginDomNode);
    margin$1.getDomNode().appendChild(marginViewOverlays.getDomNode());
    this._viewParts.push(margin$1);
    this._contentWidgets = new contentWidgets.ViewContentWidgets(this._context, this.domNode);
    this._viewParts.push(this._contentWidgets);
    this._viewCursors = new viewCursors.ViewCursors(this._context);
    this._viewParts.push(this._viewCursors);
    this._overlayWidgets = new overlayWidgets.ViewOverlayWidgets(this._context);
    this._viewParts.push(this._overlayWidgets);
    const rulers$1 = new rulers.Rulers(this._context);
    this._viewParts.push(rulers$1);
    const minimap$1 = new minimap.Minimap(this._context);
    this._viewParts.push(minimap$1);
    if (decorationsOverviewRuler$1) {
      const overviewRulerData = this._scrollbar.getOverviewRulerLayoutInfo();
      overviewRulerData.parent.insertBefore(decorationsOverviewRuler$1.getDomNode(), overviewRulerData.insertBefore);
    }
    this._linesContent.appendChild(contentViewOverlays.getDomNode());
    this._linesContent.appendChild(rulers$1.domNode);
    this._linesContent.appendChild(this._viewZones.domNode);
    this._linesContent.appendChild(this._viewLines.getDomNode());
    this._linesContent.appendChild(this._contentWidgets.domNode);
    this._linesContent.appendChild(this._viewCursors.getDomNode());
    this._overflowGuardContainer.appendChild(margin$1.getDomNode());
    this._overflowGuardContainer.appendChild(this._scrollbar.getDomNode());
    this._overflowGuardContainer.appendChild(scrollDecoration$1.getDomNode());
    this._overflowGuardContainer.appendChild(this._textAreaHandler.textArea);
    this._overflowGuardContainer.appendChild(this._textAreaHandler.textAreaCover);
    this._overflowGuardContainer.appendChild(this._overlayWidgets.getDomNode());
    this._overflowGuardContainer.appendChild(minimap$1.getDomNode());
    this.domNode.appendChild(this._overflowGuardContainer);
    if (overflowWidgetsDomNode) {
      overflowWidgetsDomNode.appendChild(this._contentWidgets.overflowingContentWidgetsDomNode.domNode);
    } else {
      this.domNode.appendChild(this._contentWidgets.overflowingContentWidgetsDomNode);
    }
    this._applyLayout();
    this._pointerHandler = this._register(new pointerHandler.PointerHandler(this._context, viewController$1, this._createPointerHandlerHelper()));
  }
  _flushAccumulatedAndRenderNow() {
    this._renderNow();
  }
  _createPointerHandlerHelper() {
    return {
      viewDomNode: this.domNode.domNode,
      linesContentDomNode: this._linesContent.domNode,
      focusTextArea: () => {
        this.focus();
      },
      dispatchTextAreaEvent: (event) => {
        this._textAreaHandler.textArea.domNode.dispatchEvent(event);
      },
      getLastRenderData: () => {
        const lastViewCursorsRenderData = this._viewCursors.getLastRenderData() || [];
        const lastTextareaPosition = this._textAreaHandler.getLastRenderData();
        return new mouseTarget.PointerHandlerLastRenderData(lastViewCursorsRenderData, lastTextareaPosition);
      },
      shouldSuppressMouseDownOnViewZone: (viewZoneId) => {
        return this._viewZones.shouldSuppressMouseDownOnViewZone(viewZoneId);
      },
      shouldSuppressMouseDownOnWidget: (widgetId) => {
        return this._contentWidgets.shouldSuppressMouseDownOnWidget(widgetId);
      },
      getPositionFromDOMInfo: (spanNode, offset) => {
        this._flushAccumulatedAndRenderNow();
        return this._viewLines.getPositionFromDOMInfo(spanNode, offset);
      },
      visibleRangeForPosition: (lineNumber, column) => {
        this._flushAccumulatedAndRenderNow();
        return this._viewLines.visibleRangeForPosition(new position.Position(lineNumber, column));
      },
      getLineWidth: (lineNumber) => {
        this._flushAccumulatedAndRenderNow();
        return this._viewLines.getLineWidth(lineNumber);
      }
    };
  }
  _createTextAreaHandlerHelper() {
    return {
      visibleRangeForPosition: (position2) => {
        this._flushAccumulatedAndRenderNow();
        return this._viewLines.visibleRangeForPosition(position2);
      }
    };
  }
  _applyLayout() {
    const options = this._context.configuration.options;
    const layoutInfo = options.get(
      131
      /* layoutInfo */
    );
    this.domNode.setWidth(layoutInfo.width);
    this.domNode.setHeight(layoutInfo.height);
    this._overflowGuardContainer.setWidth(layoutInfo.width);
    this._overflowGuardContainer.setHeight(layoutInfo.height);
    this._linesContent.setWidth(1e6);
    this._linesContent.setHeight(1e6);
  }
  _getEditorClassName() {
    const focused = this._textAreaHandler.isFocused() ? " focused" : "";
    return this._context.configuration.options.get(
      128
      /* editorClassName */
    ) + " " + themeService.getThemeTypeSelector(this._context.theme.type) + focused;
  }
  // --- begin event handlers
  handleEvents(events) {
    super.handleEvents(events);
    this._scheduleRender();
  }
  onConfigurationChanged(e) {
    this.domNode.setClassName(this._getEditorClassName());
    this._applyLayout();
    return false;
  }
  onCursorStateChanged(e) {
    this._selections = e.selections;
    return false;
  }
  onFocusChanged(e) {
    this.domNode.setClassName(this._getEditorClassName());
    return false;
  }
  onThemeChanged(e) {
    this._context.theme.update(e.theme);
    this.domNode.setClassName(this._getEditorClassName());
    return false;
  }
  // --- end event handlers
  dispose() {
    if (this._renderAnimationFrame !== null) {
      this._renderAnimationFrame.dispose();
      this._renderAnimationFrame = null;
    }
    this._contentWidgets.overflowingContentWidgetsDomNode.domNode.remove();
    this._context.removeEventHandler(this);
    this._viewLines.dispose();
    for (const viewPart2 of this._viewParts) {
      viewPart2.dispose();
    }
    super.dispose();
  }
  _scheduleRender() {
    if (this._renderAnimationFrame === null) {
      this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), 100);
    }
  }
  _onRenderScheduled() {
    this._renderAnimationFrame = null;
    this._flushAccumulatedAndRenderNow();
  }
  _renderNow() {
    safeInvokeNoArg(() => this._actualRender());
  }
  _getViewPartsToRender() {
    const result = [];
    let resultLen = 0;
    for (const viewPart2 of this._viewParts) {
      if (viewPart2.shouldRender()) {
        result[resultLen++] = viewPart2;
      }
    }
    return result;
  }
  _actualRender() {
    if (!dom.isInDOM(this.domNode.domNode)) {
      return;
    }
    let viewPartsToRender = this._getViewPartsToRender();
    if (!this._viewLines.shouldRender() && viewPartsToRender.length === 0) {
      return;
    }
    const partialViewportData = this._context.viewLayout.getLinesViewportData();
    this._context.viewModel.setViewport(partialViewportData.startLineNumber, partialViewportData.endLineNumber, partialViewportData.centeredLineNumber);
    const viewportData = new viewLinesViewportData.ViewportData(this._selections, partialViewportData, this._context.viewLayout.getWhitespaceViewportData(), this._context.viewModel);
    if (this._contentWidgets.shouldRender()) {
      this._contentWidgets.onBeforeRender(viewportData);
    }
    if (this._viewLines.shouldRender()) {
      this._viewLines.renderText(viewportData);
      this._viewLines.onDidRender();
      viewPartsToRender = this._getViewPartsToRender();
    }
    const renderingContext$1 = new renderingContext.RenderingContext(this._context.viewLayout, viewportData, this._viewLines);
    for (const viewPart2 of viewPartsToRender) {
      viewPart2.prepareRender(renderingContext$1);
    }
    for (const viewPart2 of viewPartsToRender) {
      viewPart2.render(renderingContext$1);
      viewPart2.onDidRender();
    }
  }
  // --- BEGIN CodeEditor helpers
  delegateVerticalScrollbarMouseDown(browserEvent) {
    this._scrollbar.delegateVerticalScrollbarMouseDown(browserEvent);
  }
  restoreState(scrollPosition) {
    this._context.viewModel.viewLayout.setScrollPosition(
      { scrollTop: scrollPosition.scrollTop },
      1
      /* Immediate */
    );
    this._context.viewModel.tokenizeViewport();
    this._renderNow();
    this._viewLines.updateLineWidths();
    this._context.viewModel.viewLayout.setScrollPosition(
      { scrollLeft: scrollPosition.scrollLeft },
      1
      /* Immediate */
    );
  }
  getOffsetForColumn(modelLineNumber, modelColumn) {
    const modelPosition = this._context.viewModel.model.validatePosition({
      lineNumber: modelLineNumber,
      column: modelColumn
    });
    const viewPosition = this._context.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition);
    this._flushAccumulatedAndRenderNow();
    const visibleRange = this._viewLines.visibleRangeForPosition(new position.Position(viewPosition.lineNumber, viewPosition.column));
    if (!visibleRange) {
      return -1;
    }
    return visibleRange.left;
  }
  getTargetAtClientPoint(clientX, clientY) {
    const mouseTarget2 = this._pointerHandler.getTargetAtClientPoint(clientX, clientY);
    if (!mouseTarget2) {
      return null;
    }
    return viewUserInputEvents.ViewUserInputEvents.convertViewToModelMouseTarget(mouseTarget2, this._context.viewModel.coordinatesConverter);
  }
  createOverviewRuler(cssClassName) {
    return new overviewRuler.OverviewRuler(this._context, cssClassName);
  }
  change(callback) {
    this._viewZones.changeViewZones(callback);
    this._scheduleRender();
  }
  render(now, everything) {
    if (everything) {
      this._viewLines.forceShouldRender();
      for (const viewPart2 of this._viewParts) {
        viewPart2.forceShouldRender();
      }
    }
    if (now) {
      this._flushAccumulatedAndRenderNow();
    } else {
      this._scheduleRender();
    }
  }
  focus() {
    this._textAreaHandler.focusTextArea();
  }
  isFocused() {
    return this._textAreaHandler.isFocused();
  }
  setAriaOptions(options) {
    this._textAreaHandler.setAriaOptions(options);
  }
  addContentWidget(widgetData) {
    this._contentWidgets.addWidget(widgetData.widget);
    this.layoutContentWidget(widgetData);
    this._scheduleRender();
  }
  layoutContentWidget(widgetData) {
    let newRange = widgetData.position ? widgetData.position.range || null : null;
    if (newRange === null) {
      const newPosition = widgetData.position ? widgetData.position.position : null;
      if (newPosition !== null) {
        newRange = new range.Range(newPosition.lineNumber, newPosition.column, newPosition.lineNumber, newPosition.column);
      }
    }
    const newPreference = widgetData.position ? widgetData.position.preference : null;
    this._contentWidgets.setWidgetPosition(widgetData.widget, newRange, newPreference);
    this._scheduleRender();
  }
  removeContentWidget(widgetData) {
    this._contentWidgets.removeWidget(widgetData.widget);
    this._scheduleRender();
  }
  addOverlayWidget(widgetData) {
    this._overlayWidgets.addWidget(widgetData.widget);
    this.layoutOverlayWidget(widgetData);
    this._scheduleRender();
  }
  layoutOverlayWidget(widgetData) {
    const newPreference = widgetData.position ? widgetData.position.preference : null;
    const shouldRender = this._overlayWidgets.setWidgetPosition(widgetData.widget, newPreference);
    if (shouldRender) {
      this._scheduleRender();
    }
  }
  removeOverlayWidget(widgetData) {
    this._overlayWidgets.removeWidget(widgetData.widget);
    this._scheduleRender();
  }
}
function safeInvokeNoArg(func) {
  try {
    return func();
  } catch (e) {
    errors.onUnexpectedError(e);
  }
}
exports.View = View;
