/**
 * Maintains a ring of stuff that has been copy / cut so you can paste any of them 🌹
 */

/** Imports */
import {replaceSelection, getSelectionOrCurrentLine} from "./monaco/monacoUtils";
import * as commands from "./commands/commands";
import * as utils from "../common/utils";
import * as ui from "./ui";
import * as uix from "./uix";

let clipboardRing: string[] = []; // New items at the head of the ring
let maxItems = 10;
let index = 0;
export function addToClipboardRing() {
    let codeEditor = uix.API.getFocusedCodeEditorIfAny();
    if (!codeEditor) return;

    index = 0; // Reset seek index

    let selected = getSelectionOrCurrentLine(codeEditor.editor);
    addSelected(selected);
}

function addSelected(selected: string): boolean {
    // Just prevents the item being added right next to each other
    let before = utils.rangeLimited({ num: index - 1, min: 0, max: clipboardRing.length - 1, loopAround: true });
    let after = utils.rangeLimited({ num: index + 1, min: 0, max: clipboardRing.length - 1, loopAround: true });
    if (clipboardRing[before] === selected
        || clipboardRing[after] === selected
        // Cause we will remove last if we get to max items, check second last too
        || clipboardRing[maxItems - 2] === selected) {
        return false;
    }

    clipboardRing.unshift(selected)
    if (clipboardRing.length > maxItems) {
        clipboardRing.pop();
    }
    // console.log(clipboardRing,index); // DEBUG
    return true;
}

export function pasteFromClipboardRing() {
    let codeEditor = uix.API.getFocusedCodeEditorIfAny();
    if (!codeEditor) return;
    const selection = codeEditor.editor.getSelection();
    let hasSelection = !selection.isEmpty();

    if (!clipboardRing.length) {
        ui.notifyInfoQuickDisappear('Clipboard Ring Empty');
        // TODO: hand over to os command + select if anything gets pasted
        return;
    }

    let item = clipboardRing[index];
    let lines = item.split('\n');
    let lastLineLength = lines[lines.length - 1].length;
    let doc = codeEditor.editor.getModel();

    /** Find the start */
    let from: EditorPosition = {
        line: selection.startLineNumber - 1,
        ch: selection.startColumn - 1
    };

    /** Also add any current selection to the clipboard ring */
    if (hasSelection) {
        let added = addSelected(codeEditor.editor.getModel().getValueInRange(selection)); // Add current selection to the ring
        if (added){
            index++;
        }
    }

    // replace selection (if any) with a new one
    // have the new item selected
    let line = lines.length > 1 ? from.line + (lines.length - 1) : from.line;
    let ch = lines.length > 1 ? lastLineLength : from.ch + item.length;
    let to = { line, ch };
    replaceSelection({editor:codeEditor.editor,newText:item});
    codeEditor.editor.setSelection({
        startLineNumber: from.line + 1,
        startColumn: from.ch + 1,
        endLineNumber: to.line + 1,
        endColumn: to.ch + 1
    });

    // update the index (and loop around)
    index = utils.rangeLimited({ num: index + 1, min: 0, max: clipboardRing.length - 1, loopAround: true });
}

commands.copy.on(() => {
    addToClipboardRing();
});

commands.cut.on(() => {
    addToClipboardRing();
});

commands.pasteFromRing.on(() => {
    pasteFromClipboardRing();
})
