/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { refHasTileLabel } from "./referencePositions";
import { TextSegment } from "./textSegment";
function isTextAndMarkerAccumulator(accum) {
    return accum.parallelArrays === true;
}
/**
 * @deprecated  for internal use only. public export will be removed.
 * @internal
 */
export class MergeTreeTextHelper {
    constructor(mergeTree) {
        this.mergeTree = mergeTree;
        this.gatherText = (segment, pos, refSeq, clientId, start, end, accumText) => {
            var _a, _b;
            let _start = start;
            if (TextSegment.is(segment)) {
                let beginTags = "";
                let endTags = "";
                if (isTextAndMarkerAccumulator(accumText)) {
                    // TODO: let clients pass in function to get tag
                    const tags = [];
                    const initTags = [];
                    if ((_a = segment.properties) === null || _a === void 0 ? void 0 : _a["font-weight"]) {
                        tags.push("b");
                    }
                    if ((_b = segment.properties) === null || _b === void 0 ? void 0 : _b["text-decoration"]) {
                        tags.push("u");
                    }
                    const remTags = [];
                    if (tags.length > 0) {
                        for (const tag of tags) {
                            if (!accumText.tagsInProgress.includes(tag)) {
                                beginTags += `<${tag}>`;
                                initTags.push(tag);
                            }
                        }
                        for (const accumTag of accumText.tagsInProgress) {
                            if (!tags.includes(accumTag)) {
                                endTags += `</${accumTag}>`;
                                remTags.push(accumTag);
                            }
                        }
                        for (const initTag of initTags.reverse()) {
                            accumText.tagsInProgress.push(initTag);
                        }
                    }
                    else {
                        for (const accumTag of accumText.tagsInProgress) {
                            endTags += `</${accumTag}>`;
                            remTags.push(accumTag);
                        }
                    }
                    for (const remTag of remTags) {
                        const remdex = accumText.tagsInProgress.indexOf(remTag);
                        if (remdex >= 0) {
                            accumText.tagsInProgress.splice(remdex, 1);
                        }
                    }
                }
                accumText.textSegment.text += endTags;
                accumText.textSegment.text += beginTags;
                if ((_start <= 0) && (end >= segment.text.length)) {
                    accumText.textSegment.text += segment.text;
                }
                else {
                    if (_start < 0) {
                        _start = 0;
                    }
                    if (end >= segment.text.length) {
                        accumText.textSegment.text += segment.text.substring(_start);
                    }
                    else {
                        accumText.textSegment.text += segment.text.substring(_start, end);
                    }
                }
            }
            else {
                if (accumText.placeholder && (accumText.placeholder.length > 0)) {
                    if (accumText.placeholder === "*") {
                        const marker = segment;
                        accumText.textSegment.text += `\n${marker.toString()}`;
                    }
                    else {
                        for (let i = 0; i < segment.cachedLength; i++) {
                            accumText.textSegment.text += accumText.placeholder;
                        }
                    }
                }
                else if (isTextAndMarkerAccumulator(accumText)) {
                    const marker = segment;
                    if (refHasTileLabel(marker, accumText.parallelMarkerLabel)) {
                        accumText.parallelMarkers.push(marker);
                        accumText.parallelText.push(accumText.textSegment.text);
                        accumText.textSegment.text = "";
                    }
                }
            }
            return true;
        };
    }
    getTextAndMarkers(refSeq, clientId, label, start, end) {
        const range = this.getValidRange(start, end, refSeq, clientId);
        const accum = {
            parallelArrays: true,
            parallelMarkerLabel: label,
            parallelMarkers: [],
            parallelText: [],
            tagsInProgress: [],
            textSegment: new TextSegment(""),
        };
        this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
        return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };
    }
    getText(refSeq, clientId, placeholder = "", start, end) {
        const range = this.getValidRange(start, end, refSeq, clientId);
        const accum = { textSegment: new TextSegment(""), placeholder };
        this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
        return accum.textSegment.text;
    }
    getValidRange(start, end, refSeq, clientId) {
        const range = {
            end: end !== null && end !== void 0 ? end : this.mergeTree.getLength(refSeq, clientId),
            start: start !== null && start !== void 0 ? start : 0,
        };
        return range;
    }
}
//# sourceMappingURL=MergeTreeTextHelper.js.map