import { EditorState } from '@codemirror/state';
import { openSearchPanel, highlightSelectionMatches,searchKeymap } from '@codemirror/search';
import {openLintPanel, lintGutter, lintKeymap,linter,setDiagnostics,} from "@codemirror/lint"
import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands';
import { foldGutter, indentOnInput, indentUnit, bracketMatching, foldKeymap, syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
import { lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine, keymap, EditorView } from '@codemirror/view';
import {markdown} from "@codemirror/lang-markdown";
// Theme
import { oneDark } from "@codemirror/theme-one-dark";
import { LSPClient,  LSPPlugin,languageServerSupport } from "@codemirror/lsp-client";
// Language
import { xml } from "@codemirror/lang-xml";

// no error checking
function simpleWebSocketTransport(uri) {
    let handlers = [];
    let sock = new WebSocket(uri);
    sock.addEventListener("close", (event) => { alert("sock gone!")})
    sock.addEventListener("error", (event) => { alert("sock error!")})
    sock.onmessage = e => { for (let h of handlers) h(e.data.toString()); };
    return new Promise(resolve => {
        sock.onopen = () => resolve({
            send: (message) => sock.send(message),
            subscribe: (handler) => handlers.push(handler),
            unsubscribe: (handler) => handlers = handlers.filter(h => h != handler)
        });

    });
};

const baseExts = [
    lineNumbers(),
    highlightActiveLineGutter(),
    highlightSpecialChars(),
    history(),
    foldGutter(),
    lintGutter(),
    drawSelection(),
    indentUnit.of("    "),
    EditorState.allowMultipleSelections.of(true),
    EditorView.lineWrapping,
    indentOnInput(),
    bracketMatching(),
    closeBrackets(),
    autocompletion(),
    rectangularSelection(),
    crosshairCursor(),
    highlightActiveLine(),
    highlightSelectionMatches(),
    keymap.of([
        indentWithTab,
        ...closeBracketsKeymap,
        ...defaultKeymap,
        ...historyKeymap,
        ...foldKeymap,
        ...completionKeymap,
        ...searchKeymap,
        ...lintKeymap
    ]),
    xml(),
    syntaxHighlighting(defaultHighlightStyle, { fallback: true })
];

function createEditorState(initialContents, extensions,options = {}) {
   
    if (options.oneDark)
        extensions.push(oneDark);

    return EditorState.create({
        doc: initialContents,
        extensions
    });
}

function createEditorView(state, parent) {
    return new EditorView({ state, parent });
}
class xqLinter {
    constructor(parameters) {
      this.fred=parameters;  
    }
}

export { createEditorState, createEditorView, openSearchPanel,openLintPanel, languageServerSupport, baseExts , simpleWebSocketTransport,linter, LSPPlugin,setDiagnostics,xqLinter,LSPClient};