"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const arrays = require("../../../../base/common/arrays.js");
const async = require("../../../../base/common/async.js");
const htmlContent = require("../../../../base/common/htmlContent.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const markdownRenderer = require("../../markdownRenderer/browser/markdownRenderer.js");
const position = require("../../../common/core/position.js");
const range = require("../../../common/core/range.js");
const language = require("../../../common/languages/language.js");
const getHover = require("./getHover.js");
const nls = require("../../../../nls.js");
const configuration = require("../../../../platform/configuration/common/configuration.js");
const opener = require("../../../../platform/opener/common/opener.js");
const languageFeatures = require("../../../common/services/languageFeatures.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);
  };
};
const $ = dom.$;
class MarkdownHover {
  constructor(owner, range2, contents, ordinal) {
    this.owner = owner;
    this.range = range2;
    this.contents = contents;
    this.ordinal = ordinal;
  }
  isValidForHoverAnchor(anchor) {
    return anchor.type === 1 && this.range.startColumn <= anchor.range.startColumn && this.range.endColumn >= anchor.range.endColumn;
  }
}
exports.MarkdownHoverParticipant = class MarkdownHoverParticipant {
  constructor(_editor, _languageService, _openerService, _configurationService, _languageFeaturesService) {
    this._editor = _editor;
    this._languageService = _languageService;
    this._openerService = _openerService;
    this._configurationService = _configurationService;
    this._languageFeaturesService = _languageFeaturesService;
    this.hoverOrdinal = 2;
  }
  createLoadingMessage(anchor) {
    return new MarkdownHover(this, anchor.range, [new htmlContent.MarkdownString().appendText(nls.localize("modesContentHover.loading", "Loading..."))], 2e3);
  }
  computeSync(anchor, lineDecorations) {
    if (!this._editor.hasModel() || anchor.type !== 1) {
      return [];
    }
    const model = this._editor.getModel();
    const lineNumber = anchor.range.startLineNumber;
    const maxColumn = model.getLineMaxColumn(lineNumber);
    const result = [];
    let index = 1e3;
    const lineLength = model.getLineLength(lineNumber);
    const languageId = model.getLanguageIdAtPosition(anchor.range.startLineNumber, anchor.range.startColumn);
    const maxTokenizationLineLength = this._configurationService.getValue("editor.maxTokenizationLineLength", {
      overrideIdentifier: languageId
    });
    if (typeof maxTokenizationLineLength === "number" && lineLength >= maxTokenizationLineLength) {
      result.push(new MarkdownHover(this, anchor.range, [{
        value: nls.localize("too many characters", "Tokenization is skipped for long lines for performance reasons. This can be configured via `editor.maxTokenizationLineLength`.")
      }], index++));
    }
    for (const d of lineDecorations) {
      const startColumn = d.range.startLineNumber === lineNumber ? d.range.startColumn : 1;
      const endColumn = d.range.endLineNumber === lineNumber ? d.range.endColumn : maxColumn;
      const hoverMessage = d.options.hoverMessage;
      if (!hoverMessage || htmlContent.isEmptyMarkdownString(hoverMessage)) {
        continue;
      }
      const range$1 = new range.Range(anchor.range.startLineNumber, startColumn, anchor.range.startLineNumber, endColumn);
      result.push(new MarkdownHover(this, range$1, arrays.asArray(hoverMessage), index++));
    }
    return result;
  }
  computeAsync(anchor, lineDecorations, token) {
    if (!this._editor.hasModel() || anchor.type !== 1) {
      return async.AsyncIterableObject.EMPTY;
    }
    const model = this._editor.getModel();
    if (!this._languageFeaturesService.hoverProvider.has(model)) {
      return async.AsyncIterableObject.EMPTY;
    }
    const position$1 = new position.Position(anchor.range.startLineNumber, anchor.range.startColumn);
    return getHover.getHover(this._languageFeaturesService.hoverProvider, model, position$1, token).filter((item) => !htmlContent.isEmptyMarkdownString(item.hover.contents)).map((item) => {
      const rng = item.hover.range ? range.Range.lift(item.hover.range) : anchor.range;
      return new MarkdownHover(this, rng, item.hover.contents, item.ordinal);
    });
  }
  renderHoverParts(context, hoverParts) {
    return renderMarkdownHovers(context, hoverParts, this._editor, this._languageService, this._openerService);
  }
};
exports.MarkdownHoverParticipant = __decorate([
  __param(1, language.ILanguageService),
  __param(2, opener.IOpenerService),
  __param(3, configuration.IConfigurationService),
  __param(4, languageFeatures.ILanguageFeaturesService)
], exports.MarkdownHoverParticipant);
function renderMarkdownHovers(context, hoverParts, editor, languageService, openerService) {
  hoverParts.sort((a, b) => a.ordinal - b.ordinal);
  const disposables = new lifecycle.DisposableStore();
  for (const hoverPart of hoverParts) {
    for (const contents of hoverPart.contents) {
      if (htmlContent.isEmptyMarkdownString(contents)) {
        continue;
      }
      const markdownHoverElement = $("div.hover-row.markdown-hover");
      const hoverContentsElement = dom.append(markdownHoverElement, $("div.hover-contents"));
      const renderer = disposables.add(new markdownRenderer.MarkdownRenderer({ editor }, languageService, openerService));
      disposables.add(renderer.onDidRenderAsync(() => {
        hoverContentsElement.className = "hover-contents code-hover-contents";
        context.onContentsChanged();
      }));
      const renderedContents = disposables.add(renderer.render(contents));
      hoverContentsElement.appendChild(renderedContents.element);
      context.fragment.appendChild(markdownHoverElement);
    }
  }
  return disposables;
}
exports.MarkdownHover = MarkdownHover;
exports.renderMarkdownHovers = renderMarkdownHovers;
