import { LineRange } from '../core/lineRange.js';
class LineRangeMapping {
    static inverse(mapping, originalLineCount, modifiedLineCount) {
        const result = [];
        let lastOriginalEndLineNumber = 1;
        let lastModifiedEndLineNumber = 1;
        for (const m of mapping) {
            const r = ( new LineRangeMapping(( new LineRange(lastOriginalEndLineNumber, m.original.startLineNumber)), ( new LineRange(lastModifiedEndLineNumber, m.modified.startLineNumber))));
            if (!r.modified.isEmpty) {
                result.push(r);
            }
            lastOriginalEndLineNumber = m.original.endLineNumberExclusive;
            lastModifiedEndLineNumber = m.modified.endLineNumberExclusive;
        }
        const r = ( new LineRangeMapping(( new LineRange(lastOriginalEndLineNumber, originalLineCount + 1)), ( new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1))));
        if (!r.modified.isEmpty) {
            result.push(r);
        }
        return result;
    }
    static clip(mapping, originalRange, modifiedRange) {
        const result = [];
        for (const m of mapping) {
            const original = m.original.intersect(originalRange);
            const modified = m.modified.intersect(modifiedRange);
            if (original && !original.isEmpty && modified && !modified.isEmpty) {
                result.push(( new LineRangeMapping(original, modified)));
            }
        }
        return result;
    }
    constructor(originalRange, modifiedRange) {
        this.original = originalRange;
        this.modified = modifiedRange;
    }
    toString() {
        return `{${( this.original.toString())}->${( this.modified.toString())}}`;
    }
    flip() {
        return ( new LineRangeMapping(this.modified, this.original));
    }
    join(other) {
        return ( new LineRangeMapping(this.original.join(other.original), this.modified.join(other.modified)));
    }
    get changedLineCount() {
        return Math.max(this.original.length, this.modified.length);
    }
}
class DetailedLineRangeMapping extends LineRangeMapping {
    static fromRangeMappings(rangeMappings) {
        const originalRange = LineRange.join(( rangeMappings.map(r => LineRange.fromRangeInclusive(r.originalRange))));
        const modifiedRange = LineRange.join(( rangeMappings.map(r => LineRange.fromRangeInclusive(r.modifiedRange))));
        return ( new DetailedLineRangeMapping(originalRange, modifiedRange, rangeMappings));
    }
    constructor(originalRange, modifiedRange, innerChanges) {
        super(originalRange, modifiedRange);
        this.innerChanges = innerChanges;
    }
    flip() {
        return ( new DetailedLineRangeMapping(this.modified, this.original, this.innerChanges?.map(c => c.flip())));
    }
    withInnerChangesFromLineRanges() {
        return ( new DetailedLineRangeMapping(this.original, this.modified, [
            ( new RangeMapping(this.original.toExclusiveRange(), this.modified.toExclusiveRange())),
        ]));
    }
}
class RangeMapping {
    constructor(originalRange, modifiedRange) {
        this.originalRange = originalRange;
        this.modifiedRange = modifiedRange;
    }
    toString() {
        return `{${( this.originalRange.toString())}->${( this.modifiedRange.toString())}}`;
    }
    flip() {
        return ( new RangeMapping(this.modifiedRange, this.originalRange));
    }
}
export { DetailedLineRangeMapping, LineRangeMapping, RangeMapping };
