"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const scrollableElement = require("../../../../base/browser/ui/scrollbar/scrollableElement.js");
const arrays = require("../../../../base/common/arrays.js");
const color = require("../../../../base/common/color.js");
const event = require("../../../../base/common/event.js");
const labels = require("../../../../base/common/labels.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const resources = require("../../../../base/common/resources.js");
const strings = require("../../../../base/common/strings.js");
require("./media/gotoErrorWidget.css.js");
const range = require("../../../common/core/range.js");
const peekView = require("../../peekView/browser/peekView.js");
const nls = require("../../../../nls.js");
const menuEntryActionViewItem = require("../../../../platform/actions/browser/menuEntryActionViewItem.js");
const actions = require("../../../../platform/actions/common/actions.js");
const contextkey = require("../../../../platform/contextkey/common/contextkey.js");
const instantiation = require("../../../../platform/instantiation/common/instantiation.js");
const label = require("../../../../platform/label/common/label.js");
const markers = require("../../../../platform/markers/common/markers.js");
const opener = require("../../../../platform/opener/common/opener.js");
const severityIcon = require("../../../../platform/severityIcon/common/severityIcon.js");
const colorRegistry = require("../../../../platform/theme/common/colorRegistry.js");
const themeService = require("../../../../platform/theme/common/themeService.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
class MessageWidget {
  constructor(parent, editor, onRelatedInformation, _openerService, _labelService) {
    this._openerService = _openerService;
    this._labelService = _labelService;
    this._lines = 0;
    this._longestLineLength = 0;
    this._relatedDiagnostics = /* @__PURE__ */ new WeakMap();
    this._disposables = new lifecycle.DisposableStore();
    this._editor = editor;
    const domNode = document.createElement("div");
    domNode.className = "descriptioncontainer";
    this._messageBlock = document.createElement("div");
    this._messageBlock.classList.add("message");
    this._messageBlock.setAttribute("aria-live", "assertive");
    this._messageBlock.setAttribute("role", "alert");
    domNode.appendChild(this._messageBlock);
    this._relatedBlock = document.createElement("div");
    domNode.appendChild(this._relatedBlock);
    this._disposables.add(dom.addStandardDisposableListener(this._relatedBlock, "click", (event2) => {
      event2.preventDefault();
      const related = this._relatedDiagnostics.get(event2.target);
      if (related) {
        onRelatedInformation(related);
      }
    }));
    this._scrollable = new scrollableElement.ScrollableElement(domNode, {
      horizontal: 1,
      vertical: 1,
      useShadows: false,
      horizontalScrollbarSize: 6,
      verticalScrollbarSize: 6
    });
    parent.appendChild(this._scrollable.getDomNode());
    this._disposables.add(this._scrollable.onScroll((e) => {
      domNode.style.left = `-${e.scrollLeft}px`;
      domNode.style.top = `-${e.scrollTop}px`;
    }));
    this._disposables.add(this._scrollable);
  }
  dispose() {
    lifecycle.dispose(this._disposables);
  }
  update(marker) {
    const { source, message, relatedInformation, code } = marker;
    let sourceAndCodeLength = ((source === null || source === void 0 ? void 0 : source.length) || 0) + "()".length;
    if (code) {
      if (typeof code === "string") {
        sourceAndCodeLength += code.length;
      } else {
        sourceAndCodeLength += code.value.length;
      }
    }
    const lines = strings.splitLines(message);
    this._lines = lines.length;
    this._longestLineLength = 0;
    for (const line of lines) {
      this._longestLineLength = Math.max(line.length + sourceAndCodeLength, this._longestLineLength);
    }
    dom.clearNode(this._messageBlock);
    this._messageBlock.setAttribute("aria-label", this.getAriaLabel(marker));
    this._editor.applyFontInfo(this._messageBlock);
    let lastLineElement = this._messageBlock;
    for (const line of lines) {
      lastLineElement = document.createElement("div");
      lastLineElement.innerText = line;
      if (line === "") {
        lastLineElement.style.height = this._messageBlock.style.lineHeight;
      }
      this._messageBlock.appendChild(lastLineElement);
    }
    if (source || code) {
      const detailsElement = document.createElement("span");
      detailsElement.classList.add("details");
      lastLineElement.appendChild(detailsElement);
      if (source) {
        const sourceElement = document.createElement("span");
        sourceElement.innerText = source;
        sourceElement.classList.add("source");
        detailsElement.appendChild(sourceElement);
      }
      if (code) {
        if (typeof code === "string") {
          const codeElement = document.createElement("span");
          codeElement.innerText = `(${code})`;
          codeElement.classList.add("code");
          detailsElement.appendChild(codeElement);
        } else {
          this._codeLink = dom.$("a.code-link");
          this._codeLink.setAttribute("href", `${code.target.toString()}`);
          this._codeLink.onclick = (e) => {
            this._openerService.open(code.target, { allowCommands: true });
            e.preventDefault();
            e.stopPropagation();
          };
          const codeElement = dom.append(this._codeLink, dom.$("span"));
          codeElement.innerText = code.value;
          detailsElement.appendChild(this._codeLink);
        }
      }
    }
    dom.clearNode(this._relatedBlock);
    this._editor.applyFontInfo(this._relatedBlock);
    if (arrays.isNonEmptyArray(relatedInformation)) {
      const relatedInformationNode = this._relatedBlock.appendChild(document.createElement("div"));
      relatedInformationNode.style.paddingTop = `${Math.floor(this._editor.getOption(
        59
        /* lineHeight */
      ) * 0.66)}px`;
      this._lines += 1;
      for (const related of relatedInformation) {
        let container = document.createElement("div");
        let relatedResource = document.createElement("a");
        relatedResource.classList.add("filename");
        relatedResource.innerText = `${labels.getBaseLabel(related.resource)}(${related.startLineNumber}, ${related.startColumn}): `;
        relatedResource.title = this._labelService.getUriLabel(related.resource);
        this._relatedDiagnostics.set(relatedResource, related);
        let relatedMessage = document.createElement("span");
        relatedMessage.innerText = related.message;
        container.appendChild(relatedResource);
        container.appendChild(relatedMessage);
        this._lines += 1;
        relatedInformationNode.appendChild(container);
      }
    }
    const fontInfo = this._editor.getOption(
      44
      /* fontInfo */
    );
    const scrollWidth = Math.ceil(fontInfo.typicalFullwidthCharacterWidth * this._longestLineLength * 0.75);
    const scrollHeight = fontInfo.lineHeight * this._lines;
    this._scrollable.setScrollDimensions({ scrollWidth, scrollHeight });
  }
  layout(height, width) {
    this._scrollable.getDomNode().style.height = `${height}px`;
    this._scrollable.getDomNode().style.width = `${width}px`;
    this._scrollable.setScrollDimensions({ width, height });
  }
  getHeightInLines() {
    return Math.min(17, this._lines);
  }
  getAriaLabel(marker) {
    let severityLabel = "";
    switch (marker.severity) {
      case markers.MarkerSeverity.Error:
        severityLabel = nls.localize("Error", "Error");
        break;
      case markers.MarkerSeverity.Warning:
        severityLabel = nls.localize("Warning", "Warning");
        break;
      case markers.MarkerSeverity.Info:
        severityLabel = nls.localize("Info", "Info");
        break;
      case markers.MarkerSeverity.Hint:
        severityLabel = nls.localize("Hint", "Hint");
        break;
    }
    let ariaLabel = nls.localize("marker aria", "{0} at {1}. ", severityLabel, marker.startLineNumber + ":" + marker.startColumn);
    const model = this._editor.getModel();
    if (model && marker.startLineNumber <= model.getLineCount() && marker.startLineNumber >= 1) {
      const lineContent = model.getLineContent(marker.startLineNumber);
      ariaLabel = `${lineContent}, ${ariaLabel}`;
    }
    return ariaLabel;
  }
}
exports.MarkerNavigationWidget = class MarkerNavigationWidget extends peekView.PeekViewWidget {
  constructor(editor, _themeService, _openerService, _menuService, instantiationService, _contextKeyService, _labelService) {
    super(editor, { showArrow: true, showFrame: true, isAccessible: true, frameWidth: 1 }, instantiationService);
    this._themeService = _themeService;
    this._openerService = _openerService;
    this._menuService = _menuService;
    this._contextKeyService = _contextKeyService;
    this._labelService = _labelService;
    this._callOnDispose = new lifecycle.DisposableStore();
    this._onDidSelectRelatedInformation = new event.Emitter();
    this.onDidSelectRelatedInformation = this._onDidSelectRelatedInformation.event;
    this._severity = markers.MarkerSeverity.Warning;
    this._backgroundColor = color.Color.white;
    this._applyTheme(_themeService.getColorTheme());
    this._callOnDispose.add(_themeService.onDidColorThemeChange(this._applyTheme.bind(this)));
    this.create();
  }
  _applyTheme(theme) {
    this._backgroundColor = theme.getColor(editorMarkerNavigationBackground);
    let colorId = editorMarkerNavigationError;
    let headerBackground = editorMarkerNavigationErrorHeader;
    if (this._severity === markers.MarkerSeverity.Warning) {
      colorId = editorMarkerNavigationWarning;
      headerBackground = editorMarkerNavigationWarningHeader;
    } else if (this._severity === markers.MarkerSeverity.Info) {
      colorId = editorMarkerNavigationInfo;
      headerBackground = editorMarkerNavigationInfoHeader;
    }
    const frameColor = theme.getColor(colorId);
    const headerBg = theme.getColor(headerBackground);
    this.style({
      arrowColor: frameColor,
      frameColor,
      headerBackgroundColor: headerBg,
      primaryHeadingColor: theme.getColor(peekView.peekViewTitleForeground),
      secondaryHeadingColor: theme.getColor(peekView.peekViewTitleInfoForeground)
    });
  }
  _applyStyles() {
    if (this._parentContainer) {
      this._parentContainer.style.backgroundColor = this._backgroundColor ? this._backgroundColor.toString() : "";
    }
    super._applyStyles();
  }
  dispose() {
    this._callOnDispose.dispose();
    super.dispose();
  }
  _fillHead(container) {
    super._fillHead(container);
    this._disposables.add(this._actionbarWidget.actionRunner.onBeforeRun((e) => this.editor.focus()));
    const actions2 = [];
    const menu = this._menuService.createMenu(MarkerNavigationWidget.TitleMenu, this._contextKeyService);
    menuEntryActionViewItem.createAndFillInActionBarActions(menu, void 0, actions2);
    this._actionbarWidget.push(actions2, { label: false, icon: true, index: 0 });
    menu.dispose();
  }
  _fillTitleIcon(container) {
    this._icon = dom.append(container, dom.$(""));
  }
  _fillBody(container) {
    this._parentContainer = container;
    container.classList.add("marker-widget");
    this._parentContainer.tabIndex = 0;
    this._parentContainer.setAttribute("role", "tooltip");
    this._container = document.createElement("div");
    container.appendChild(this._container);
    this._message = new MessageWidget(this._container, this.editor, (related) => this._onDidSelectRelatedInformation.fire(related), this._openerService, this._labelService);
    this._disposables.add(this._message);
  }
  show() {
    throw new Error("call showAtMarker");
  }
  showAtMarker(marker, markerIdx, markerCount) {
    this._container.classList.remove("stale");
    this._message.update(marker);
    this._severity = marker.severity;
    this._applyTheme(this._themeService.getColorTheme());
    let range$1 = range.Range.lift(marker);
    const editorPosition = this.editor.getPosition();
    let position = editorPosition && range$1.containsPosition(editorPosition) ? editorPosition : range$1.getStartPosition();
    super.show(position, this.computeRequiredHeight());
    const model = this.editor.getModel();
    if (model) {
      const detail = markerCount > 1 ? nls.localize("problems", "{0} of {1} problems", markerIdx, markerCount) : nls.localize("change", "{0} of {1} problem", markerIdx, markerCount);
      this.setTitle(resources.basename(model.uri), detail);
    }
    this._icon.className = `codicon ${severityIcon.SeverityIcon.className(markers.MarkerSeverity.toSeverity(this._severity))}`;
    this.editor.revealPositionNearTop(
      position,
      0
      /* Smooth */
    );
    this.editor.focus();
  }
  updateMarker(marker) {
    this._container.classList.remove("stale");
    this._message.update(marker);
  }
  showStale() {
    this._container.classList.add("stale");
    this._relayout();
  }
  _doLayoutBody(heightInPixel, widthInPixel) {
    super._doLayoutBody(heightInPixel, widthInPixel);
    this._heightInPixel = heightInPixel;
    this._message.layout(heightInPixel, widthInPixel);
    this._container.style.height = `${heightInPixel}px`;
  }
  _onWidth(widthInPixel) {
    this._message.layout(this._heightInPixel, widthInPixel);
  }
  _relayout() {
    super._relayout(this.computeRequiredHeight());
  }
  computeRequiredHeight() {
    return 3 + this._message.getHeightInLines();
  }
};
exports.MarkerNavigationWidget.TitleMenu = new actions.MenuId("gotoErrorTitleMenu");
exports.MarkerNavigationWidget = __decorate([
  __param(1, themeService.IThemeService),
  __param(2, opener.IOpenerService),
  __param(3, actions.IMenuService),
  __param(4, instantiation.IInstantiationService),
  __param(5, contextkey.IContextKeyService),
  __param(6, label.ILabelService)
], exports.MarkerNavigationWidget);
let errorDefault = colorRegistry.oneOf(colorRegistry.editorErrorForeground, colorRegistry.editorErrorBorder);
let warningDefault = colorRegistry.oneOf(colorRegistry.editorWarningForeground, colorRegistry.editorWarningBorder);
let infoDefault = colorRegistry.oneOf(colorRegistry.editorInfoForeground, colorRegistry.editorInfoBorder);
const editorMarkerNavigationError = colorRegistry.registerColor("editorMarkerNavigationError.background", { dark: errorDefault, light: errorDefault, hc: colorRegistry.contrastBorder }, nls.localize("editorMarkerNavigationError", "Editor marker navigation widget error color."));
const editorMarkerNavigationErrorHeader = colorRegistry.registerColor("editorMarkerNavigationError.headerBackground", { dark: colorRegistry.transparent(editorMarkerNavigationError, 0.1), light: colorRegistry.transparent(editorMarkerNavigationError, 0.1), hc: null }, nls.localize("editorMarkerNavigationErrorHeaderBackground", "Editor marker navigation widget error heading background."));
const editorMarkerNavigationWarning = colorRegistry.registerColor("editorMarkerNavigationWarning.background", { dark: warningDefault, light: warningDefault, hc: colorRegistry.contrastBorder }, nls.localize("editorMarkerNavigationWarning", "Editor marker navigation widget warning color."));
const editorMarkerNavigationWarningHeader = colorRegistry.registerColor("editorMarkerNavigationWarning.headerBackground", { dark: colorRegistry.transparent(editorMarkerNavigationWarning, 0.1), light: colorRegistry.transparent(editorMarkerNavigationWarning, 0.1), hc: "#0C141F" }, nls.localize("editorMarkerNavigationWarningBackground", "Editor marker navigation widget warning heading background."));
const editorMarkerNavigationInfo = colorRegistry.registerColor("editorMarkerNavigationInfo.background", { dark: infoDefault, light: infoDefault, hc: colorRegistry.contrastBorder }, nls.localize("editorMarkerNavigationInfo", "Editor marker navigation widget info color."));
const editorMarkerNavigationInfoHeader = colorRegistry.registerColor("editorMarkerNavigationInfo.headerBackground", { dark: colorRegistry.transparent(editorMarkerNavigationInfo, 0.1), light: colorRegistry.transparent(editorMarkerNavigationInfo, 0.1), hc: null }, nls.localize("editorMarkerNavigationInfoHeaderBackground", "Editor marker navigation widget info heading background."));
const editorMarkerNavigationBackground = colorRegistry.registerColor("editorMarkerNavigation.background", { dark: colorRegistry.editorBackground, light: colorRegistry.editorBackground, hc: colorRegistry.editorBackground }, nls.localize("editorMarkerNavigationBackground", "Editor marker navigation widget background."));
exports.editorMarkerNavigationBackground = editorMarkerNavigationBackground;
exports.editorMarkerNavigationError = editorMarkerNavigationError;
exports.editorMarkerNavigationErrorHeader = editorMarkerNavigationErrorHeader;
exports.editorMarkerNavigationInfo = editorMarkerNavigationInfo;
exports.editorMarkerNavigationInfoHeader = editorMarkerNavigationInfoHeader;
exports.editorMarkerNavigationWarning = editorMarkerNavigationWarning;
exports.editorMarkerNavigationWarningHeader = editorMarkerNavigationWarningHeader;
