"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const htmlContent = require("../../../../base/common/htmlContent.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const markdownRenderer = require("../../markdownRenderer/browser/markdownRenderer.js");
const range = require("../../../common/core/range.js");
const language = require("../../../common/languages/language.js");
const hoverTypes = require("../../hover/browser/hoverTypes.js");
const ghostTextController = require("./ghostTextController.js");
const nls = require("../../../../nls.js");
const accessibility = require("../../../../platform/accessibility/common/accessibility.js");
const actions = require("../../../../platform/actions/common/actions.js");
const commands = require("../../../../platform/commands/common/commands.js");
const contextkey = require("../../../../platform/contextkey/common/contextkey.js");
const opener = require("../../../../platform/opener/common/opener.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 InlineCompletionsHover {
  constructor(owner, range2, controller) {
    this.owner = owner;
    this.range = range2;
    this.controller = controller;
  }
  isValidForHoverAnchor(anchor) {
    return anchor.type === 1 && this.range.startColumn <= anchor.range.startColumn && this.range.endColumn >= anchor.range.endColumn;
  }
  hasMultipleSuggestions() {
    return this.controller.hasMultipleInlineCompletions();
  }
}
exports.InlineCompletionsHoverParticipant = class InlineCompletionsHoverParticipant {
  constructor(_editor, _commandService, _menuService, _contextKeyService, _languageService, _openerService, accessibilityService) {
    this._editor = _editor;
    this._commandService = _commandService;
    this._menuService = _menuService;
    this._contextKeyService = _contextKeyService;
    this._languageService = _languageService;
    this._openerService = _openerService;
    this.accessibilityService = accessibilityService;
    this.hoverOrdinal = 3;
  }
  suggestHoverAnchor(mouseEvent) {
    const controller = ghostTextController.GhostTextController.get(this._editor);
    if (!controller) {
      return null;
    }
    const target = mouseEvent.target;
    if (target.type === 8) {
      const viewZoneData = target.detail;
      if (controller.shouldShowHoverAtViewZone(viewZoneData.viewZoneId)) {
        return new hoverTypes.HoverForeignElementAnchor(1e3, this, range.Range.fromPositions(viewZoneData.positionBefore || viewZoneData.position, viewZoneData.positionBefore || viewZoneData.position));
      }
    }
    if (target.type === 7) {
      if (controller.shouldShowHoverAt(target.range)) {
        return new hoverTypes.HoverForeignElementAnchor(1e3, this, target.range);
      }
    }
    if (target.type === 6) {
      const mightBeForeignElement = target.detail.mightBeForeignElement;
      if (mightBeForeignElement && controller.shouldShowHoverAt(target.range)) {
        return new hoverTypes.HoverForeignElementAnchor(1e3, this, target.range);
      }
    }
    return null;
  }
  computeSync(anchor, lineDecorations) {
    const controller = ghostTextController.GhostTextController.get(this._editor);
    if (controller && controller.shouldShowHoverAt(anchor.range)) {
      return [new InlineCompletionsHover(this, anchor.range, controller)];
    }
    return [];
  }
  renderHoverParts(context, hoverParts) {
    const disposableStore = new lifecycle.DisposableStore();
    const part = hoverParts[0];
    if (this.accessibilityService.isScreenReaderOptimized()) {
      this.renderScreenReaderText(context, part, disposableStore);
    }
    const menu = disposableStore.add(this._menuService.createMenu(actions.MenuId.InlineCompletionsActions, this._contextKeyService));
    const previousAction = context.statusBar.addAction({
      label: nls.localize("showNextInlineSuggestion", "Next"),
      commandId: ghostTextController.ShowNextInlineSuggestionAction.ID,
      run: () => this._commandService.executeCommand(ghostTextController.ShowNextInlineSuggestionAction.ID)
    });
    const nextAction = context.statusBar.addAction({
      label: nls.localize("showPreviousInlineSuggestion", "Previous"),
      commandId: ghostTextController.ShowPreviousInlineSuggestionAction.ID,
      run: () => this._commandService.executeCommand(ghostTextController.ShowPreviousInlineSuggestionAction.ID)
    });
    context.statusBar.addAction({
      label: nls.localize("acceptInlineSuggestion", "Accept"),
      commandId: ghostTextController.commitInlineSuggestionAction.id,
      run: () => this._commandService.executeCommand(ghostTextController.commitInlineSuggestionAction.id)
    });
    const actions$1 = [previousAction, nextAction];
    for (const action of actions$1) {
      action.setEnabled(false);
    }
    part.hasMultipleSuggestions().then((hasMore) => {
      for (const action of actions$1) {
        action.setEnabled(hasMore);
      }
    });
    for (const [_, group] of menu.getActions()) {
      for (const action of group) {
        if (action instanceof actions.MenuItemAction) {
          context.statusBar.addAction({
            label: action.label,
            commandId: action.item.id,
            run: () => this._commandService.executeCommand(action.item.id)
          });
        }
      }
    }
    return disposableStore;
  }
  renderScreenReaderText(context, part, disposableStore) {
    var _a, _b;
    const $ = dom.$;
    const markdownHoverElement = $("div.hover-row.markdown-hover");
    const hoverContentsElement = dom.append(markdownHoverElement, $("div.hover-contents"));
    const renderer = disposableStore.add(new markdownRenderer.MarkdownRenderer({ editor: this._editor }, this._languageService, this._openerService));
    const render = (code) => {
      disposableStore.add(renderer.onDidRenderAsync(() => {
        hoverContentsElement.className = "hover-contents code-hover-contents";
        context.onContentsChanged();
      }));
      const inlineSuggestionAvailable = nls.localize("inlineSuggestionFollows", "Suggestion:");
      const renderedContents = disposableStore.add(renderer.render(new htmlContent.MarkdownString().appendText(inlineSuggestionAvailable).appendCodeblock("text", code)));
      hoverContentsElement.replaceChildren(renderedContents.element);
    };
    const ghostText = (_b = (_a = part.controller.activeModel) === null || _a === void 0 ? void 0 : _a.inlineCompletionsModel) === null || _b === void 0 ? void 0 : _b.ghostText;
    if (ghostText) {
      const lineText = this._editor.getModel().getLineContent(ghostText.lineNumber);
      render(ghostText.renderForScreenReader(lineText));
    }
    context.fragment.appendChild(markdownHoverElement);
  }
};
exports.InlineCompletionsHoverParticipant = __decorate([
  __param(1, commands.ICommandService),
  __param(2, actions.IMenuService),
  __param(3, contextkey.IContextKeyService),
  __param(4, language.ILanguageService),
  __param(5, opener.IOpenerService),
  __param(6, accessibility.IAccessibilityService)
], exports.InlineCompletionsHoverParticipant);
exports.InlineCompletionsHover = InlineCompletionsHover;
