"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const arrays = require("../../../../base/common/arrays.js");
const htmlContent = require("../../../../base/common/htmlContent.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const markdownRenderer = require("../../markdownRenderer/browser/markdownRenderer.js");
const hoverOperation = require("./hoverOperation.js");
const opener = require("../../../../platform/opener/common/opener.js");
const hoverWidget = require("../../../../base/browser/ui/hover/hoverWidget.js");
const $ = dom.$;
class MarginHoverWidget extends lifecycle.Disposable {
  constructor(editor, languageService, openerService = opener.NullOpenerService) {
    super();
    this._renderDisposeables = this._register(new lifecycle.DisposableStore());
    this._editor = editor;
    this._isVisible = false;
    this._messages = [];
    this._hover = this._register(new hoverWidget.HoverWidget());
    this._hover.containerDomNode.classList.toggle("hidden", !this._isVisible);
    this._markdownRenderer = this._register(new markdownRenderer.MarkdownRenderer({ editor: this._editor }, languageService, openerService));
    this._computer = new MarginHoverComputer(this._editor);
    this._hoverOperation = this._register(new hoverOperation.HoverOperation(this._editor, this._computer));
    this._register(this._hoverOperation.onResult((result) => {
      this._withResult(result.value);
    }));
    this._register(this._editor.onDidChangeModelDecorations(() => this._onModelDecorationsChanged()));
    this._register(this._editor.onDidChangeConfiguration((e) => {
      if (e.hasChanged(
        44
        /* fontInfo */
      )) {
        this._updateFont();
      }
    }));
    this._editor.addOverlayWidget(this);
  }
  dispose() {
    this._editor.removeOverlayWidget(this);
    super.dispose();
  }
  getId() {
    return MarginHoverWidget.ID;
  }
  getDomNode() {
    return this._hover.containerDomNode;
  }
  getPosition() {
    return null;
  }
  _updateFont() {
    const codeClasses = Array.prototype.slice.call(this._hover.contentsDomNode.getElementsByClassName("code"));
    codeClasses.forEach((node) => this._editor.applyFontInfo(node));
  }
  _onModelDecorationsChanged() {
    if (this._isVisible) {
      this._hoverOperation.cancel();
      this._hoverOperation.start(
        0
        /* Delayed */
      );
    }
  }
  startShowingAt(lineNumber) {
    if (this._computer.lineNumber === lineNumber) {
      return;
    }
    this._hoverOperation.cancel();
    this.hide();
    this._computer.lineNumber = lineNumber;
    this._hoverOperation.start(
      0
      /* Delayed */
    );
  }
  hide() {
    this._computer.lineNumber = -1;
    this._hoverOperation.cancel();
    if (!this._isVisible) {
      return;
    }
    this._isVisible = false;
    this._hover.containerDomNode.classList.toggle("hidden", !this._isVisible);
  }
  _withResult(result) {
    this._messages = result;
    if (this._messages.length > 0) {
      this._renderMessages(this._computer.lineNumber, this._messages);
    } else {
      this.hide();
    }
  }
  _renderMessages(lineNumber, messages) {
    this._renderDisposeables.clear();
    const fragment = document.createDocumentFragment();
    for (const msg of messages) {
      const markdownHoverElement = $("div.hover-row.markdown-hover");
      const hoverContentsElement = dom.append(markdownHoverElement, $("div.hover-contents"));
      const renderedContents = this._renderDisposeables.add(this._markdownRenderer.render(msg.value));
      hoverContentsElement.appendChild(renderedContents.element);
      fragment.appendChild(markdownHoverElement);
    }
    this._updateContents(fragment);
    this._showAt(lineNumber);
  }
  _updateContents(node) {
    this._hover.contentsDomNode.textContent = "";
    this._hover.contentsDomNode.appendChild(node);
    this._updateFont();
  }
  _showAt(lineNumber) {
    if (!this._isVisible) {
      this._isVisible = true;
      this._hover.containerDomNode.classList.toggle("hidden", !this._isVisible);
    }
    const editorLayout = this._editor.getLayoutInfo();
    const topForLineNumber = this._editor.getTopForLineNumber(lineNumber);
    const editorScrollTop = this._editor.getScrollTop();
    const lineHeight = this._editor.getOption(
      59
      /* lineHeight */
    );
    const nodeHeight = this._hover.containerDomNode.clientHeight;
    const top = topForLineNumber - editorScrollTop - (nodeHeight - lineHeight) / 2;
    this._hover.containerDomNode.style.left = `${editorLayout.glyphMarginLeft + editorLayout.glyphMarginWidth}px`;
    this._hover.containerDomNode.style.top = `${Math.max(Math.round(top), 0)}px`;
  }
}
MarginHoverWidget.ID = "editor.contrib.modesGlyphHoverWidget";
class MarginHoverComputer {
  constructor(_editor) {
    this._editor = _editor;
    this._lineNumber = -1;
  }
  get lineNumber() {
    return this._lineNumber;
  }
  set lineNumber(value) {
    this._lineNumber = value;
  }
  computeSync() {
    const toHoverMessage = (contents) => {
      return {
        value: contents
      };
    };
    const lineDecorations = this._editor.getLineDecorations(this._lineNumber);
    const result = [];
    if (!lineDecorations) {
      return result;
    }
    for (const d of lineDecorations) {
      if (!d.options.glyphMarginClassName) {
        continue;
      }
      const hoverMessage = d.options.glyphMarginHoverMessage;
      if (!hoverMessage || htmlContent.isEmptyMarkdownString(hoverMessage)) {
        continue;
      }
      result.push(...arrays.asArray(hoverMessage).map(toHoverMessage));
    }
    return result;
  }
}
exports.MarginHoverWidget = MarginHoverWidget;
