/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module DisplayStyles
 */
import { CompressedId64Set } from "@itwin/core-bentley";
/** The different modes by which a [[PlanarClipMaskSettings]] collects the geometry used to mask a model.
 * @public
 * @extensions
 */
export var PlanarClipMaskMode;
(function (PlanarClipMaskMode) {
    /** No masking. */
    PlanarClipMaskMode[PlanarClipMaskMode["None"] = 0] = "None";
    /** Mask based on priority. Different types of models have different default priorities as enumerated by [[PlanarClipMaskPriority]].
     * For example, background maps have the lowest priority, so they are masked by all other types, while design models have the highest priority and are therefore never masked.
     * The priority of a reality model can be overridden by [[PlanarClipMaskSettings.priority]]. This is useful to allow one reality model to mask another overlapping one.
     * Everything visible in the view creates the mask, so turning off models, categories, or elements (via fully transparent overrides) will make things not be in the mask.
     */
    PlanarClipMaskMode[PlanarClipMaskMode["Priority"] = 1] = "Priority";
    /** Indicates that masks should be produced from the geometry in a set of [GeometricModel]($backend)s, regardless of what model is on or off in the view.
     * However, things that are off from category settings or element feature overrides in the view will not be in the mask for these models.
     */
    PlanarClipMaskMode[PlanarClipMaskMode["Models"] = 2] = "Models";
    /** Indicates that masks should be produced from geometry belonging to a set of subcategories.
     * View settings do not affect what is in the mask, unless [[PlanarClipMaskSettings.subCategoryOrElementIds]] is undefined, in which case it behaves like Models mode.
     */
    PlanarClipMaskMode[PlanarClipMaskMode["IncludeSubCategories"] = 3] = "IncludeSubCategories";
    /** Indicates that masks should be produced from the geometry of a set of [GeometricElement]($backend)s.
     * View settings do not affect what is in the mask, unless [[PlanarClipMaskSettings.subCategoryOrElementIds]] is undefined, in which case it behaves like Models mode.
     */
    PlanarClipMaskMode[PlanarClipMaskMode["IncludeElements"] = 4] = "IncludeElements";
    /** Indicates that masks should be produced from the geometry of all [GeometricElement]($backend)s in a view, **except** for a specified set of excluded elements.
     * View settings do not affect what is in the mask, unless [[PlanarClipMaskSettings.subCategoryOrElementIds]] is undefined, in which case it behaves like Models mode.
     */
    PlanarClipMaskMode[PlanarClipMaskMode["ExcludeElements"] = 5] = "ExcludeElements";
})(PlanarClipMaskMode || (PlanarClipMaskMode = {}));
/** The default priority values for a [[PlanarClipMaskSettings]], based on model type. Models with a lower priority are masked by models with a higher priority.
 * The default can be overridden by [[PlanarClipMaskSettings.priority]].
 *  @public
 * @extensions
 */
export var PlanarClipMaskPriority;
(function (PlanarClipMaskPriority) {
    /** Background map. */
    PlanarClipMaskPriority[PlanarClipMaskPriority["BackgroundMap"] = -2048] = "BackgroundMap";
    /** A reality model that spans the globe - e.g., OpenStreetMaps Buildings. */
    PlanarClipMaskPriority[PlanarClipMaskPriority["GlobalRealityModel"] = -1024] = "GlobalRealityModel";
    /** A reality model with a bounded range. */
    PlanarClipMaskPriority[PlanarClipMaskPriority["RealityModel"] = 0] = "RealityModel";
    /** A design model stored in the [IModelDb]($backend). */
    PlanarClipMaskPriority[PlanarClipMaskPriority["DesignModel"] = 2048] = "DesignModel";
})(PlanarClipMaskPriority || (PlanarClipMaskPriority = {}));
/** Describes how to mask the geometry of one [GeometricModel]($backend) for display. The mask is produced by projecting geometry from any number of other models -
 * optionally filtered by [SubCategory]($backend) or by a set of specific [GeometricElement]($backend)s - onto a plane. Regions of the masked model that intersect the
 * mask are rendered partially or completely transparent. This is useful for, e.g., making subsurface geometry visible below the background map, or clipping out portions
 * of a reality model that intersect a design model.
 * @note Currently reality models (including background maps and terrain) can be masked, but design models can only produce masks.
 * @see [[DisplayStyleSettings.planarClipMasks]] to define clip masks for a [DisplayStyle]($backend).
 * @see [[ContextRealityModel.planarClipMaskSettings]] to apply a clip mask to a context reality model.
 * @public
 */
export class PlanarClipMaskSettings {
    /** The compressed representation of [[modelIds]]. */
    get compressedModelIds() {
        return this._modelIds;
    }
    /** Create a new [[PlanarClipMaskSettings]] object from its JSON representation. */
    static fromJSON(json) {
        if (!json || undefined === json.mode)
            return this.defaults;
        return new PlanarClipMaskSettings(json.mode, json.transparency, json.modelIds, json.subCategoryOrElementIds, json.priority, json.invert);
    }
    /** Create a new PlanarClipMaskSettings. */
    static create(args) {
        const modelIds = args.modelIds ? CompressedId64Set.sortAndCompress(args.modelIds) : undefined;
        if (undefined !== args.priority)
            return new PlanarClipMaskSettings(PlanarClipMaskMode.Priority, args.transparency, undefined, undefined, args.priority, args.invert);
        else if (undefined !== args.subCategoryIds)
            return new PlanarClipMaskSettings(PlanarClipMaskMode.IncludeSubCategories, args.transparency, modelIds, CompressedId64Set.sortAndCompress(args.subCategoryIds), undefined, args.invert);
        else if (undefined !== args.elementIds)
            return new PlanarClipMaskSettings(args.exclude ? PlanarClipMaskMode.ExcludeElements : PlanarClipMaskMode.IncludeElements, args.transparency, modelIds, CompressedId64Set.sortAndCompress(args.elementIds), undefined, args.invert);
        else
            return new PlanarClipMaskSettings(PlanarClipMaskMode.Models, args.transparency, modelIds, undefined, undefined, args.invert);
    }
    /** Create JSON object representing this [[PlanarClipMaskSettings]] */
    toJSON() {
        const props = { mode: this.mode };
        if (undefined !== this._modelIds)
            props.modelIds = this._modelIds;
        if (undefined !== this._subCategoryOrElementIds)
            props.subCategoryOrElementIds = this._subCategoryOrElementIds;
        if (undefined !== this.priority)
            props.priority = this.priority;
        if (undefined !== this.transparency)
            props.transparency = this.transparency;
        if (this.invert)
            props.invert = true;
        return props;
    }
    /** Returns true if masking is enabled. */
    get isValid() {
        return this.mode !== PlanarClipMaskMode.None;
    }
    equals(other) {
        return this.mode === other.mode &&
            this.priority === other.priority &&
            this.transparency === other.transparency &&
            this.invert === other.invert &&
            this._modelIds === other._modelIds &&
            this._subCategoryOrElementIds === other._subCategoryOrElementIds;
    }
    /** Create a copy of this TerrainSettings, optionally modifying some of its properties.
     * @param changedProps JSON representation of the properties to change.
     * @returns A PlanarClipMaskSettings with all of its properties set to match those of`this`, except those explicitly defined in `changedProps`.
     */
    clone(changedProps) {
        if (undefined === changedProps)
            return this;
        return PlanarClipMaskSettings.fromJSON({
            ...this.toJSON(),
            ...changedProps,
        });
    }
    constructor(mode, transparency, modelIds, subCategoryOrElementIds, priority, invert) {
        this.mode = mode;
        this._modelIds = modelIds;
        this._subCategoryOrElementIds = subCategoryOrElementIds;
        this.priority = priority;
        this.invert = true === invert;
        this.transparency = undefined !== transparency ? Math.max(0, Math.min(1, transparency)) : undefined;
        if (modelIds)
            this.modelIds = CompressedId64Set.iterable(modelIds);
        if (subCategoryOrElementIds)
            this.subCategoryOrElementIds = CompressedId64Set.iterable(subCategoryOrElementIds);
    }
}
/** A default PlanarClipMask which masks nothing. */
PlanarClipMaskSettings.defaults = new PlanarClipMaskSettings(PlanarClipMaskMode.None);
//# sourceMappingURL=PlanarClipMask.js.map