
import { KeyMod as KeyMod$1, KeyCode, KeyChord } from '../../../../base/common/keyCodes.js';
import { EditorAction, registerEditorAction } from '../../../browser/editorExtensions.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { Range } from '../../../common/core/range.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.service.js';
import { BlockCommentCommand } from './blockCommentCommand.js';
import { LineCommentCommand, Type } from './lineCommentCommand.js';
import { localize, localize2 } from '../../../../nls.js';
import { MenuId } from '../../../../platform/actions/common/actions.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';

class CommentLineAction extends EditorAction {
    constructor(type, opts) {
        super(opts);
        this._type = type;
    }
    run(accessor, editor) {
        const languageConfigurationService = accessor.get(ILanguageConfigurationService);
        if (!editor.hasModel()) {
            return;
        }
        const model = editor.getModel();
        const commands = [];
        const modelOptions = model.getOptions();
        const commentsOptions = editor.getOption(EditorOption.comments);
        const selections = ( editor.getSelections().map((selection, index) => ({ selection, index, ignoreFirstLine: false })));
        selections.sort((a, b) => Range.compareRangesUsingStarts(a.selection, b.selection));
        let prev = selections[0];
        for (let i = 1; i < selections.length; i++) {
            const curr = selections[i];
            if (prev.selection.endLineNumber === curr.selection.startLineNumber) {
                if (prev.index < curr.index) {
                    curr.ignoreFirstLine = true;
                }
                else {
                    prev.ignoreFirstLine = true;
                    prev = curr;
                }
            }
        }
        for (const selection of selections) {
            commands.push(( new LineCommentCommand(
                languageConfigurationService,
                selection.selection,
                modelOptions.indentSize,
                this._type,
                commentsOptions.insertSpace,
                commentsOptions.ignoreEmptyLines,
                selection.ignoreFirstLine
            )));
        }
        editor.pushUndoStop();
        editor.executeCommands(this.id, commands);
        editor.pushUndoStop();
    }
}
class ToggleCommentLineAction extends CommentLineAction {
    constructor() {
        super(Type.Toggle, {
            id: 'editor.action.commentLine',
            label: ( localize2(958, "Toggle Line Comment")),
            precondition: EditorContextKeys.writable,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.CtrlCmd | KeyCode.Slash,
                weight: KeybindingWeight.EditorContrib
            },
            menuOpts: {
                menuId: MenuId.MenubarEditMenu,
                group: '5_insert',
                title: ( localize(959, "&&Toggle Line Comment")),
                order: 1
            }
        });
    }
}
class AddLineCommentAction extends CommentLineAction {
    constructor() {
        super(Type.ForceAdd, {
            id: 'editor.action.addCommentLine',
            label: ( localize2(960, "Add Line Comment")),
            precondition: EditorContextKeys.writable,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: KeyChord(KeyMod$1.CtrlCmd | KeyCode.KeyK, KeyMod$1.CtrlCmd | KeyCode.KeyC),
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
}
class RemoveLineCommentAction extends CommentLineAction {
    constructor() {
        super(Type.ForceRemove, {
            id: 'editor.action.removeCommentLine',
            label: ( localize2(961, "Remove Line Comment")),
            precondition: EditorContextKeys.writable,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: KeyChord(KeyMod$1.CtrlCmd | KeyCode.KeyK, KeyMod$1.CtrlCmd | KeyCode.KeyU),
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
}
class BlockCommentAction extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.blockComment',
            label: ( localize2(962, "Toggle Block Comment")),
            precondition: EditorContextKeys.writable,
            kbOpts: {
                kbExpr: EditorContextKeys.editorTextFocus,
                primary: KeyMod$1.Shift | KeyMod$1.Alt | KeyCode.KeyA,
                linux: { primary: KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.KeyA },
                weight: KeybindingWeight.EditorContrib
            },
            menuOpts: {
                menuId: MenuId.MenubarEditMenu,
                group: '5_insert',
                title: ( localize(963, "Toggle &&Block Comment")),
                order: 2
            }
        });
    }
    run(accessor, editor) {
        const languageConfigurationService = accessor.get(ILanguageConfigurationService);
        if (!editor.hasModel()) {
            return;
        }
        const commentsOptions = editor.getOption(EditorOption.comments);
        const commands = [];
        const selections = editor.getSelections();
        for (const selection of selections) {
            commands.push(( new BlockCommentCommand(selection, commentsOptions.insertSpace, languageConfigurationService)));
        }
        editor.pushUndoStop();
        editor.executeCommands(this.id, commands);
        editor.pushUndoStop();
    }
}
registerEditorAction(ToggleCommentLineAction);
registerEditorAction(AddLineCommentAction);
registerEditorAction(RemoveLineCommentAction);
registerEditorAction(BlockCommentAction);
