"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../../../base/browser/dom.js");
const globalMouseMoveMonitor = require("../../../../base/browser/globalMouseMoveMonitor.js");
const touch = require("../../../../base/browser/touch.js");
const codicons = require("../../../../base/common/codicons.js");
const event = require("../../../../base/common/event.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
require("./lightBulbWidget.css.js");
const utils = require("../../../common/model/utils.js");
const nls = require("../../../../nls.js");
const keybinding = require("../../../../platform/keybinding/common/keybinding.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);
  };
};
var LightBulbState;
(function(LightBulbState2) {
  LightBulbState2.Hidden = {
    type: 0
    /* Hidden */
  };
  class Showing {
    constructor(actions, trigger, editorPosition, widgetPosition) {
      this.actions = actions;
      this.trigger = trigger;
      this.editorPosition = editorPosition;
      this.widgetPosition = widgetPosition;
      this.type = 1;
    }
  }
  LightBulbState2.Showing = Showing;
})(LightBulbState || (LightBulbState = {}));
exports.LightBulbWidget = class LightBulbWidget extends lifecycle.Disposable {
  constructor(_editor, _quickFixActionId, _preferredFixActionId, _keybindingService) {
    super();
    this._editor = _editor;
    this._quickFixActionId = _quickFixActionId;
    this._preferredFixActionId = _preferredFixActionId;
    this._keybindingService = _keybindingService;
    this._onClick = this._register(new event.Emitter());
    this.onClick = this._onClick.event;
    this._state = LightBulbState.Hidden;
    this._domNode = document.createElement("div");
    this._domNode.className = codicons.Codicon.lightBulb.classNames;
    this._editor.addContentWidget(this);
    this._register(this._editor.onDidChangeModelContent((_) => {
      const editorModel = this._editor.getModel();
      if (this.state.type !== 1 || !editorModel || this.state.editorPosition.lineNumber >= editorModel.getLineCount()) {
        this.hide();
      }
    }));
    touch.Gesture.ignoreTarget(this._domNode);
    this._register(dom.addStandardDisposableGenericMouseDownListener(this._domNode, (e) => {
      if (this.state.type !== 1) {
        return;
      }
      this._editor.focus();
      e.preventDefault();
      const { top, height } = dom.getDomNodePagePosition(this._domNode);
      const lineHeight = this._editor.getOption(
        59
        /* lineHeight */
      );
      let pad = Math.floor(lineHeight / 3);
      if (this.state.widgetPosition.position !== null && this.state.widgetPosition.position.lineNumber < this.state.editorPosition.lineNumber) {
        pad += lineHeight;
      }
      this._onClick.fire({
        x: e.posx,
        y: top + height + pad,
        actions: this.state.actions,
        trigger: this.state.trigger
      });
    }));
    this._register(dom.addDisposableListener(this._domNode, "mouseenter", (e) => {
      if ((e.buttons & 1) !== 1) {
        return;
      }
      this.hide();
      const monitor = new globalMouseMoveMonitor.GlobalMouseMoveMonitor();
      monitor.startMonitoring(e.target, e.buttons, globalMouseMoveMonitor.standardMouseMoveMerger, () => {
      }, () => {
        monitor.dispose();
      });
    }));
    this._register(this._editor.onDidChangeConfiguration((e) => {
      if (e.hasChanged(
        57
        /* lightbulb */
      ) && !this._editor.getOption(
        57
        /* lightbulb */
      ).enabled) {
        this.hide();
      }
    }));
    this._updateLightBulbTitleAndIcon();
    this._register(this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitleAndIcon, this));
  }
  dispose() {
    super.dispose();
    this._editor.removeContentWidget(this);
  }
  getId() {
    return "LightBulbWidget";
  }
  getDomNode() {
    return this._domNode;
  }
  getPosition() {
    return this._state.type === 1 ? this._state.widgetPosition : null;
  }
  update(actions, trigger, atPosition) {
    if (actions.validActions.length <= 0) {
      return this.hide();
    }
    const options = this._editor.getOptions();
    if (!options.get(
      57
      /* lightbulb */
    ).enabled) {
      return this.hide();
    }
    const model = this._editor.getModel();
    if (!model) {
      return this.hide();
    }
    const { lineNumber, column } = model.validatePosition(atPosition);
    const tabSize = model.getOptions().tabSize;
    const fontInfo = options.get(
      44
      /* fontInfo */
    );
    const lineContent = model.getLineContent(lineNumber);
    const indent = utils.computeIndentLevel(lineContent, tabSize);
    const lineHasSpace = fontInfo.spaceWidth * indent > 22;
    const isFolded = (lineNumber2) => {
      return lineNumber2 > 2 && this._editor.getTopForLineNumber(lineNumber2) === this._editor.getTopForLineNumber(lineNumber2 - 1);
    };
    let effectiveLineNumber = lineNumber;
    if (!lineHasSpace) {
      if (lineNumber > 1 && !isFolded(lineNumber - 1)) {
        effectiveLineNumber -= 1;
      } else if (!isFolded(lineNumber + 1)) {
        effectiveLineNumber += 1;
      } else if (column * fontInfo.spaceWidth < 22) {
        return this.hide();
      }
    }
    this.state = new LightBulbState.Showing(actions, trigger, atPosition, {
      position: { lineNumber: effectiveLineNumber, column: 1 },
      preference: LightBulbWidget._posPref
    });
    this._editor.layoutContentWidget(this);
  }
  hide() {
    this.state = LightBulbState.Hidden;
    this._editor.layoutContentWidget(this);
  }
  get state() {
    return this._state;
  }
  set state(value) {
    this._state = value;
    this._updateLightBulbTitleAndIcon();
  }
  _updateLightBulbTitleAndIcon() {
    if (this.state.type === 1 && this.state.actions.hasAutoFix) {
      this._domNode.classList.remove(...codicons.Codicon.lightBulb.classNamesArray);
      this._domNode.classList.add(...codicons.Codicon.lightbulbAutofix.classNamesArray);
      const preferredKb = this._keybindingService.lookupKeybinding(this._preferredFixActionId);
      if (preferredKb) {
        this.title = nls.localize("preferredcodeActionWithKb", "Show Code Actions. Preferred Quick Fix Available ({0})", preferredKb.getLabel());
        return;
      }
    }
    this._domNode.classList.remove(...codicons.Codicon.lightbulbAutofix.classNamesArray);
    this._domNode.classList.add(...codicons.Codicon.lightBulb.classNamesArray);
    const kb = this._keybindingService.lookupKeybinding(this._quickFixActionId);
    if (kb) {
      this.title = nls.localize("codeActionWithKb", "Show Code Actions ({0})", kb.getLabel());
    } else {
      this.title = nls.localize("codeAction", "Show Code Actions");
    }
  }
  set title(value) {
    this._domNode.title = value;
  }
};
exports.LightBulbWidget._posPref = [
  0
  /* EXACT */
];
exports.LightBulbWidget = __decorate([
  __param(3, keybinding.IKeybindingService)
], exports.LightBulbWidget);
themeService.registerThemingParticipant((theme, collector) => {
  var _a;
  const editorBackgroundColor = (_a = theme.getColor(colorRegistry.editorBackground)) === null || _a === void 0 ? void 0 : _a.transparent(0.7);
  const editorLightBulbForegroundColor = theme.getColor(colorRegistry.editorLightBulbForeground);
  if (editorLightBulbForegroundColor) {
    collector.addRule(`
		.monaco-editor .contentWidgets ${codicons.Codicon.lightBulb.cssSelector} {
			color: ${editorLightBulbForegroundColor};
			background-color: ${editorBackgroundColor};
		}`);
  }
  const editorLightBulbAutoFixForegroundColor = theme.getColor(colorRegistry.editorLightBulbAutoFixForeground);
  if (editorLightBulbAutoFixForegroundColor) {
    collector.addRule(`
		.monaco-editor .contentWidgets ${codicons.Codicon.lightbulbAutofix.cssSelector} {
			color: ${editorLightBulbAutoFixForegroundColor};
			background-color: ${editorBackgroundColor};
		}`);
  }
});
