<script>

    // https://codesandbox.io/s/codemirror-remark-editor-4m4z9?file=/src/CodeEditor.js:374-387
    import {onDestroy, onMount} from "svelte";
    import {basicSetup, EditorView} from "codemirror";
    import {autocompletion, completionKeymap} from "@codemirror/autocomplete";
    import {Compartment, EditorState} from "@codemirror/state";
    import {keymap} from "@codemirror/view";
    import {indentWithTab} from "@codemirror/commands";
    import {markdown} from "@codemirror/lang-markdown";
    import {lintKeymap} from "@codemirror/lint";

    let parentElement;
    let codeMirrorView;
    export let value;
    export let editable = true;

    export function insertMedia(info) {
        let insertText = "";
        if (info.record._file.width > 0) {
            insertText = `![${info.record._file.originalName}](${info.url})`;
        } else {
            insertText = `[${info.record._file.originalName}](${info.originalUrl})`;
        }
        const cursor = codeMirrorView.state.selection.main.head;
        const transaction = codeMirrorView.state.update({
            changes: {
                from: cursor,
                insert: insertText,
            },
            // the next 2 lines will set the appropriate cursor position after inserting the new text.
            selection: {anchor: cursor + 1},
            scrollIntoView: true,
        });

        if (transaction) {
            codeMirrorView.dispatch(transaction);
        }
    }

    onMount(() => {
        let language = new Compartment();
        let tabSize = new Compartment();

        let state = EditorState.create({
            doc: value,
            extensions: [
                basicSetup,
                keymap.of([
                    indentWithTab,
                    ...lintKeymap,
                    ...completionKeymap
                ]),
                language.of(markdown()),
                markdown(),
                autocompletion(),
                tabSize.of(EditorState.tabSize.of(4)),
                basicSetup,
                EditorView.editable.of(editable),
                EditorView.updateListener.of(function (e) {
                    if (e.docChanged) {
                        value = e.state.doc.toString();
                    }
                }),
                EditorView.lineWrapping,
                EditorView.contentAttributes.of({spellcheck: "true"})
            ],
        });


        codeMirrorView = new EditorView({
            state,
            parent: parentElement,
        });


    });

    onDestroy(() => {
        if (codeMirrorView) {
            codeMirrorView.destroy();
        }
    });
</script>

<div class="is-editable-{editable}" bind:this={parentElement}/>
