/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Symbology
 */
import { Vector3d, YawPitchRollAngles } from "@itwin/core-geometry";
/** @public */
export var LineStyle;
(function (LineStyle) {
    /** Optional modifiers to override line style definition */
    class Modifier {
        scale;
        dashScale;
        gapScale;
        startWidth;
        endWidth;
        distPhase;
        fractPhase;
        centerPhase;
        segmentMode;
        physicalWidth;
        normal;
        rotation;
        /** constructor for LineStyle.Modifier */
        constructor(props) {
            this.scale = props.scale;
            this.dashScale = props.dashScale;
            this.gapScale = props.gapScale;
            this.startWidth = props.startWidth;
            this.endWidth = props.endWidth;
            this.distPhase = props.distPhase;
            this.fractPhase = props.fractPhase;
            this.centerPhase = props.centerPhase;
            this.segmentMode = props.segmentMode;
            this.physicalWidth = props.physicalWidth;
            this.normal = props.normal ? Vector3d.fromJSON(props.normal) : undefined;
            this.rotation = props.rotation ? YawPitchRollAngles.fromJSON(props.rotation) : undefined;
        }
        /** Returns a deep copy of this object. */
        clone() {
            return new Modifier(this);
        }
        /** Compare two LineStyle.Modifier for equivalence */
        equals(other) {
            if (this === other) // same pointer
                return true;
            if (other.scale !== this.scale ||
                other.dashScale !== this.dashScale ||
                other.gapScale !== this.gapScale ||
                other.startWidth !== this.startWidth ||
                other.endWidth !== this.endWidth ||
                other.distPhase !== this.distPhase ||
                other.fractPhase !== this.fractPhase ||
                other.centerPhase !== this.centerPhase ||
                other.segmentMode !== this.segmentMode ||
                other.physicalWidth !== this.physicalWidth)
                return false;
            if ((this.normal === undefined) !== (other.normal === undefined))
                return false;
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            if (this.normal && !this.normal.isAlmostEqual(other.normal))
                return false;
            if ((this.rotation === undefined) !== (other.rotation === undefined))
                return false;
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            if (this.rotation && !this.rotation.isAlmostEqual(other.rotation))
                return false;
            return true;
        }
        applyTransform(transform) {
            if (transform.isIdentity)
                return true;
            if (this.normal) {
                transform.matrix.multiplyVector(this.normal, this.normal);
                const normalized = this.normal.normalize();
                if (normalized)
                    this.normal.setFrom(normalized);
                else
                    return false;
            }
            if (this.rotation) {
                const newTransform = this.rotation.toMatrix3d().multiplyMatrixTransform(transform);
                const scales = new Vector3d();
                if (!newTransform.matrix.normalizeColumnsInPlace(scales))
                    return false;
                const newRotation = YawPitchRollAngles.createFromMatrix3d(newTransform.matrix);
                if (undefined === newRotation)
                    return false;
                this.rotation.setFrom(newRotation);
            }
            let scaleFactor;
            const scaleVector = Vector3d.create();
            const scaleMatrix = transform.matrix;
            scaleMatrix.normalizeRowsInPlace(scaleVector);
            // Check for flatten transform, dividing scaleVector by 3 gives wrong scaleFactor
            if (scaleVector.x !== 0.0 && scaleVector.y !== 0.0 && scaleVector.z !== 0.0)
                scaleFactor = (scaleVector.x + scaleVector.y + scaleVector.z) / 3.0;
            else
                scaleFactor = (scaleVector.x + scaleVector.y + scaleVector.z) / 2.0;
            if (1.0 === scaleFactor)
                return true;
            if (this.scale)
                this.scale *= scaleFactor;
            if (this.physicalWidth)
                return true;
            if (this.startWidth)
                this.startWidth *= scaleFactor;
            if (this.endWidth)
                this.endWidth *= scaleFactor;
            return true;
        }
    }
    LineStyle.Modifier = Modifier;
    /** Line style id and optional modifiers to override line style definition */
    class Info {
        styleId;
        styleMod; // Optional modifiers to override line style definition
        /** Creates a LineStyle.Info object */
        constructor(styleId, styleMod) {
            this.styleId = styleId;
            this.styleMod = styleMod;
        }
        /** Returns a deep copy of this object. */
        clone() {
            return new Info(this.styleId, this.styleMod ? this.styleMod.clone() : undefined);
        }
        equals(other) {
            if (this === other)
                return true;
            if (this.styleId !== other.styleId)
                return false;
            if ((this.styleMod === undefined) !== (other.styleMod === undefined))
                return false;
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            if (this.styleMod && !this.styleMod.equals(other.styleMod))
                return false;
            return true;
        }
    }
    LineStyle.Info = Info;
})(LineStyle || (LineStyle = {}));
//# sourceMappingURL=LineStyle.js.map