
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { getShadowRoot, getDomNodePagePosition } from '../../../../base/browser/dom.js';
import { ActionViewItem } from '../../../../base/browser/ui/actionbar/actionViewItems.js';
import { SubmenuAction, Separator } from '../../../../base/common/actions.js';
import { KeyCode, KeyMod as KeyMod$1 } from '../../../../base/common/keyCodes.js';
import { DisposableStore } from '../../../../base/common/lifecycle.js';
import { isIOS } from '../../../../base/common/platform.js';
import { MouseTargetType } from '../../../browser/editorBrowser.js';
import { EditorAction, registerEditorContribution, EditorContributionInstantiation, registerEditorAction } from '../../../browser/editorExtensions.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { ScrollType } from '../../../common/editorCommon.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { localize, localize2 } from '../../../../nls.js';
import { SubmenuItemAction } from '../../../../platform/actions/common/actions.js';
import { IMenuService } from '../../../../platform/actions/common/actions.service.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IContextMenuService, IContextViewService } from '../../../../platform/contextview/browser/contextView.service.js';
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.service.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { isStandaloneEditorWorkspace } from '../../../../platform/workspace/common/workspace.js';
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.service.js';

var ContextMenuController_1;
let ContextMenuController = class ContextMenuController {
    static { ContextMenuController_1 = this; }
    static { this.ID = 'editor.contrib.contextmenu'; }
    static get(editor) {
        return editor.getContribution(ContextMenuController_1.ID);
    }
    constructor(editor, _contextMenuService, _contextViewService, _contextKeyService, _keybindingService, _menuService, _configurationService, _workspaceContextService) {
        this._contextMenuService = _contextMenuService;
        this._contextViewService = _contextViewService;
        this._contextKeyService = _contextKeyService;
        this._keybindingService = _keybindingService;
        this._menuService = _menuService;
        this._configurationService = _configurationService;
        this._workspaceContextService = _workspaceContextService;
        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 (!this._editor.getOption(EditorOption.contextmenu)) {
                return;
            }
            if (e.keyCode === KeyCode.ContextMenu) {
                e.preventDefault();
                e.stopPropagation();
                this.showContextMenu();
            }
        }));
    }
    _onContextMenu(e) {
        if (!this._editor.hasModel()) {
            return;
        }
        if (!this._editor.getOption(EditorOption.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 === MouseTargetType.OVERLAY_WIDGET) {
            return;
        }
        if (e.target.type === MouseTargetType.CONTENT_TEXT && e.target.detail.injectedText) {
            return;
        }
        e.event.preventDefault();
        e.event.stopPropagation();
        if (e.target.type === MouseTargetType.SCROLLBAR) {
            return this._showScrollbarContextMenu(e.event);
        }
        if (e.target.type !== MouseTargetType.CONTENT_TEXT && e.target.type !== MouseTargetType.CONTENT_EMPTY && e.target.type !== MouseTargetType.TEXTAREA) {
            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 !== MouseTargetType.TEXTAREA) {
            anchor = e.event;
        }
        this.showContextMenu(anchor);
    }
    showContextMenu(anchor) {
        if (!this._editor.getOption(EditorOption.contextmenu)) {
            return;
        }
        if (!this._editor.hasModel()) {
            return;
        }
        const menuActions = this._getMenuActions(this._editor.getModel(), this._editor.contextMenuId);
        if (menuActions.length > 0) {
            this._doShowContextMenu(menuActions, anchor);
        }
    }
    _getMenuActions(model, menuId) {
        const result = [];
        const groups = this._menuService.getMenuActions(menuId, this._contextKeyService, { arg: model.uri });
        for (const 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, event = null) {
        if (!this._editor.hasModel()) {
            return;
        }
        const oldHoverSetting = this._editor.getOption(EditorOption.hover);
        this._editor.updateOptions({
            hover: {
                enabled: false
            }
        });
        let anchor = event;
        if (!anchor) {
            this._editor.revealPosition(this._editor.getPosition(), ScrollType.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(EditorOption.useShadowDOM) && !isIOS;
        this._contextMenuIsBeingShownCount++;
        this._contextMenuService.showContextMenu({
            domForShadowRoot: useShadowDOM ? this._editor.getOverflowWidgetsDomNode() ?? this._editor.getDomNode() : undefined,
            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.updateOptions({
                    hover: oldHoverSetting
                });
            }
        });
    }
    _showScrollbarContextMenu(anchor) {
        if (!this._editor.hasModel()) {
            return;
        }
        if (isStandaloneEditorWorkspace(this._workspaceContextService.getWorkspace())) {
            return;
        }
        const minimapOptions = this._editor.getOption(EditorOption.minimap);
        let lastId = 0;
        const createAction = (opts) => {
            return {
                id: `menu-action-${++lastId}`,
                label: opts.label,
                tooltip: '',
                class: undefined,
                enabled: (typeof opts.enabled === 'undefined' ? true : opts.enabled),
                checked: opts.checked,
                run: opts.run
            };
        };
        const createSubmenuAction = (label, actions) => {
            return ( new SubmenuAction(`menu-action-${++lastId}`, label, actions, undefined));
        };
        const createEnumAction = (label, enabled, configName, configuredValue, options) => {
            if (!enabled) {
                return createAction({ label, enabled, run: () => { } });
            }
            const createRunner = (value) => {
                return () => {
                    this._configurationService.updateValue(configName, value);
                };
            };
            const actions = [];
            for (const option of options) {
                actions.push(createAction({
                    label: option.label,
                    checked: configuredValue === option.value,
                    run: createRunner(option.value)
                }));
            }
            return createSubmenuAction(label, actions);
        };
        const actions = [];
        actions.push(createAction({
            label: ( localize(916, "Minimap")),
            checked: minimapOptions.enabled,
            run: () => {
                this._configurationService.updateValue(`editor.minimap.enabled`, !minimapOptions.enabled);
            }
        }));
        actions.push(( new Separator()));
        actions.push(createAction({
            label: ( localize(917, "Render Characters")),
            enabled: minimapOptions.enabled,
            checked: minimapOptions.renderCharacters,
            run: () => {
                this._configurationService.updateValue(`editor.minimap.renderCharacters`, !minimapOptions.renderCharacters);
            }
        }));
        actions.push(createEnumAction(( localize(918, "Vertical size")), minimapOptions.enabled, 'editor.minimap.size', minimapOptions.size, [{
                label: ( localize(919, "Proportional")),
                value: 'proportional'
            }, {
                label: ( localize(920, "Fill")),
                value: 'fill'
            }, {
                label: ( localize(921, "Fit")),
                value: 'fit'
            }]));
        actions.push(createEnumAction(( localize(922, "Slider")), minimapOptions.enabled, 'editor.minimap.showSlider', minimapOptions.showSlider, [{
                label: ( localize(923, "Mouse Over")),
                value: 'mouseover'
            }, {
                label: ( localize(924, "Always")),
                value: 'always'
            }]));
        const useShadowDOM = this._editor.getOption(EditorOption.useShadowDOM) && !isIOS;
        this._contextMenuIsBeingShownCount++;
        this._contextMenuService.showContextMenu({
            domForShadowRoot: useShadowDOM ? this._editor.getDomNode() : undefined,
            getAnchor: () => anchor,
            getActions: () => actions,
            onHide: (wasCancelled) => {
                this._contextMenuIsBeingShownCount--;
                this._editor.focus();
            }
        });
    }
    _keybindingFor(action) {
        return this._keybindingService.lookupKeybinding(action.id);
    }
    dispose() {
        if (this._contextMenuIsBeingShownCount > 0) {
            this._contextViewService.hideContextView();
        }
        this._toDispose.dispose();
    }
};
ContextMenuController = ContextMenuController_1 = ( __decorate([
    ( __param(1, IContextMenuService)),
    ( __param(2, IContextViewService)),
    ( __param(3, IContextKeyService)),
    ( __param(4, IKeybindingService)),
    ( __param(5, IMenuService)),
    ( __param(6, IConfigurationService)),
    ( __param(7, IWorkspaceContextService))
], ContextMenuController));
class ShowContextMenu extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.showContextMenu',
            label: ( localize2(925, "Show Editor Context Menu")),
            precondition: undefined,
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: KeyMod$1.Shift | KeyCode.F10,
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
    run(accessor, editor) {
        ContextMenuController.get(editor)?.showContextMenu();
    }
}
registerEditorContribution(ContextMenuController.ID, ContextMenuController, EditorContributionInstantiation.BeforeFirstInteraction);
registerEditorAction(ShowContextMenu);

export { ContextMenuController };
