import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Component, ViewEncapsulation, Self, Optional, Input, Output, ViewChild, HostListener, NgModule } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import * as i3 from '@deja-js/component/core';
import { ResizeListenerModule } from '@deja-js/component/core';

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
/**
 * Configuration options for the editor.
 */
class EditorOptions {
}

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
/**
 * Monaco Editor Service
 *
 * Service used by Monaco Editor Component to load only once instance of the Monaco Editor Library
 */
class MonacoEditorService {
    /**
     * Load the Monaco Editor Library
     *
     * @return Resolved promise when the library is loaded
     */
    initMonacoLib() {
        if (!this._loading) {
            this.init();
        }
        return this._loader;
    }
    init() {
        this._loader = new Promise(resolve => {
            this._loading = true;
            const baseElement = document.getElementsByTagName('base')[0] || {};
            const baseHref = baseElement.href;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            const wnd = window;
            const basePath = wnd.MONACOEDITOR_BASEPATH || `${baseHref}assets/monaco/vs`;
            const onGotAmdLoader = () => {
                // Load monaco
                // eslint-disable-next-line @typescript-eslint/no-unsafe-call
                wnd.require.config({ paths: { vs: basePath } });
                wnd.require(['vs/editor/editor.main'], () => {
                    resolve();
                });
            };
            // Load AMD loader if necessary
            if (!wnd.require && !wnd.monaco) {
                const loaderScript = document.createElement('script');
                loaderScript.type = 'text/javascript';
                loaderScript.src = `${basePath}/loader.js`;
                loaderScript.addEventListener('load', onGotAmdLoader);
                document.body.appendChild(loaderScript);
            }
            else {
                onGotAmdLoader();
            }
        });
    }
}
MonacoEditorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: MonacoEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
MonacoEditorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: MonacoEditorService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: MonacoEditorService, decorators: [{
            type: Injectable
        }] });

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
/**
 * Monaco Editor Component for Angular
 *
 * The Monaco Editor is the code editor that powers [VS Code](https://github.com/Microsoft/vscode), a good page describing the code editor's features is [here](https://code.visualstudio.com/docs/editor/editingevolved).
 */
class DejaMonacoEditorComponent {
    /**
     * Constructor
     */
    constructor(monacoEditorService, control) {
        this.monacoEditorService = monacoEditorService;
        this.control = control;
        /**
         * Event triggered when value change
         */
        this.valueChange = new EventEmitter();
        /**
         * Event triggered when valueToCompare change
         */
        this.valueToCompareChange = new EventEmitter();
        /**
         * Event triggered when editor is initialized
         */
        this.onInit = new EventEmitter();
        this._value = '';
        this._valueToCompare = '';
        this.onTouchedCallback = () => undefined;
        this.onChangeCallback = (_) => undefined;
        console.warn('@deja-js/component/deja-monaco-editor is deprecated, and will be removed in a further version. Please use @deja-js/component/v2/monaco-editor instead.');
        if (this.control) {
            this.control.valueAccessor = this;
        }
    }
    /**
     * Content language
     */
    set language(val) {
        if (val) {
            this._language = val;
            if (this._editor) {
                this.ngAfterViewInit();
            }
        }
    }
    // @Input() public language: 'bat' | 'c' | 'cpp' | 'csharp' | 'css' | 'dockerfile' | 'fsharp' | 'go' | 'handlebars' | 'html' | 'ini' | 'jade' | 'javascript' | 'json' | 'less' | 'lua' | 'markdown' | 'objective-c' | 'php' | 'csharp' | 'plaintext' | 'postiats' | 'powershell' | 'python' | 'r' | 'razor' | 'ruby' | 'scss' | 'sql' | 'swift' | 'typescript' | 'vb' | 'xml' | 'yaml';
    /**
     * Value to compare with the Value input
     * Used only when `isDiffEditor` is set to `true`
     */
    set valueToCompare(v) {
        if (v !== this._valueToCompare) {
            this._valueToCompare = v;
            if (this._valueToCompare === undefined || !this._valueToCompare || !this._editor) {
                return;
            }
            if (this._editor.getEditorType() !== 'vs.editor.ICodeEditor') {
                this.getModifiedModel().setValue(this._valueToCompare);
            }
        }
    }
    /**
     * Value to show in the editor
     */
    set value(v) {
        if (v !== this._value) {
            this._value = v;
            if (!this._editor) {
                return;
            }
            if (this._value === undefined || !this._value) {
                this._value = '';
            }
            this.getOriginalModel().setValue(this._value);
            this.onChangeCallback(this._value);
        }
    }
    /**
* Triggered when windows is resized
* Resize the component
*/
    onResize() {
        // Manually set monaco size because MonacoEditor doesn't work with Flexbox css
        const myDiv = this.editorContent.nativeElement;
        myDiv.setAttribute('style', 'height: 100%; width: 100%;');
        if (this._editor) {
            this._editor.layout();
        }
    }
    /**
     * Load Monaco Editor library
     */
    ngAfterViewInit() {
        void this.monacoEditorService.initMonacoLib().then(() => {
            this.initEditor();
        });
    }
    /**
     * Lifecycle hook that is called when a directive, pipe or service is destroyed.
     */
    ngOnDestroy() {
        this.dispose();
    }
    /**
     * Lifecycle hook that is called when any data-bound property of a directive changes.
     */
    ngOnChanges() {
        if (this._editor) {
            this._editor.updateOptions(this.getOptions());
        }
    }
    /** From ControlValueAccessor interface */
    writeValue(value) {
        this.value = value;
    }
    /** From ControlValueAccessor interface */
    registerOnChange(fn) {
        this.onChangeCallback = fn;
    }
    /** From ControlValueAccessor interface */
    registerOnTouched(fn) {
        this.onTouchedCallback = fn;
    }
    /**
     * Destroy the monaco component
     */
    dispose() {
        const myDiv = this.editorContent.nativeElement;
        if (this._editor) {
            // this._editor.dispose();
            // eslint-disable-next-line no-loops/no-loops
            while (myDiv.hasChildNodes()) {
                myDiv.removeChild(myDiv.firstChild);
            }
            this._editor = null;
        }
    }
    /**
     * Init the component
     */
    initEditor() {
        const myDiv = this.editorContent.nativeElement;
        const options = this.getOptions();
        this.dispose();
        if (!this.isDiffEditor) {
            this._editor = this.initSimpleEditor(myDiv, options);
        }
        else {
            this._editor = this.initDiffEditor(myDiv, options);
        }
        this.onResize();
        // Trigger on change event for simple editor
        this.getOriginalModel().onDidChangeContent(() => {
            const newVal = this.getOriginalModel().getValue();
            if (this._value !== newVal) {
                this.updateValue(newVal);
            }
        });
        // Trigger on change event for diff editor
        if (this.getModifiedModel()) {
            this.getModifiedModel().onDidChangeContent(() => {
                const newVal = this.getModifiedModel().getValue();
                if (this._valueToCompare !== newVal) {
                    this.updateValueToCompare(newVal);
                }
            });
        }
        this.onInit.next(this._editor);
    }
    /**
     * Create a simple editor text
     * @param div
     * @param options
     * @return instance of monaco
     */
    initSimpleEditor(div, options) {
        return monaco.editor.create(div, options);
    }
    /**
     * Create a diff editor to compare two string (_value and _valueToCompare)
     * @param div
     * @return instance of monaco
     */
    initDiffEditor(div, options) {
        const originalModel = monaco.editor.createModel(this._value, this.language);
        const modifiedModel = monaco.editor.createModel(this._valueToCompare, this.language);
        const diffEditor = monaco.editor.createDiffEditor(div, options);
        diffEditor.setModel({
            modified: modifiedModel,
            original: originalModel
        });
        return diffEditor;
    }
    getOptions() {
        const options = new EditorOptions();
        options.experimentalScreenReader = this.experimentalScreenReader;
        options.ariaLabel = this.ariaLabel;
        options.rulers = this.rulers;
        options.wordSeparators = this.wordSeparators;
        options.selectionClipboard = this.selectionClipboard;
        options.lineNumbers = this.lineNumbers;
        options.selectOnLineNumbers = this.selectOnLineNumbers;
        options.lineNumbersMinChars = this.lineNumbersMinChars;
        options.glyphMargin = this.glyphMargin;
        options.lineDecorationsWidth = this.lineDecorationsWidth;
        options.revealHorizontalRightPadding = this.revealHorizontalRightPadding;
        options.roundedSelection = this.roundedSelection;
        options.theme = this.theme;
        options.readOnly = this.readOnly;
        options.scrollbar = this.scrollbar;
        options.overviewRulerLanes = this.overviewRulerLanes;
        options.cursorBlinking = this.cursorBlinking;
        options.mouseWheelZoom = this.mouseWheelZoom;
        options.cursorStyle = this.cursorStyle;
        options.mouseWheelZoom = this.mouseWheelZoom;
        options.fontLigatures = this.fontLigatures;
        options.disableTranslate3d = this.disableTranslate3d;
        options.hideCursorInOverviewRuler = this.hideCursorInOverviewRuler;
        options.scrollBeyondLastLine = this.scrollBeyondLastLine;
        options.automaticLayout = this.automaticLayout;
        options.wrappingColumn = this.wrappingColumn;
        options.wordWrap = this.wordWrap;
        options.wrappingIndent = this.wrappingIndent;
        options.wordWrapBreakBeforeCharacters = this.wordWrapBreakBeforeCharacters;
        options.wordWrapBreakAfterCharacters = this.wordWrapBreakAfterCharacters;
        options.wordWrapBreakObtrusiveCharacters = this.wordWrapBreakObtrusiveCharacters;
        options.stopRenderingLineAfter = this.stopRenderingLineAfter;
        options.hover = this.hover;
        options.contextmenu = this.contextmenu;
        options.mouseWheelScrollSensitivity = this.mouseWheelScrollSensitivity;
        options.quickSuggestions = this.quickSuggestions;
        options.quickSuggestionsDelay = this.quickSuggestionsDelay;
        options.parameterHints = this.parameterHints;
        options.iconsInSuggestions = this.iconsInSuggestions;
        options.autoClosingBrackets = this.autoClosingBrackets;
        options.formatOnType = this.formatOnType;
        options.suggestOnTriggerCharacters = this.suggestOnTriggerCharacters;
        options.acceptSuggestionOnEnter = this.acceptSuggestionOnEnter;
        options.snippetSuggestions = this.snippetSuggestions;
        options.tabCompletion = this.tabCompletion;
        options.wordBasedSuggestions = this.wordBasedSuggestions;
        options.selectionHighlight = this.selectionHighlight;
        options.codeLens = this.codeLens;
        options.folding = this.folding;
        options.renderWhitespace = this.renderWhitespace;
        options.renderControlCharacters = this.renderControlCharacters;
        options.renderIndentGuides = this.renderIndentGuides;
        options.renderLineHighlight = this.renderLineHighlight;
        options.useTabStops = this.useTabStops;
        options.fontFamily = this.fontFamily;
        options.fontWeight = this.fontWeight;
        options.fontSize = this.fontSize;
        options.lineHeight = this.lineHeight;
        options.formatOnPaste = this.formatOnPaste;
        options.value = this._value;
        options.language = this._language;
        Object.keys(options).forEach(key => options[key] === undefined && delete options[key]); // Remove all undefined properties
        return options;
    }
    /**
     * UpdateValue
     *
     * @param value
     */
    updateValue(value) {
        // this.value = value;
        this._value = value;
        this.valueChange.emit(value);
        this.onChangeCallback(value);
    }
    /**
     * UpdateValue
     *
     * @param value
     */
    updateValueToCompare(value) {
        // this.valueToCompare = value;
        this._valueToCompare = value;
        this.valueToCompareChange.emit(value);
    }
    getOriginalModel() {
        if (this._editor) {
            const model = this._editor.getModel();
            return model.original || model;
        }
        return undefined;
    }
    getModifiedModel() {
        if (this._editor) {
            const model = this._editor.getModel();
            return model.modified || null;
        }
        return undefined;
    }
}
DejaMonacoEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorComponent, deps: [{ token: MonacoEditorService }, { token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
DejaMonacoEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.1", type: DejaMonacoEditorComponent, selector: "deja-monaco-editor", inputs: { experimentalScreenReader: "experimentalScreenReader", ariaLabel: "ariaLabel", rulers: "rulers", wordSeparators: "wordSeparators", selectionClipboard: "selectionClipboard", lineNumbers: "lineNumbers", selectOnLineNumbers: "selectOnLineNumbers", lineNumbersMinChars: "lineNumbersMinChars", glyphMargin: "glyphMargin", lineDecorationsWidth: "lineDecorationsWidth", revealHorizontalRightPadding: "revealHorizontalRightPadding", roundedSelection: "roundedSelection", theme: "theme", readOnly: "readOnly", scrollbar: "scrollbar", fixedOverflowWidgets: "fixedOverflowWidgets", overviewRulerLanes: "overviewRulerLanes", cursorBlinking: "cursorBlinking", mouseWheelZoom: "mouseWheelZoom", cursorStyle: "cursorStyle", fontLigatures: "fontLigatures", disableTranslate3d: "disableTranslate3d", disableMonospaceOptimizations: "disableMonospaceOptimizations", hideCursorInOverviewRuler: "hideCursorInOverviewRuler", scrollBeyondLastLine: "scrollBeyondLastLine", automaticLayout: "automaticLayout", wrappingColumn: "wrappingColumn", wordWrap: "wordWrap", wrappingIndent: "wrappingIndent", wordWrapBreakBeforeCharacters: "wordWrapBreakBeforeCharacters", wordWrapBreakAfterCharacters: "wordWrapBreakAfterCharacters", wordWrapBreakObtrusiveCharacters: "wordWrapBreakObtrusiveCharacters", stopRenderingLineAfter: "stopRenderingLineAfter", hover: "hover", contextmenu: "contextmenu", mouseWheelScrollSensitivity: "mouseWheelScrollSensitivity", quickSuggestions: "quickSuggestions", quickSuggestionsDelay: "quickSuggestionsDelay", parameterHints: "parameterHints", iconsInSuggestions: "iconsInSuggestions", autoClosingBrackets: "autoClosingBrackets", formatOnType: "formatOnType", formatOnPaste: "formatOnPaste", suggestOnTriggerCharacters: "suggestOnTriggerCharacters", acceptSuggestionOnEnter: "acceptSuggestionOnEnter", acceptSuggestionOnCommitCharacter: "acceptSuggestionOnCommitCharacter", snippetSuggestions: "snippetSuggestions", emptySelectionClipboard: "emptySelectionClipboard", tabCompletion: "tabCompletion", wordBasedSuggestions: "wordBasedSuggestions", suggestFontSize: "suggestFontSize", suggestLineHeight: "suggestLineHeight", selectionHighlight: "selectionHighlight", codeLens: "codeLens", folding: "folding", renderWhitespace: "renderWhitespace", renderControlCharacters: "renderControlCharacters", renderIndentGuides: "renderIndentGuides", renderLineHighlight: "renderLineHighlight", useTabStops: "useTabStops", fontFamily: "fontFamily", fontWeight: "fontWeight", fontSize: "fontSize", lineHeight: "lineHeight", isDiffEditor: "isDiffEditor", language: "language", valueToCompare: "valueToCompare", value: "value" }, outputs: { valueChange: "valueChange", valueToCompareChange: "valueToCompareChange", onInit: "onInit" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "editorContent", first: true, predicate: ["editor"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: '<div #editor resize-listener (sizeChanged)="onResize()" class="monaco-editor"></div>', isInline: true, styles: ["deja-monaco-editor{width:100%;display:flex;flex:1 1 auto}deja-monaco-editor .monaco-editor{flex:1 1 auto}\n"], directives: [{ type: i3.DejaResizeListenerDirective, selector: "[resize-listener]", outputs: ["sizeChanged"] }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorComponent, decorators: [{
            type: Component,
            args: [{ encapsulation: ViewEncapsulation.None, selector: 'deja-monaco-editor', template: '<div #editor resize-listener (sizeChanged)="onResize()" class="monaco-editor"></div>', styles: ["deja-monaco-editor{width:100%;display:flex;flex:1 1 auto}deja-monaco-editor .monaco-editor{flex:1 1 auto}\n"] }]
        }], ctorParameters: function () {
        return [{ type: MonacoEditorService }, { type: i2.NgControl, decorators: [{
                        type: Self
                    }, {
                        type: Optional
                    }] }];
    }, propDecorators: { experimentalScreenReader: [{
                type: Input
            }], ariaLabel: [{
                type: Input
            }], rulers: [{
                type: Input
            }], wordSeparators: [{
                type: Input
            }], selectionClipboard: [{
                type: Input
            }], lineNumbers: [{
                type: Input
            }], selectOnLineNumbers: [{
                type: Input
            }], lineNumbersMinChars: [{
                type: Input
            }], glyphMargin: [{
                type: Input
            }], lineDecorationsWidth: [{
                type: Input
            }], revealHorizontalRightPadding: [{
                type: Input
            }], roundedSelection: [{
                type: Input
            }], theme: [{
                type: Input
            }], readOnly: [{
                type: Input
            }], scrollbar: [{
                type: Input
            }], fixedOverflowWidgets: [{
                type: Input
            }], overviewRulerLanes: [{
                type: Input
            }], cursorBlinking: [{
                type: Input
            }], mouseWheelZoom: [{
                type: Input
            }], cursorStyle: [{
                type: Input
            }], fontLigatures: [{
                type: Input
            }], disableTranslate3d: [{
                type: Input
            }], disableMonospaceOptimizations: [{
                type: Input
            }], hideCursorInOverviewRuler: [{
                type: Input
            }], scrollBeyondLastLine: [{
                type: Input
            }], automaticLayout: [{
                type: Input
            }], wrappingColumn: [{
                type: Input
            }], wordWrap: [{
                type: Input
            }], wrappingIndent: [{
                type: Input
            }], wordWrapBreakBeforeCharacters: [{
                type: Input
            }], wordWrapBreakAfterCharacters: [{
                type: Input
            }], wordWrapBreakObtrusiveCharacters: [{
                type: Input
            }], stopRenderingLineAfter: [{
                type: Input
            }], hover: [{
                type: Input
            }], contextmenu: [{
                type: Input
            }], mouseWheelScrollSensitivity: [{
                type: Input
            }], quickSuggestions: [{
                type: Input
            }], quickSuggestionsDelay: [{
                type: Input
            }], parameterHints: [{
                type: Input
            }], iconsInSuggestions: [{
                type: Input
            }], autoClosingBrackets: [{
                type: Input
            }], formatOnType: [{
                type: Input
            }], formatOnPaste: [{
                type: Input
            }], suggestOnTriggerCharacters: [{
                type: Input
            }], acceptSuggestionOnEnter: [{
                type: Input
            }], acceptSuggestionOnCommitCharacter: [{
                type: Input
            }], snippetSuggestions: [{
                type: Input
            }], emptySelectionClipboard: [{
                type: Input
            }], tabCompletion: [{
                type: Input
            }], wordBasedSuggestions: [{
                type: Input
            }], suggestFontSize: [{
                type: Input
            }], suggestLineHeight: [{
                type: Input
            }], selectionHighlight: [{
                type: Input
            }], codeLens: [{
                type: Input
            }], folding: [{
                type: Input
            }], renderWhitespace: [{
                type: Input
            }], renderControlCharacters: [{
                type: Input
            }], renderIndentGuides: [{
                type: Input
            }], renderLineHighlight: [{
                type: Input
            }], useTabStops: [{
                type: Input
            }], fontFamily: [{
                type: Input
            }], fontWeight: [{
                type: Input
            }], fontSize: [{
                type: Input
            }], lineHeight: [{
                type: Input
            }], isDiffEditor: [{
                type: Input
            }], language: [{
                type: Input
            }], valueToCompare: [{
                type: Input
            }], value: [{
                type: Input
            }], valueChange: [{
                type: Output
            }], valueToCompareChange: [{
                type: Output
            }], onInit: [{
                type: Output
            }], editorContent: [{
                type: ViewChild,
                args: ['editor', { static: true }]
            }], onResize: [{
                type: HostListener,
                args: ['window:resize', []]
            }] } });

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
/**
 * Configuration options for editor scrollbars
 */
class EditorScrollbarOptions {
}

/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
class DejaMonacoEditorModule {
}
DejaMonacoEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
DejaMonacoEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorModule, declarations: [DejaMonacoEditorComponent], imports: [CommonModule,
        FormsModule,
        ResizeListenerModule], exports: [DejaMonacoEditorComponent] });
DejaMonacoEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorModule, providers: [MonacoEditorService], imports: [[
            CommonModule,
            FormsModule,
            ResizeListenerModule
        ]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: DejaMonacoEditorModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [DejaMonacoEditorComponent],
                    exports: [DejaMonacoEditorComponent],
                    imports: [
                        CommonModule,
                        FormsModule,
                        ResizeListenerModule
                    ],
                    providers: [MonacoEditorService]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { DejaMonacoEditorComponent, DejaMonacoEditorModule, EditorOptions, EditorScrollbarOptions };
//# sourceMappingURL=deja-js-component-monaco-editor.mjs.map
