/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Views
 */
import { assert, JsonUtils } from "@itwin/core-bentley";
import { RgbColor } from "./RgbColor";
import { HiddenLine } from "./HiddenLine";
import { FeatureAppearance } from "./FeatureSymbology";
import { ColorDef } from "./ColorDef";
/** As part of a [[ClipStyle]], describes how section-cut graphics should be displayed.
 * @note Section-cut graphics are only produced if [[ClipStyle.produceCutGeometry]] is `true`.
 * @public
 */
export class CutStyle {
    constructor(viewflags, hiddenLine, appearance) {
        this.viewflags = viewflags ?? {};
        if (hiddenLine && !hiddenLine.matchesDefaults)
            this.hiddenLine = hiddenLine;
        if (appearance && !appearance.matchesDefaults)
            this.appearance = appearance;
    }
    /** Create a CutStyle from its components. */
    static create(viewflags, hiddenLine, appearance) {
        if ((viewflags && JsonUtils.isNonEmptyObject(viewflags)) || (hiddenLine && !hiddenLine.matchesDefaults) || (appearance && !appearance.matchesDefaults))
            return new CutStyle(viewflags, hiddenLine, appearance);
        return this.defaults;
    }
    static fromJSON(props) {
        if (JsonUtils.isNonEmptyObject(props)) {
            const viewflags = { ...props?.viewflags };
            const hiddenLine = props?.hiddenLine ? HiddenLine.Settings.fromJSON(props.hiddenLine) : undefined;
            const appearance = props?.appearance ? FeatureAppearance.fromJSON(props.appearance) : undefined;
            return this.create(viewflags, hiddenLine, appearance);
        }
        else {
            return this.defaults;
        }
    }
    /** Return JSON representation. The representation is `undefined` if this style matches the default style. */
    toJSON() {
        if (this.matchesDefaults)
            return undefined;
        const props = {};
        if (JsonUtils.isNonEmptyObject(this.viewflags))
            props.viewflags = this.viewflags;
        if (this.hiddenLine && !this.hiddenLine.matchesDefaults)
            props.hiddenLine = this.hiddenLine?.toJSON();
        if (this.appearance && !this.appearance.matchesDefaults)
            props.appearance = this.appearance.toJSON();
        return props;
    }
    /** Returns true if this style matches the default style - that is, it overrides none of the view's settings. */
    get matchesDefaults() {
        if (this === CutStyle.defaults)
            return true;
        return !JsonUtils.isNonEmptyObject(this.viewflags) && (!this.hiddenLine || this.hiddenLine.matchesDefaults) && (!this.appearance || this.appearance.matchesDefaults);
    }
}
/** The default CutStyle, configured to draw the section-cut graphics using the view's settings, with no overrides. */
CutStyle.defaults = new CutStyle();
/** As part of a [[ClipStyle]], describes how to colorize geometry intersecting the clip planes.
 * @note Edges are highlighted only if [[ClipStyle.ClipIntersectionStyle]] is `true`.
 * @public
 * @extensions
 */
export class ClipIntersectionStyle {
    constructor(color = RgbColor.fromColorDef(ColorDef.white), width = 1) {
        this.color = color;
        this.width = width;
    }
    /** Create a highlight  from its components. */
    static create(color, width) {
        if (!color && !width)
            return this.defaults;
        return new ClipIntersectionStyle(color, width);
    }
    static fromJSON(props) {
        if (props === undefined) {
            return ClipIntersectionStyle.defaults;
        }
        const color = props.color ? RgbColor.fromJSON(props.color) : RgbColor.fromColorDef(ColorDef.white);
        const width = props.width ? props.width : 1;
        return new ClipIntersectionStyle(color, width);
    }
    /** The JSON representation of this style. It is `undefined` if this style matches the defaults. */
    toJSON() {
        const props = {};
        if (this.matchesDefaults) {
            return undefined;
        }
        if (this.color)
            props.color = this.color.toJSON();
        if (this.width)
            props.width = this.width;
        return props;
    }
    get matchesDefaults() {
        if (this === ClipIntersectionStyle.defaults)
            return true;
        return !this.color && !this.width;
    }
}
ClipIntersectionStyle.defaults = new ClipIntersectionStyle();
/** Describes symbology and behavior applied to a [ClipVector]($core-geometry) when applied to a [ViewState]($frontend) or [[ModelClipGroup]].
 * @see [[DisplayStyleSettings.clipStyle]].
 * @public
 */
export class ClipStyle {
    constructor(produceCutGeometry, colorizeIntersection, cutStyle, inside, outside, intersectionStyle) {
        this.produceCutGeometry = produceCutGeometry;
        this.colorizeIntersection = colorizeIntersection;
        this.cutStyle = cutStyle;
        this.insideColor = inside;
        this.outsideColor = outside;
        this.intersectionStyle = intersectionStyle;
    }
    /** @internal */
    static create(styleOrProduceCutGeometry, cutStyle, insideColor, outsideColor) {
        if (typeof styleOrProduceCutGeometry === "boolean") {
            cutStyle = cutStyle === undefined ? CutStyle.defaults : cutStyle;
            if (!styleOrProduceCutGeometry && cutStyle.matchesDefaults && !insideColor && !outsideColor) {
                return this.defaults;
            }
            return new ClipStyle(styleOrProduceCutGeometry, false, cutStyle, insideColor, outsideColor, undefined);
        }
        const style = styleOrProduceCutGeometry;
        if (!style.produceCutGeometry && !style.colorizeIntersection && (!style.cutStyle || style.cutStyle.matchesDefaults) && !style.insideColor && !style.outsideColor && !style.intersectionStyle)
            return this.defaults;
        const produceCutGeometry = style.produceCutGeometry ? true : false;
        const colorizeIntersection = style.colorizeIntersection ? true : false;
        cutStyle = style.cutStyle === undefined ? CutStyle.defaults : style.cutStyle;
        return new ClipStyle(produceCutGeometry, colorizeIntersection, cutStyle, style.insideColor, style.outsideColor, style.intersectionStyle);
    }
    static fromJSON(props) {
        if (JsonUtils.isNonEmptyObject(props)) {
            const produceCutGeometry = props.produceCutGeometry ?? false;
            const colorizeIntersection = props.colorizeIntersection ? true : false;
            const cutStyle = CutStyle.fromJSON(props.cutStyle);
            const insideColor = props.insideColor ? RgbColor.fromJSON(props.insideColor) : undefined;
            const outsideColor = props.outsideColor ? RgbColor.fromJSON(props.outsideColor) : undefined;
            const intersectionStyle = props.intersectionStyle ? ClipIntersectionStyle.fromJSON(props.intersectionStyle) : undefined;
            return this.create({ produceCutGeometry, colorizeIntersection, cutStyle, insideColor, outsideColor, intersectionStyle });
        }
        return this.defaults;
    }
    /** The JSON representation of this style. It is `undefined` if this style matches the defaults. */
    toJSON() {
        if (this.matchesDefaults)
            return undefined;
        const props = {};
        if (this.produceCutGeometry)
            props.produceCutGeometry = true;
        if (this.colorizeIntersection)
            props.colorizeIntersection = true;
        const cutStyle = this.cutStyle.toJSON();
        if (cutStyle) {
            assert(!this.cutStyle.matchesDefaults);
            props.cutStyle = cutStyle;
        }
        if (this.insideColor)
            props.insideColor = this.insideColor.toJSON();
        if (this.outsideColor)
            props.outsideColor = this.outsideColor.toJSON();
        if (this.intersectionStyle)
            props.intersectionStyle = this.intersectionStyle.toJSON();
        return props;
    }
    /** Returns true if this style matches the [[ClipStyle.defaults]] - that is, it overrides no settings from the view. */
    get matchesDefaults() {
        if (this === ClipStyle.defaults)
            return true;
        return !this.produceCutGeometry && !this.colorizeIntersection && !this.insideColor && !this.outsideColor && this.cutStyle.matchesDefaults && !this.intersectionStyle;
    }
}
/** The default style, which overrides none of the view's settings. */
ClipStyle.defaults = new ClipStyle(false, false, CutStyle.defaults, undefined, undefined, undefined);
//# sourceMappingURL=ClipStyle.js.map