/*---------------------------------------------------------------------------------------------
* 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 { CesiumTerrainAssetId } from "./CesiumIonAssets";
/** Correction modes for terrain height
 * @see [[TerrainProps]]
 * @public
 * @extensions
 */
export var TerrainHeightOriginMode;
(function (TerrainHeightOriginMode) {
    /** Height value indicates the geodetic height of the IModel origin (also referred to as ellipsoidal or GPS height) */
    TerrainHeightOriginMode[TerrainHeightOriginMode["Geodetic"] = 0] = "Geodetic";
    /** Height value indicates the geoidal height of the IModel origin (commonly referred to as sea level). */
    TerrainHeightOriginMode[TerrainHeightOriginMode["Geoid"] = 1] = "Geoid";
    /** Height value indicates the height of the IModel origin relative to ground level at project center. */
    TerrainHeightOriginMode[TerrainHeightOriginMode["Ground"] = 2] = "Ground";
})(TerrainHeightOriginMode || (TerrainHeightOriginMode = {}));
/** Normalized version of [[TerrainProps]] for which provider has been validated and default values of all members are used.
 * @public
 */
export class TerrainSettings {
    _nonLocatable;
    /** Identifies the [TerrainProvider]($frontend) that will supply terrain meshes.
     * Defaults to "CesiumWorldTerrain".
     */
    providerName;
    /** Identifies the specific terrain data source to be supplied by the [TerrainProvider]($frontend) identified by [[providerName]],
     * for those providers that support multiple data sources.
     * For example, the "CesiumWorldTerrain" provider uses this field to store a [[CesiumTerrainAssetId]].
     * Default value: an empty string.
     */
    dataSource;
    /** A value greater than one will cause terrain height to be exaggerated/scaled. 1.0 indicates no exaggeration. Default value: 1.0 */
    exaggeration;
    /**  Applying lighting can help to visualize subtle terrain variations. Default value: false */
    applyLighting;
    /** Origin value - height of the IModel origin at the project center as defined by heightOriginMode. Default value 0.0 */
    heightOrigin;
    /** Determines how/if the heightOrigin is applied to the terrain height. Default value: Geodetic */
    heightOriginMode;
    /** Optionally overrides [[BackgroundMapSettings.locatable]]. For backwards compatibility only.
     * @see [[TerrainProps.nonLocatable]].
     * @internal
     */
    get nonLocatable() {
        return this._nonLocatable;
    }
    /** @internal */
    constructor(providerNameOrProps, exaggeration, applyLighting, heightOrigin, heightOriginMode) {
        let providerName;
        let dataSource;
        let nonLocatable;
        if (typeof providerNameOrProps === "string") {
            providerName = providerNameOrProps;
        }
        else if (providerNameOrProps) {
            ({ providerName, dataSource, exaggeration, applyLighting, heightOrigin, heightOriginMode, nonLocatable } = providerNameOrProps);
        }
        this.providerName = providerName ?? "CesiumWorldTerrain";
        this.dataSource = dataSource ?? "";
        this.exaggeration = Math.min(100, Math.max(0.1, exaggeration ?? 1.0));
        this.applyLighting = applyLighting ?? false;
        this.heightOrigin = heightOrigin ?? 0.0;
        if (true === nonLocatable)
            this._nonLocatable = true;
        switch (heightOriginMode) {
            case TerrainHeightOriginMode.Ground:
            case TerrainHeightOriginMode.Geoid:
                this.heightOriginMode = heightOriginMode;
                break;
            default:
                this.heightOriginMode = TerrainHeightOriginMode.Geodetic;
                break;
        }
    }
    static fromJSON(json) {
        return new TerrainSettings(json);
    }
    /** Create settings that obtain terrain from a [Cesium ION asset](https://cesium.com/platform/cesium-ion/content/) such as
     * one of those defined by [[CesiumTerrainAssetId]].
     * @note You must ensure your Cesium ION account has access to the specified asset.
     */
    static fromCesiumIonAsset(assetId = CesiumTerrainAssetId.Default, options) {
        return TerrainSettings.fromJSON({
            ...options,
            dataSource: assetId,
        });
    }
    toJSON() {
        const props = { heightOriginMode: this.heightOriginMode };
        if ("CesiumWorldTerrain" !== this.providerName)
            props.providerName = this.providerName;
        if (this.dataSource)
            props.dataSource = this.dataSource;
        if (1 !== this.exaggeration)
            props.exaggeration = this.exaggeration;
        if (this.nonLocatable)
            props.nonLocatable = true;
        if (this.applyLighting)
            props.applyLighting = true;
        if (0 !== this.heightOrigin)
            props.heightOrigin = this.heightOrigin;
        return props;
    }
    equals(other) {
        return this.providerName === other.providerName && this.dataSource === other.dataSource && this.exaggeration === other.exaggeration && this.applyLighting === other.applyLighting
            && this.heightOrigin === other.heightOrigin && this.heightOriginMode === other.heightOriginMode && this.nonLocatable === other.nonLocatable;
    }
    /** Returns true if these settings are equivalent to the supplied JSON settings. */
    equalsJSON(json) {
        return this.equals(TerrainSettings.fromJSON(json));
    }
    /** Create a copy of this TerrainSettings, optionally modifying some of its properties.
     * @param changedProps JSON representation of the properties to change.
     * @returns A TerrainSettings with all of its properties set to match those of`this`, except those explicitly defined in `changedProps`.
     */
    clone(changedProps) {
        if (undefined === changedProps)
            return this;
        const props = {
            providerName: changedProps.providerName ?? this.providerName,
            dataSource: changedProps.dataSource ?? this.dataSource,
            exaggeration: changedProps.exaggeration ?? this.exaggeration,
            nonLocatable: changedProps.nonLocatable ?? this.nonLocatable,
            applyLighting: changedProps.applyLighting ?? this.applyLighting,
            heightOrigin: changedProps.heightOrigin ?? this.heightOrigin,
            heightOriginMode: changedProps.heightOriginMode ?? this.heightOriginMode,
        };
        return TerrainSettings.fromJSON(props);
    }
}
//# sourceMappingURL=TerrainSettings.js.map