/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { EventDispatcher, Objects, } from "@vertexvis/utils";
/**
 * A model representing the state of measurement.
 *
 * Measurement contains a set of `MeasureEntity`s that represent what's being
 * measured, and a set of `MeasurementResult`s representing the results of the
 * measurement.
 *
 * Views can register event listeners to the model to be notified when new
 * measurements have been added.
 */
export class MeasurementModel {
    constructor() {
        this.entities = new Set();
        this.results = new Set();
        this.entitiesChanged = new EventDispatcher();
        this.outcomeChanged = new EventDispatcher();
    }
    /**
     * Registers an entity to be measured with the model.
     *
     * @param entity An entity to measure.
     * @returns `true` if the entity has been added.
     */
    addEntity(entity) {
        if (!this.entities.has(entity)) {
            this.entities.add(entity);
            this.entitiesChanged.emit(this.getEntities());
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * Clears all registered entities from the model.
     */
    clearEntities() {
        this.entities.forEach((e) => this.removeEntity(e));
    }
    /**
     * Clears the outcome containing the results of a measurement.
     */
    clearOutcome() {
        this.setOutcome(undefined);
    }
    /**
     * Sets the outcome containing the results of a measurement.
     *
     * Emits a _outcome changed_ event.
     *
     * @param outcome The outcome containing results.
     */
    setOutcome(outcome) {
        if (!Objects.isEqual(this.outcome, outcome)) {
            this.outcome = outcome;
            this.outcomeChanged.emit(outcome);
        }
    }
    /**
     * Returns all the entities registered with the model.
     */
    getEntities() {
        return Array.from(this.entities);
    }
    /**
     * Returns the outcome that contains the results of a measurement.
     */
    getOutcome() {
        return this.outcome;
    }
    /**
     * Returns all the measurement results of the model.
     */
    getResults() {
        return Array.from(this.results);
    }
    /**
     * Unregisters an entity from the model.
     *
     * @param entity The entity to remove.
     * @returns `true` if the entity was removed.
     */
    removeEntity(entity) {
        if (this.entities.has(entity)) {
            this.entities.delete(entity);
            this.entitiesChanged.emit(this.getEntities());
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * Sets the set of entities to be measured with the model.
     *
     * @param entities A set of entities to measure.
     * @returns `true` if the entity has been added.
     */
    setEntities(entities) {
        this.entities.clear();
        entities.forEach((e) => this.entities.add(e));
        this.entitiesChanged.emit(this.getEntities());
        return true;
    }
    /**
     * Registers an event listener that will be invoked when the model's outcome
     * changes.
     *
     * @param listener The listener to add.
     * @returns A disposable that can be used to remove the listener.
     */
    onOutcomeChanged(listener) {
        return this.outcomeChanged.on(listener);
    }
    /**
     * Registers an event listener that will be invoked when the model's
     * measurement entities change.
     *
     * @param listener The listener to add.
     * @returns A disposable that can be used to remove the listener.
     */
    onEntitiesChanged(listener) {
        return this.entitiesChanged.on(listener);
    }
}
//# sourceMappingURL=model.js.map
