import { getShadowRoot, getDomNodePagePosition } from "../../../../base/browser/dom.mjs";
import { ActionViewItem } from "../../../../base/browser/ui/actionbar/actionViewItems.mjs";
import { SubmenuAction, Separator } from "../../../../base/common/actions.mjs";
import { DisposableStore } from "../../../../base/common/lifecycle.mjs";
import { isIOS } from "../../../../base/common/platform.mjs";
import { registerEditorContribution, registerEditorAction, EditorAction } from "../../../browser/editorExtensions.mjs";
import { EditorContextKeys } from "../../../common/editorContextKeys.mjs";
import { localize } from "../../../../nls.mjs";
import { IMenuService, MenuId, SubmenuItemAction } from "../../../../platform/actions/common/actions.mjs";
import { IContextKeyService } from "../../../../platform/contextkey/common/contextkey.mjs";
import { IContextMenuService, IContextViewService } from "../../../../platform/contextview/browser/contextView.mjs";
import { IKeybindingService } from "../../../../platform/keybinding/common/keybinding.mjs";
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);
  };
};
let ContextMenuController = class ContextMenuController2 {
  constructor(editor, _contextMenuService, _contextViewService, _contextKeyService, _keybindingService, _menuService) {
    this._contextMenuService = _contextMenuService;
    this._contextViewService = _contextViewService;
    this._contextKeyService = _contextKeyService;
    this._keybindingService = _keybindingService;
    this._menuService = _menuService;
    this._toDispose = new DisposableStore();
    this._contextMenuIsBeingShownCount = 0;
    this._editor = editor;
    this._toDispose.add(this._editor.onContextMenu((e) => this._onContextMenu(e)));
    this._toDispose.add(this._editor.onMouseWheel((e) => {
      if (this._contextMenuIsBeingShownCount > 0) {
        const view = this._contextViewService.getContextViewElement();
        const target = e.srcElement;
        if (!(target.shadowRoot && getShadowRoot(view) === target.shadowRoot)) {
          this._contextViewService.hideContextView();
        }
      }
    }));
    this._toDispose.add(this._editor.onKeyDown((e) => {
      if (e.keyCode === 58) {
        e.preventDefault();
        e.stopPropagation();
        this.showContextMenu();
      }
    }));
  }
  static get(editor) {
    return editor.getContribution(ContextMenuController2.ID);
  }
  _onContextMenu(e) {
    if (!this._editor.hasModel()) {
      return;
    }
    if (!this._editor.getOption(
      20
      /* contextmenu */
    )) {
      this._editor.focus();
      if (e.target.position && !this._editor.getSelection().containsPosition(e.target.position)) {
        this._editor.setPosition(e.target.position);
      }
      return;
    }
    if (e.target.type === 12) {
      return;
    }
    if (e.target.type === 6 && e.target.detail.injectedText) {
      return;
    }
    e.event.preventDefault();
    e.event.stopPropagation();
    if (e.target.type !== 6 && e.target.type !== 7 && e.target.type !== 1) {
      return;
    }
    this._editor.focus();
    if (e.target.position) {
      let hasSelectionAtPosition = false;
      for (const selection of this._editor.getSelections()) {
        if (selection.containsPosition(e.target.position)) {
          hasSelectionAtPosition = true;
          break;
        }
      }
      if (!hasSelectionAtPosition) {
        this._editor.setPosition(e.target.position);
      }
    }
    let anchor = null;
    if (e.target.type !== 1) {
      anchor = { x: e.event.posx - 1, width: 2, y: e.event.posy - 1, height: 2 };
    }
    this.showContextMenu(anchor);
  }
  showContextMenu(anchor) {
    if (!this._editor.getOption(
      20
      /* contextmenu */
    )) {
      return;
    }
    if (!this._editor.hasModel()) {
      return;
    }
    if (!this._contextMenuService) {
      this._editor.focus();
      return;
    }
    const menuActions = this._getMenuActions(this._editor.getModel(), this._editor.isSimpleWidget ? MenuId.SimpleEditorContext : MenuId.EditorContext);
    if (menuActions.length > 0) {
      this._doShowContextMenu(menuActions, anchor);
    }
  }
  _getMenuActions(model, menuId) {
    const result = [];
    const menu = this._menuService.createMenu(menuId, this._contextKeyService);
    const groups = menu.getActions({ arg: model.uri });
    menu.dispose();
    for (let group of groups) {
      const [, actions] = group;
      let addedItems = 0;
      for (const action of actions) {
        if (action instanceof SubmenuItemAction) {
          const subActions = this._getMenuActions(model, action.item.submenu);
          if (subActions.length > 0) {
            result.push(new SubmenuAction(action.id, action.label, subActions));
            addedItems++;
          }
        } else {
          result.push(action);
          addedItems++;
        }
      }
      if (addedItems) {
        result.push(new Separator());
      }
    }
    if (result.length) {
      result.pop();
    }
    return result;
  }
  _doShowContextMenu(actions, anchor = null) {
    if (!this._editor.hasModel()) {
      return;
    }
    const oldHoverSetting = this._editor.getOption(
      53
      /* hover */
    );
    this._editor.updateOptions({
      hover: {
        enabled: false
      }
    });
    if (!anchor) {
      this._editor.revealPosition(
        this._editor.getPosition(),
        1
        /* Immediate */
      );
      this._editor.render();
      const cursorCoords = this._editor.getScrolledVisiblePosition(this._editor.getPosition());
      const editorCoords = getDomNodePagePosition(this._editor.getDomNode());
      const posx = editorCoords.left + cursorCoords.left;
      const posy = editorCoords.top + cursorCoords.top + cursorCoords.height;
      anchor = { x: posx, y: posy };
    }
    const useShadowDOM = this._editor.getOption(
      115
      /* useShadowDOM */
    ) && !isIOS;
    this._contextMenuIsBeingShownCount++;
    this._contextMenuService.showContextMenu({
      domForShadowRoot: useShadowDOM ? this._editor.getDomNode() : void 0,
      getAnchor: () => anchor,
      getActions: () => actions,
      getActionViewItem: (action) => {
        const keybinding = this._keybindingFor(action);
        if (keybinding) {
          return new ActionViewItem(action, action, { label: true, keybinding: keybinding.getLabel(), isMenu: true });
        }
        const customActionViewItem = action;
        if (typeof customActionViewItem.getActionViewItem === "function") {
          return customActionViewItem.getActionViewItem();
        }
        return new ActionViewItem(action, action, { icon: true, label: true, isMenu: true });
      },
      getKeyBinding: (action) => {
        return this._keybindingFor(action);
      },
      onHide: (wasCancelled) => {
        this._contextMenuIsBeingShownCount--;
        this._editor.focus();
        this._editor.updateOptions({
          hover: oldHoverSetting
        });
      }
    });
  }
  _keybindingFor(action) {
    return this._keybindingService.lookupKeybinding(action.id);
  }
  dispose() {
    if (this._contextMenuIsBeingShownCount > 0) {
      this._contextViewService.hideContextView();
    }
    this._toDispose.dispose();
  }
};
ContextMenuController.ID = "editor.contrib.contextmenu";
ContextMenuController = __decorate([
  __param(1, IContextMenuService),
  __param(2, IContextViewService),
  __param(3, IContextKeyService),
  __param(4, IKeybindingService),
  __param(5, IMenuService)
], ContextMenuController);
class ShowContextMenu extends EditorAction {
  constructor() {
    super({
      id: "editor.action.showContextMenu",
      label: localize("action.showContextMenu.label", "Show Editor Context Menu"),
      alias: "Show Editor Context Menu",
      precondition: void 0,
      kbOpts: {
        kbExpr: EditorContextKeys.textInputFocus,
        primary: 1024 | 68,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(accessor, editor) {
    var _a;
    (_a = ContextMenuController.get(editor)) === null || _a === void 0 ? void 0 : _a.showContextMenu();
  }
}
registerEditorContribution(ContextMenuController.ID, ContextMenuController);
registerEditorAction(ShowContextMenu);
export {
  ContextMenuController
};
