import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { StandaloneColorPickerParticipant } from './colorHoverParticipant.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { EditorHoverStatusBar } from '../../hover/browser/contentHover.js';
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.service.js';
import { Emitter } from '../../../../base/common/event.js';
import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
import { registerEditorContribution } from '../../../browser/editorExtensions.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IModelService } from '../../../common/services/model.js';
import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.js';
import { DefaultDocumentColorProvider } from './defaultDocumentColorProvider.js';
import { trackFocus } from '../../../../base/browser/dom.js';
import './colorPicker.css.js';
var StandaloneColorPickerController_1, StandaloneColorPickerWidget_1;
let StandaloneColorPickerController = class StandaloneColorPickerController extends Disposable {
    static { StandaloneColorPickerController_1 = this; }
    static { this.ID = 'editor.contrib.standaloneColorPickerController'; }
    constructor(_editor, _contextKeyService, _modelService, _keybindingService, _instantiationService, _languageFeatureService, _languageConfigurationService) {
        super();
        this._editor = _editor;
        this._modelService = _modelService;
        this._keybindingService = _keybindingService;
        this._instantiationService = _instantiationService;
        this._languageFeatureService = _languageFeatureService;
        this._languageConfigurationService = _languageConfigurationService;
        this._standaloneColorPickerWidget = null;
        this._standaloneColorPickerVisible = EditorContextKeys.standaloneColorPickerVisible.bindTo(_contextKeyService);
        this._standaloneColorPickerFocused = EditorContextKeys.standaloneColorPickerFocused.bindTo(_contextKeyService);
    }
    showOrFocus() {
        if (!this._editor.hasModel()) {
            return;
        }
        if (!this._standaloneColorPickerVisible.get()) {
            this._standaloneColorPickerWidget = ( new StandaloneColorPickerWidget(
                this._editor,
                this._standaloneColorPickerVisible,
                this._standaloneColorPickerFocused,
                this._instantiationService,
                this._modelService,
                this._keybindingService,
                this._languageFeatureService,
                this._languageConfigurationService
            ));
        }
        else if (!this._standaloneColorPickerFocused.get()) {
            this._standaloneColorPickerWidget?.focus();
        }
    }
    hide() {
        this._standaloneColorPickerFocused.set(false);
        this._standaloneColorPickerVisible.set(false);
        this._standaloneColorPickerWidget?.hide();
        this._editor.focus();
    }
    insertColor() {
        this._standaloneColorPickerWidget?.updateEditor();
        this.hide();
    }
    static get(editor) {
        return editor.getContribution(StandaloneColorPickerController_1.ID);
    }
};
StandaloneColorPickerController = StandaloneColorPickerController_1 = ( __decorate([
    ( __param(1, IContextKeyService)),
    ( __param(2, IModelService)),
    ( __param(3, IKeybindingService)),
    ( __param(4, IInstantiationService)),
    ( __param(5, ILanguageFeaturesService)),
    ( __param(6, ILanguageConfigurationService))
], StandaloneColorPickerController));
registerEditorContribution(StandaloneColorPickerController.ID, StandaloneColorPickerController, 1 );
const PADDING = 8;
const CLOSE_BUTTON_WIDTH = 22;
let StandaloneColorPickerWidget = class StandaloneColorPickerWidget extends Disposable {
    static { StandaloneColorPickerWidget_1 = this; }
    static { this.ID = 'editor.contrib.standaloneColorPickerWidget'; }
    constructor(_editor, _standaloneColorPickerVisible, _standaloneColorPickerFocused, _instantiationService, _modelService, _keybindingService, _languageFeaturesService, _languageConfigurationService) {
        super();
        this._editor = _editor;
        this._standaloneColorPickerVisible = _standaloneColorPickerVisible;
        this._standaloneColorPickerFocused = _standaloneColorPickerFocused;
        this._modelService = _modelService;
        this._keybindingService = _keybindingService;
        this._languageFeaturesService = _languageFeaturesService;
        this._languageConfigurationService = _languageConfigurationService;
        this.allowEditorOverflow = true;
        this._position = undefined;
        this._body = document.createElement('div');
        this._colorHover = null;
        this._selectionSetInEditor = false;
        this._onResult = this._register(( new Emitter()));
        this.onResult = this._onResult.event;
        this._standaloneColorPickerVisible.set(true);
        this._standaloneColorPickerParticipant = _instantiationService.createInstance(StandaloneColorPickerParticipant, this._editor);
        this._position = this._editor._getViewModel()?.getPrimaryCursorState().modelState.position;
        const editorSelection = this._editor.getSelection();
        const selection = editorSelection ?
            {
                startLineNumber: editorSelection.startLineNumber,
                startColumn: editorSelection.startColumn,
                endLineNumber: editorSelection.endLineNumber,
                endColumn: editorSelection.endColumn
            } : { startLineNumber: 0, endLineNumber: 0, endColumn: 0, startColumn: 0 };
        const focusTracker = this._register(trackFocus(this._body));
        this._register(focusTracker.onDidBlur(_ => {
            this.hide();
        }));
        this._register(focusTracker.onDidFocus(_ => {
            this.focus();
        }));
        this._register(this._editor.onDidChangeCursorPosition(() => {
            if (!this._selectionSetInEditor) {
                this.hide();
            }
            else {
                this._selectionSetInEditor = false;
            }
        }));
        this._register(this._editor.onMouseMove((e) => {
            const classList = e.target.element?.classList;
            if (classList && classList.contains('colorpicker-color-decoration')) {
                this.hide();
            }
        }));
        this._register(this.onResult((result) => {
            this._render(result.value, result.foundInEditor);
        }));
        this._start(selection);
        this._body.style.zIndex = '50';
        this._editor.addContentWidget(this);
    }
    updateEditor() {
        if (this._colorHover) {
            this._standaloneColorPickerParticipant.updateEditorModel(this._colorHover);
        }
    }
    getId() {
        return StandaloneColorPickerWidget_1.ID;
    }
    getDomNode() {
        return this._body;
    }
    getPosition() {
        if (!this._position) {
            return null;
        }
        const positionPreference = this._editor.getOption(60 ).above;
        return {
            position: this._position,
            secondaryPosition: this._position,
            preference: positionPreference ? [1 , 2 ] : [2 , 1 ],
            positionAffinity: 2
        };
    }
    hide() {
        this.dispose();
        this._standaloneColorPickerVisible.set(false);
        this._standaloneColorPickerFocused.set(false);
        this._editor.removeContentWidget(this);
        this._editor.focus();
    }
    focus() {
        this._standaloneColorPickerFocused.set(true);
        this._body.focus();
    }
    async _start(selection) {
        const computeAsyncResult = await this._computeAsync(selection);
        if (!computeAsyncResult) {
            return;
        }
        this._onResult.fire(( new StandaloneColorPickerResult(computeAsyncResult.result, computeAsyncResult.foundInEditor)));
    }
    async _computeAsync(range) {
        if (!this._editor.hasModel()) {
            return null;
        }
        const colorInfo = {
            range: range,
            color: { red: 0, green: 0, blue: 0, alpha: 1 }
        };
        const colorHoverResult = await this._standaloneColorPickerParticipant.createColorHover(colorInfo, ( new DefaultDocumentColorProvider(this._modelService, this._languageConfigurationService)), this._languageFeaturesService.colorProvider);
        if (!colorHoverResult) {
            return null;
        }
        return { result: colorHoverResult.colorHover, foundInEditor: colorHoverResult.foundInEditor };
    }
    _render(colorHover, foundInEditor) {
        const fragment = document.createDocumentFragment();
        const statusBar = this._register(( new EditorHoverStatusBar(this._keybindingService)));
        let colorPickerWidget;
        const context = {
            fragment,
            statusBar,
            setColorPicker: (widget) => colorPickerWidget = widget,
            onContentsChanged: () => { },
            hide: () => this.hide()
        };
        this._colorHover = colorHover;
        this._register(this._standaloneColorPickerParticipant.renderHoverParts(context, [colorHover]));
        if (colorPickerWidget === undefined) {
            return;
        }
        this._body.classList.add('standalone-colorpicker-body');
        this._body.style.maxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250) + 'px';
        this._body.style.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500) + 'px';
        this._body.tabIndex = 0;
        this._body.appendChild(fragment);
        colorPickerWidget.layout();
        const colorPickerBody = colorPickerWidget.body;
        const saturationBoxWidth = colorPickerBody.saturationBox.domNode.clientWidth;
        const widthOfOriginalColorBox = colorPickerBody.domNode.clientWidth - saturationBoxWidth - CLOSE_BUTTON_WIDTH - PADDING;
        const enterButton = colorPickerWidget.body.enterButton;
        enterButton?.onClicked(() => {
            this.updateEditor();
            this.hide();
        });
        const colorPickerHeader = colorPickerWidget.header;
        const pickedColorNode = colorPickerHeader.pickedColorNode;
        pickedColorNode.style.width = saturationBoxWidth + PADDING + 'px';
        const originalColorNode = colorPickerHeader.originalColorNode;
        originalColorNode.style.width = widthOfOriginalColorBox + 'px';
        const closeButton = colorPickerWidget.header.closeButton;
        closeButton?.onClicked(() => {
            this.hide();
        });
        if (foundInEditor) {
            if (enterButton) {
                enterButton.button.textContent = 'Replace';
            }
            this._selectionSetInEditor = true;
            this._editor.setSelection(colorHover.range);
        }
        this._editor.layoutContentWidget(this);
    }
};
StandaloneColorPickerWidget = StandaloneColorPickerWidget_1 = ( __decorate([
    ( __param(3, IInstantiationService)),
    ( __param(4, IModelService)),
    ( __param(5, IKeybindingService)),
    ( __param(6, ILanguageFeaturesService)),
    ( __param(7, ILanguageConfigurationService))
], StandaloneColorPickerWidget));
class StandaloneColorPickerResult {
    constructor(value, foundInEditor) {
        this.value = value;
        this.foundInEditor = foundInEditor;
    }
}
export { StandaloneColorPickerController, StandaloneColorPickerWidget };
