/* eslint-disable no-bitwise */
import ArenaSelection from '../helpers/ArenaSelection';
export default class ArenaHistory {
    constructor(asm) {
        this.asm = asm;
        this.log = [];
        this.currentIndex = 0;
        this.typed = false;
        this.asm.commandManager.registerCommand('undo', (textarena, selection) => this.undo(selection) || selection, false);
        this.asm.commandManager.registerShortcut('Ctrl + KeyZ', 'undo');
        this.asm.commandManager.registerCommand('redo', (textarena, selection) => this.redo(selection) || selection, false);
        this.asm.commandManager.registerShortcut('Ctrl + Shift + KeyZ', 'redo');
    }
    reset(selection) {
        this.log = [];
        this.currentIndex = 0;
        this.save(selection);
    }
    save(selection, typing = false) {
        const root = this.asm.model.model.clone();
        const sel = selection ? this.getSelectionIndexes(selection) : undefined;
        if (this.currentIndex < this.log.length - 1) {
            this.log.splice(this.currentIndex + 1);
        }
        else if (typing && this.typed) {
            this.log.splice(this.currentIndex);
        }
        if (typing) {
            this.typed = true;
        }
        this.log.push([
            root,
            sel,
        ]);
        this.currentIndex = this.log.length - 1;
    }
    undo(selection) {
        if (this.currentIndex > 0) {
            this.currentIndex -= 1;
            return this.applyCurrent();
        }
        return selection;
    }
    redo(selection) {
        if (this.currentIndex < this.log.length - 1) {
            this.currentIndex += 1;
            return this.applyCurrent();
        }
        return selection;
    }
    resetTyped() {
        this.typed = false;
    }
    applyCurrent() {
        const [root, sel] = this.log[this.currentIndex];
        const newRoot = root.clone();
        this.asm.model.setRoot(newRoot);
        return sel ? this.getSelectionFromIndexes(sel) : undefined;
    }
    getSelectionFromIndexes(sel) {
        const startNode = this.asm.model.getTextNodeById(sel[0]);
        const endNode = this.asm.model.getTextNodeById(sel[2]);
        if (startNode && endNode) {
            return new ArenaSelection(startNode, sel[1], endNode, sel[3], sel[4]);
        }
        return undefined;
    }
    getSelectionIndexes(selection) {
        return [
            selection.startNode.getGlobalIndex(),
            selection.startOffset,
            selection.endNode.getGlobalIndex(),
            selection.endOffset,
            selection.direction,
        ];
    }
}
//# sourceMappingURL=ArenaHistory.js.map