"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const keyCodes = require("../../../../base/common/keyCodes.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const editorExtensions = require("../../../browser/editorExtensions.js");
const range = require("../../../common/core/range.js");
const editorContextKeys = require("../../../common/editorContextKeys.js");
const language = require("../../../common/languages/language.js");
const goToDefinitionAtPosition = require("../../gotoSymbol/browser/link/goToDefinitionAtPosition.js");
const contentHover = require("./contentHover.js");
const marginHover = require("./marginHover.js");
const nls = require("../../../../nls.js");
const contextkey = require("../../../../platform/contextkey/common/contextkey.js");
const instantiation = require("../../../../platform/instantiation/common/instantiation.js");
const opener = require("../../../../platform/opener/common/opener.js");
const colorRegistry = require("../../../../platform/theme/common/colorRegistry.js");
const themeService = require("../../../../platform/theme/common/themeService.js");
const hoverTypes = require("./hoverTypes.js");
const markdownHoverParticipant = require("./markdownHoverParticipant.js");
const markerHoverParticipant = require("./markerHoverParticipant.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);
  };
};
exports.ModesHoverController = class ModesHoverController {
  constructor(_editor, _instantiationService, _openerService, _languageService, _contextKeyService) {
    this._editor = _editor;
    this._instantiationService = _instantiationService;
    this._openerService = _openerService;
    this._languageService = _languageService;
    this._toUnhook = new lifecycle.DisposableStore();
    this._isMouseDown = false;
    this._hoverClicked = false;
    this._contentWidget = null;
    this._glyphWidget = null;
    this._hookEvents();
    this._didChangeConfigurationHandler = this._editor.onDidChangeConfiguration((e) => {
      if (e.hasChanged(
        53
        /* hover */
      )) {
        this._unhookEvents();
        this._hookEvents();
      }
    });
  }
  static get(editor) {
    return editor.getContribution(ModesHoverController.ID);
  }
  _hookEvents() {
    const hideWidgetsEventHandler = () => this._hideWidgets();
    const hoverOpts = this._editor.getOption(
      53
      /* hover */
    );
    this._isHoverEnabled = hoverOpts.enabled;
    this._isHoverSticky = hoverOpts.sticky;
    if (this._isHoverEnabled) {
      this._toUnhook.add(this._editor.onMouseDown((e) => this._onEditorMouseDown(e)));
      this._toUnhook.add(this._editor.onMouseUp((e) => this._onEditorMouseUp(e)));
      this._toUnhook.add(this._editor.onMouseMove((e) => this._onEditorMouseMove(e)));
      this._toUnhook.add(this._editor.onKeyDown((e) => this._onKeyDown(e)));
    } else {
      this._toUnhook.add(this._editor.onMouseMove((e) => this._onEditorMouseMove(e)));
      this._toUnhook.add(this._editor.onKeyDown((e) => this._onKeyDown(e)));
    }
    this._toUnhook.add(this._editor.onMouseLeave(hideWidgetsEventHandler));
    this._toUnhook.add(this._editor.onDidChangeModel(hideWidgetsEventHandler));
    this._toUnhook.add(this._editor.onDidScrollChange((e) => this._onEditorScrollChanged(e)));
  }
  _unhookEvents() {
    this._toUnhook.clear();
  }
  _onEditorScrollChanged(e) {
    if (e.scrollTopChanged || e.scrollLeftChanged) {
      this._hideWidgets();
    }
  }
  _onEditorMouseDown(mouseEvent) {
    this._isMouseDown = true;
    const target = mouseEvent.target;
    if (target.type === 9 && target.detail === contentHover.ContentHoverWidget.ID) {
      this._hoverClicked = true;
      return;
    }
    if (target.type === 12 && target.detail === marginHover.MarginHoverWidget.ID) {
      return;
    }
    if (target.type !== 12) {
      this._hoverClicked = false;
    }
    this._hideWidgets();
  }
  _onEditorMouseUp(mouseEvent) {
    this._isMouseDown = false;
  }
  _onEditorMouseMove(mouseEvent) {
    var _a, _b, _c, _d, _e;
    const target = mouseEvent.target;
    if (this._isMouseDown && this._hoverClicked) {
      return;
    }
    if (this._isHoverSticky && target.type === 9 && target.detail === contentHover.ContentHoverWidget.ID) {
      return;
    }
    if (this._isHoverSticky && !((_b = (_a = mouseEvent.event.browserEvent.view) === null || _a === void 0 ? void 0 : _a.getSelection()) === null || _b === void 0 ? void 0 : _b.isCollapsed)) {
      return;
    }
    if (!this._isHoverSticky && target.type === 9 && target.detail === contentHover.ContentHoverWidget.ID && ((_c = this._contentWidget) === null || _c === void 0 ? void 0 : _c.isColorPickerVisible())) {
      return;
    }
    if (this._isHoverSticky && target.type === 12 && target.detail === marginHover.MarginHoverWidget.ID) {
      return;
    }
    if (!this._isHoverEnabled) {
      this._hideWidgets();
      return;
    }
    const contentWidget = this._getOrCreateContentWidget();
    if (contentWidget.maybeShowAt(mouseEvent)) {
      (_d = this._glyphWidget) === null || _d === void 0 ? void 0 : _d.hide();
      return;
    }
    if (target.type === 2 && target.position) {
      (_e = this._contentWidget) === null || _e === void 0 ? void 0 : _e.hide();
      if (!this._glyphWidget) {
        this._glyphWidget = new marginHover.MarginHoverWidget(this._editor, this._languageService, this._openerService);
      }
      this._glyphWidget.startShowingAt(target.position.lineNumber);
      return;
    }
    this._hideWidgets();
  }
  _onKeyDown(e) {
    if (e.keyCode !== 5 && e.keyCode !== 6 && e.keyCode !== 57 && e.keyCode !== 4) {
      this._hideWidgets();
    }
  }
  _hideWidgets() {
    var _a, _b, _c;
    if (this._isMouseDown && this._hoverClicked && ((_a = this._contentWidget) === null || _a === void 0 ? void 0 : _a.isColorPickerVisible())) {
      return;
    }
    this._hoverClicked = false;
    (_b = this._glyphWidget) === null || _b === void 0 ? void 0 : _b.hide();
    (_c = this._contentWidget) === null || _c === void 0 ? void 0 : _c.hide();
  }
  _getOrCreateContentWidget() {
    if (!this._contentWidget) {
      this._contentWidget = this._instantiationService.createInstance(contentHover.ContentHoverController, this._editor);
    }
    return this._contentWidget;
  }
  isColorPickerVisible() {
    var _a;
    return ((_a = this._contentWidget) === null || _a === void 0 ? void 0 : _a.isColorPickerVisible()) || false;
  }
  showContentHover(range2, mode, focus) {
    this._getOrCreateContentWidget().startShowingAtRange(range2, mode, focus);
  }
  dispose() {
    var _a, _b;
    this._unhookEvents();
    this._toUnhook.dispose();
    this._didChangeConfigurationHandler.dispose();
    (_a = this._glyphWidget) === null || _a === void 0 ? void 0 : _a.dispose();
    (_b = this._contentWidget) === null || _b === void 0 ? void 0 : _b.dispose();
  }
};
exports.ModesHoverController.ID = "editor.contrib.hover";
exports.ModesHoverController = __decorate([
  __param(1, instantiation.IInstantiationService),
  __param(2, opener.IOpenerService),
  __param(3, language.ILanguageService),
  __param(4, contextkey.IContextKeyService)
], exports.ModesHoverController);
class ShowHoverAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.showHover",
      label: nls.localize({
        key: "showHover",
        comment: [
          "Label for action that will trigger the showing of a hover in the editor.",
          "This allows for users to show the hover without using the mouse."
        ]
      }, "Show Hover"),
      alias: "Show Hover",
      precondition: void 0,
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: keyCodes.KeyChord(
          2048 | 41,
          2048 | 39
          /* KeyI */
        ),
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(accessor, editor) {
    if (!editor.hasModel()) {
      return;
    }
    let controller = exports.ModesHoverController.get(editor);
    if (!controller) {
      return;
    }
    const position = editor.getPosition();
    const range$1 = new range.Range(position.lineNumber, position.column, position.lineNumber, position.column);
    const focus = editor.getOption(
      2
      /* accessibilitySupport */
    ) === 2;
    controller.showContentHover(range$1, 1, focus);
  }
}
class ShowDefinitionPreviewHoverAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: "editor.action.showDefinitionPreviewHover",
      label: nls.localize({
        key: "showDefinitionPreviewHover",
        comment: [
          "Label for action that will trigger the showing of definition preview hover in the editor.",
          "This allows for users to show the definition preview hover without using the mouse."
        ]
      }, "Show Definition Preview Hover"),
      alias: "Show Definition Preview Hover",
      precondition: void 0
    });
  }
  run(accessor, editor) {
    const controller = exports.ModesHoverController.get(editor);
    if (!controller) {
      return;
    }
    const position = editor.getPosition();
    if (!position) {
      return;
    }
    const range$1 = new range.Range(position.lineNumber, position.column, position.lineNumber, position.column);
    const goto = goToDefinitionAtPosition.GotoDefinitionAtPositionEditorContribution.get(editor);
    if (!goto) {
      return;
    }
    const promise = goto.startFindDefinitionFromCursor(position);
    promise.then(() => {
      controller.showContentHover(range$1, 1, true);
    });
  }
}
editorExtensions.registerEditorContribution(exports.ModesHoverController.ID, exports.ModesHoverController);
editorExtensions.registerEditorAction(ShowHoverAction);
editorExtensions.registerEditorAction(ShowDefinitionPreviewHoverAction);
hoverTypes.HoverParticipantRegistry.register(markdownHoverParticipant.MarkdownHoverParticipant);
hoverTypes.HoverParticipantRegistry.register(markerHoverParticipant.MarkerHoverParticipant);
themeService.registerThemingParticipant((theme, collector) => {
  const editorHoverHighlightColor = theme.getColor(colorRegistry.editorHoverHighlight);
  if (editorHoverHighlightColor) {
    collector.addRule(`.monaco-editor .hoverHighlight { background-color: ${editorHoverHighlightColor}; }`);
  }
  const hoverBackground = theme.getColor(colorRegistry.editorHoverBackground);
  if (hoverBackground) {
    collector.addRule(`.monaco-editor .monaco-hover { background-color: ${hoverBackground}; }`);
  }
  const hoverBorder = theme.getColor(colorRegistry.editorHoverBorder);
  if (hoverBorder) {
    collector.addRule(`.monaco-editor .monaco-hover { border: 1px solid ${hoverBorder}; }`);
    collector.addRule(`.monaco-editor .monaco-hover .hover-row:not(:first-child):not(:empty) { border-top: 1px solid ${hoverBorder.transparent(0.5)}; }`);
    collector.addRule(`.monaco-editor .monaco-hover hr { border-top: 1px solid ${hoverBorder.transparent(0.5)}; }`);
    collector.addRule(`.monaco-editor .monaco-hover hr { border-bottom: 0px solid ${hoverBorder.transparent(0.5)}; }`);
  }
  const link = theme.getColor(colorRegistry.textLinkForeground);
  if (link) {
    collector.addRule(`.monaco-editor .monaco-hover a { color: ${link}; }`);
  }
  const linkHover = theme.getColor(colorRegistry.textLinkActiveForeground);
  if (linkHover) {
    collector.addRule(`.monaco-editor .monaco-hover a:hover { color: ${linkHover}; }`);
  }
  const hoverForeground = theme.getColor(colorRegistry.editorHoverForeground);
  if (hoverForeground) {
    collector.addRule(`.monaco-editor .monaco-hover { color: ${hoverForeground}; }`);
  }
  const actionsBackground = theme.getColor(colorRegistry.editorHoverStatusBarBackground);
  if (actionsBackground) {
    collector.addRule(`.monaco-editor .monaco-hover .hover-row .actions { background-color: ${actionsBackground}; }`);
  }
  const codeBackground = theme.getColor(colorRegistry.textCodeBlockBackground);
  if (codeBackground) {
    collector.addRule(`.monaco-editor .monaco-hover code { background-color: ${codeBackground}; }`);
  }
});
