/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils/internal";
import { splitMarkForMoveEffects } from "./moveEffectTable.js";
import { splitMark } from "./utils.js";
export class MarkQueue {
    constructor(list, moveEffects) {
        this.list = list;
        this.moveEffects = moveEffects;
        this.stack = [];
        this.index = 0;
        this.list = list;
    }
    isEmpty() {
        return this.peek() === undefined;
    }
    dequeue() {
        const output = this.tryDequeue();
        assert(output !== undefined, 0x4e2 /* Unexpected end of mark queue */);
        return output;
    }
    tryDequeue() {
        const mark = this.stack.length > 0 ? this.stack.pop() : this.list[this.index++];
        if (mark === undefined) {
            return undefined;
        }
        const splitMarks = splitMarkForMoveEffects(mark, this.moveEffects);
        for (let i = splitMarks.length - 1; i > 0; i--) {
            this.stack.push(splitMarks[i]);
        }
        return splitMarks[0];
    }
    /**
     * Dequeues the first `length` sized portion of the next mark,
     * or the entire next mark if `length` is longer than the mark's length.
     * @param length - The length to dequeue, measured in the input context.
     */
    dequeueUpTo(length) {
        const mark = this.dequeue();
        if (mark.count <= length) {
            return mark;
        }
        const [mark1, mark2] = splitMark(mark, length);
        this.stack.push(mark2);
        return mark1;
    }
    peek() {
        const mark = this.tryDequeue();
        if (mark !== undefined) {
            this.stack.push(mark);
        }
        return mark;
    }
}
//# sourceMappingURL=markQueue.js.map