"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrackingGroupCollection = exports.UnorderedTrackingGroup = exports.TrackingGroup = void 0;
const sortedSegmentSet_js_1 = require("./sortedSegmentSet.js");
/**
 * @legacy
 * @alpha
 */
class TrackingGroup {
    constructor() {
        this.trackedSet = new sortedSegmentSet_js_1.SortedSegmentSet();
    }
    get tracked() {
        return this.trackedSet.items;
    }
    get size() {
        return this.trackedSet.size;
    }
    has(trackable) {
        return this.trackedSet.has(trackable);
    }
    link(trackable) {
        if (!this.trackedSet.has(trackable)) {
            this.trackedSet.addOrUpdate(trackable);
            trackable.trackingCollection.link(this);
        }
    }
    unlink(trackable) {
        if (this.trackedSet.remove(trackable)) {
            trackable.trackingCollection.unlink(this);
            return true;
        }
        return false;
    }
}
exports.TrackingGroup = TrackingGroup;
/**
 * Tracking group backed by an unordered set. Lookup, insertion, and deletion are O(1)
 */
class UnorderedTrackingGroup {
    constructor() {
        this.trackedSet = new Set();
    }
    get tracked() {
        return [...this.trackedSet];
    }
    get size() {
        return this.trackedSet.size;
    }
    has(trackable) {
        return this.trackedSet.has(trackable);
    }
    link(trackable) {
        if (!this.trackedSet.has(trackable)) {
            this.trackedSet.add(trackable);
            trackable.trackingCollection.link(this);
        }
    }
    unlink(trackable) {
        if (this.trackedSet.delete(trackable)) {
            trackable.trackingCollection.unlink(this);
            return true;
        }
        return false;
    }
}
exports.UnorderedTrackingGroup = UnorderedTrackingGroup;
/**
 * A collection of {@link ITrackingGroup}.
 * @legacy
 * @alpha
 */
class TrackingGroupCollection {
    get trackingGroups() {
        // Cast here is necessary to avoid a breaking change to
        // `TrackingGroupCollection`. Ideally we could just return
        // `Set<ITrackingGroup>`
        return this._trackingGroups;
    }
    constructor(trackable) {
        this.trackable = trackable;
        this._trackingGroups = new Set();
    }
    link(trackingGroup) {
        if (trackingGroup) {
            if (!this._trackingGroups.has(trackingGroup)) {
                this._trackingGroups.add(trackingGroup);
            }
            if (!trackingGroup.has(this.trackable)) {
                trackingGroup.link(this.trackable);
            }
        }
    }
    unlink(trackingGroup) {
        if (this._trackingGroups.has(trackingGroup)) {
            if (trackingGroup.has(this.trackable)) {
                trackingGroup.unlink(this.trackable);
            }
            this._trackingGroups.delete(trackingGroup);
            return true;
        }
        return false;
    }
    copyTo(trackable) {
        for (const sg of this._trackingGroups) {
            trackable.trackingCollection.link(sg);
        }
    }
    get empty() {
        return this._trackingGroups.size === 0;
    }
    matches(trackingCollection) {
        if (!trackingCollection ||
            this._trackingGroups.size !== trackingCollection._trackingGroups.size) {
            return false;
        }
        for (const tg of this._trackingGroups.values()) {
            if (!trackingCollection._trackingGroups.has(tg)) {
                return false;
            }
        }
        return true;
    }
}
exports.TrackingGroupCollection = TrackingGroupCollection;
//# sourceMappingURL=mergeTreeTracking.js.map