"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StrNode = exports.StrChunk = void 0;
const clock_1 = require("../../../json-crdt-patch/clock");
const AbstractRga_1 = require("../rga/AbstractRga");
const util_1 = require("sonic-forest/lib/util");
/**
 * @ignore
 * @category CRDT Node
 */
class StrChunk {
    constructor(id, span, str) {
        this.id = id;
        this.span = span;
        this.len = str ? span : 0;
        this.del = !str;
        this.p = undefined;
        this.l = undefined;
        this.r = undefined;
        this.p2 = undefined;
        this.l2 = undefined;
        this.r2 = undefined;
        this.s = undefined;
        this.data = str;
    }
    merge(str) {
        this.data += str;
        this.span = this.data.length;
    }
    split(ticks) {
        if (!this.del) {
            const chunk = new StrChunk((0, clock_1.tick)(this.id, ticks), this.span - ticks, this.data.slice(ticks));
            this.data = this.data.slice(0, ticks);
            this.span = ticks;
            return chunk;
        }
        const chunk = new StrChunk((0, clock_1.tick)(this.id, ticks), this.span - ticks, '');
        this.span = ticks;
        return chunk;
    }
    delete() {
        this.del = true;
        this.data = '';
    }
    clone() {
        const chunk = new StrChunk(this.id, this.span, this.data);
        return chunk;
    }
    view() {
        return this.data;
    }
}
exports.StrChunk = StrChunk;
/**
 * Represents the `str` type in JSON CRDT. The `str` type is a RGA (Replicated
 * Growable Array) of UTF-16 code units.
 *
 * @category CRDT Node
 */
class StrNode extends AbstractRga_1.AbstractRga {
    constructor() {
        // ----------------------------------------------------------------- JsonNode
        super(...arguments);
        /** @ignore */
        this._view = '';
        /** @ignore */
        this.api = undefined;
    }
    /** @ignore */
    children() { }
    /** @ignore */
    child() {
        return undefined;
    }
    /** @ignore */
    container() {
        return undefined;
    }
    view() {
        if (this._view)
            return this._view;
        let str = '';
        for (let chunk = this.first(); chunk; chunk = (0, util_1.next)(chunk))
            // TODO: Check if this optimization improves performance: if (!chunk.del) str += chunk.data;
            str += chunk.data;
        return (this._view = str);
    }
    name() {
        return 'str';
    }
    // -------------------------------------------------------------- AbstractRga
    /** @ignore */
    createChunk(id, str) {
        return new StrChunk(id, str ? str.length : 0, str || '');
    }
    /** @ignore */
    onChange() {
        this._view = '';
    }
    toStringName() {
        return this.name();
    }
}
exports.StrNode = StrNode;
//# sourceMappingURL=StrNode.js.map