
import { Emitter } from '../../../../../../base/common/event.js';
import { localize, localize2 } from '../../../../../../nls.js';
import { registerAction2, Action2, MenuId } from '../../../../../../platform/actions/common/actions.js';
import { IConfigurationService } from '../../../../../../platform/configuration/common/configuration.service.js';
import { Extensions } from '../../../../../../platform/configuration/common/configurationRegistry.js';
import { ContextKeyExpr } from '../../../../../../platform/contextkey/common/contextkey.js';
import { Registry } from '../../../../../../platform/registry/common/platform.js';
import { ActiveEditorContext } from '../../../../../common/contextkeys.js';
import { NOTEBOOK_ACTIONS_CATEGORY, NotebookMultiCellAction } from '../../controller/coreActions.js';
import { NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_CELL_LINE_NUMBERS } from '../../../common/notebookContextKeys.js';
import { CellContentPart } from '../cellPart.js';
import { NOTEBOOK_EDITOR_ID } from '../../../common/notebookCommon.js';

class CellEditorOptions extends CellContentPart {
    set tabSize(value) {
        if (this._tabSize !== value) {
            this._tabSize = value;
            this._onDidChange.fire();
        }
    }
    get tabSize() {
        return this._tabSize;
    }
    set indentSize(value) {
        if (this._indentSize !== value) {
            this._indentSize = value;
            this._onDidChange.fire();
        }
    }
    get indentSize() {
        return this._indentSize;
    }
    set insertSpaces(value) {
        if (this._insertSpaces !== value) {
            this._insertSpaces = value;
            this._onDidChange.fire();
        }
    }
    get insertSpaces() {
        return this._insertSpaces;
    }
    constructor(base, notebookOptions, configurationService) {
        super();
        this.base = base;
        this.notebookOptions = notebookOptions;
        this.configurationService = configurationService;
        this._lineNumbers = "inherit";
        this._onDidChange = this._register(( new Emitter()));
        this.onDidChange = this._onDidChange.event;
        this._register(base.onDidChange(() => {
            this._recomputeOptions();
        }));
        this._value = this._computeEditorOptions();
    }
    updateState(element, e) {
        if (e.cellLineNumberChanged) {
            this.setLineNumbers(element.lineNumbers);
        }
    }
    _recomputeOptions() {
        this._value = this._computeEditorOptions();
        this._onDidChange.fire();
    }
    _computeEditorOptions() {
        const value = this.base.value;
        const cellEditorOverridesRaw = this.notebookOptions.getDisplayOptions().editorOptionsCustomizations;
        const indentSize = cellEditorOverridesRaw?.["editor.indentSize"];
        if (indentSize !== undefined) {
            this.indentSize = indentSize;
        }
        const insertSpaces = cellEditorOverridesRaw?.["editor.insertSpaces"];
        if (insertSpaces !== undefined) {
            this.insertSpaces = insertSpaces;
        }
        const tabSize = cellEditorOverridesRaw?.["editor.tabSize"];
        if (tabSize !== undefined) {
            this.tabSize = tabSize;
        }
        let cellRenderLineNumber = value.lineNumbers;
        switch (this._lineNumbers) {
        case "inherit":
            if (this.configurationService.getValue("notebook.lineNumbers") === "on") {
                if (value.lineNumbers === "off") {
                    cellRenderLineNumber = "on";
                }
            } else {
                cellRenderLineNumber = "off";
            }
            break;
        case "on":
            if (value.lineNumbers === "off") {
                cellRenderLineNumber = "on";
            }
            break;
        case "off":
            cellRenderLineNumber = "off";
            break;
        }
        const overrides = {};
        if (value.lineNumbers !== cellRenderLineNumber) {
            overrides.lineNumbers = cellRenderLineNumber;
        }
        if (this.notebookOptions.getLayoutConfiguration().disableRulers) {
            overrides.rulers = [];
        }
        return {
            ...value,
            ...overrides
        };
    }
    getUpdatedValue(internalMetadata, cellUri) {
        const options = this.getValue(internalMetadata, cellUri);
        delete options.hover;
        return options;
    }
    getValue(internalMetadata, cellUri) {
        return {
            ...this._value,
            ...{
                padding: this.notebookOptions.computeEditorPadding(internalMetadata, cellUri)
            }
        };
    }
    getDefaultValue() {
        return {
            ...this._value,
            ...{
                padding: {
                    top: 12,
                    bottom: 12
                }
            }
        };
    }
    setLineNumbers(lineNumbers) {
        this._lineNumbers = lineNumbers;
        this._recomputeOptions();
    }
}
( Registry.as(Extensions.Configuration)).registerConfiguration({
    id: "notebook",
    order: 100,
    type: "object",
    "properties": {
        "notebook.lineNumbers": {
            type: "string",
            enum: ["off", "on"],
            default: "off",
            markdownDescription: ( localize(12202, "Controls the display of line numbers in the cell editor."))
        }
    }
});
registerAction2(class ToggleLineNumberAction extends Action2 {
    constructor() {
        super({
            id: "notebook.toggleLineNumbers",
            title: ( localize2(12203, "Toggle Notebook Line Numbers")),
            shortTitle: ( localize2(12204, "Line Numbers")),
            precondition: NOTEBOOK_EDITOR_FOCUSED,
            menu: [{
                id: MenuId.NotebookToolbar,
                group: "notebookLayout",
                order: 2,
                when: ( ContextKeyExpr.equals("config.notebook.globalToolbar", true))
            }],
            category: NOTEBOOK_ACTIONS_CATEGORY,
            f1: true,
            toggled: {
                condition: ( ContextKeyExpr.notEquals("config.notebook.lineNumbers", "off")),
                title: ( localize(12205, "Line Numbers"))
            }
        });
    }
    async run(accessor) {
        const configurationService = accessor.get(IConfigurationService);
        const renderLiNumbers = configurationService.getValue("notebook.lineNumbers") === "on";
        if (renderLiNumbers) {
            configurationService.updateValue("notebook.lineNumbers", "off");
        } else {
            configurationService.updateValue("notebook.lineNumbers", "on");
        }
    }
});
registerAction2(class ToggleActiveLineNumberAction extends NotebookMultiCellAction {
    constructor() {
        super({
            id: "notebook.cell.toggleLineNumbers",
            title: ( localize(12206, "Show Cell Line Numbers")),
            precondition: ( ActiveEditorContext.isEqualTo(NOTEBOOK_EDITOR_ID)),
            menu: [{
                id: MenuId.NotebookCellTitle,
                group: "View",
                order: 1
            }],
            toggled: ( ContextKeyExpr.or(( NOTEBOOK_CELL_LINE_NUMBERS.isEqualTo("on")), ( ContextKeyExpr.and(( NOTEBOOK_CELL_LINE_NUMBERS.isEqualTo("inherit")), ( ContextKeyExpr.equals("config.notebook.lineNumbers", "on"))))))
        });
    }
    async runWithContext(accessor, context) {
        if (context.ui) {
            this.updateCell(accessor.get(IConfigurationService), context.cell);
        } else {
            const configurationService = accessor.get(IConfigurationService);
            context.selectedCells.forEach(cell => {
                this.updateCell(configurationService, cell);
            });
        }
    }
    updateCell(configurationService, cell) {
        const renderLineNumbers = configurationService.getValue("notebook.lineNumbers") === "on";
        const cellLineNumbers = cell.lineNumbers;
        const currentLineNumberIsOn = cellLineNumbers === "on" || (cellLineNumbers === "inherit" && renderLineNumbers);
        if (currentLineNumberIsOn) {
            cell.lineNumbers = "off";
        } else {
            cell.lineNumbers = "on";
        }
    }
});

export { CellEditorOptions };
