import { MarkupSheet2D } from './MarkupSheet2D';
import { MergableObjectState } from '../../MergableSet';
/**
 * Collection of all the {@link MarkupSheet2D} instances that have been created locally and loaded via the markup API.
 */
export class MarkupSheet2DCollection {
    observable;
    attachedTo;
    /**
     * Do not use this directly, use {@link MarkupSheet2DCollection.saveAndMerge} etc instead.
     * @hidden
     */
    _layer;
    /**
     * Do not use. This is created automatically when you call {@link MarkupSheets2DApi.getOrLoadSheets}.
     * @hidden
     */
    constructor(observable, attachedTo) {
        this.observable = observable;
        this.attachedTo = attachedTo;
    }
    *[Symbol.iterator]() {
        for (const sheet of this.sheets()) {
            yield sheet;
        }
    }
    /**
     * @param states Array of states used to filter out sheets,
     * default is [MergableObjectState.Added, MergableObjectState.Modified, MergableObjectState.Unchanged].
     *
     * @example
     * ```typescript
     * // Loops all modified sheets in this collection.
     * for(const modifiedSheets of collection.sheets([MergableObjectState.Modified])) {
     *  ...
     * }
     * ```
     */
    *sheets(states = []) {
        const statesSet = new Set(states);
        if (statesSet.size === 0) {
            statesSet.add(MergableObjectState.Added);
            statesSet.add(MergableObjectState.Modified);
            statesSet.add(MergableObjectState.Unchanged);
        }
        for (const object of this._layer.objects) {
            if (object.local instanceof MarkupSheet2D && statesSet.has(object.state)) {
                yield object.local;
            }
        }
    }
    /**
     * Creates a new markup sheet and adds it to the layer api.
     * @param id The id for the new sheet (has to be unique).
     * @param properties Properties for the sheet.
     * @returns The new markup sheet.
     */
    addSheet(id, properties) {
        const existingSheet = this.get(id);
        if (existingSheet) {
            throw new Error(`Markup sheet with id "${id}" already exists.`);
        }
        const sheet = new MarkupSheet2D(id, this, properties);
        this._layer.add(sheet);
        return sheet;
    }
    /**
     * Get a markup sheet based on id.
     * @param entityOrId Id of the markup sheet you are trying to get.
     * @returns The markup sheet if it exists, undefined if no markup sheet of that id exists.
     */
    get(entityOrId) {
        return this._layer.get(typeof entityOrId === 'string' ? entityOrId : entityOrId.id);
    }
    /**
     * Clear the layer.
     */
    clear() {
        this._layer.clear();
    }
    /**
     * `true` if a layer exists and if {@link Layer.saveAndMerge} or {@link Layer.loadAndMerge}
     * has been called successfully at least once.
     */
    get isLoaded() {
        return this._layer.isLoaded;
    }
    /**
     * Loads all existing (remote) objects from the backend and attempts to merge them into {@link objects}.
     * This may result in conflicts between the local and the remote objects. A typical example is if the same
     * object has been modified locally but also remotely (in the backend.)
     */
    loadAndMerge() {
        return this._layer.loadAndMerge();
    }
    /**
     * Get the version of the currently loaded layer. [-1] if no layer has yet been loaded.
     */
    get version() {
        return this._layer.version;
    }
    /**
     * Number of objects with conflicts in the layer. A conflict occurs if there is a mismatch between the local
     * and the remote representation of the layer. Conflicts can only occur when {@link Layer.saveAndMerge} or {@link Layer.loadAndMerge}
     * is called.
     */
    get conflictCount() {
        return this._layer.conflictCount;
    }
    /**
     * Number of objects in layer not marked with state {@link MergableObjectState.Unchanged}.
     */
    get changeCount() {
        return this._layer.changeCount;
    }
    /**
     * `true` if user has permission to update the layer.
     */
    get permission() {
        return this._layer.permission;
    }
    /**
     * Get the objects currently in the layer
     */
    get objects() {
        return this._layer.objects;
    }
    /**
     * Save the sheets using the layer api.
     * @param overwrite If true then the last version will be overwritten.
     * @returns Number of conflicts, if > 0 then save was not successfull.
     */
    async saveAndMergeSheets(overwrite = false) {
        if (this._layer.changeCount > 0) {
            return this._layer.saveAndMerge(overwrite);
        }
        else
            return 0;
    }
    /**
     * Conflicts in the layer. A conflict occurs if there is a mismatch between the local
     * and the remote representation of a object in the layer. Conflicts can only occur when {@link Layer.saveAndMerge} or {@link Layer.loadAndMerge}
     * is called.
     */
    conflicts() {
        return this._layer.conflicts;
    }
}
//# sourceMappingURL=MarkupSheet2DCollection.js.map