/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Rendering
 */
import { assert, comparePossiblyUndefined, compareWithTolerance, IndexMap } from "@itwin/core-bentley";
function comparePositions(p0, p1, tolerance) {
    let diff = compareWithTolerance(p0.x, p1.x, tolerance.x);
    if (0 === diff) {
        diff = compareWithTolerance(p0.y, p1.y, tolerance.y);
        if (0 === diff)
            diff = compareWithTolerance(p0.z, p1.z, tolerance.z);
    }
    return diff;
}
function compareFeatures(f0, f1) {
    return comparePossiblyUndefined((lhs, rhs) => lhs.compare(rhs), f0, f1);
}
/** @internal */
export class VertexKey {
    constructor(position, fillColor, normal, uvParam, feature) {
        this.position = position.clone();
        this.fillColor = fillColor;
        this.normal = normal;
        this.uvParam = uvParam?.clone();
        this.feature = feature;
    }
    static create(props) {
        return new VertexKey(props.position, props.fillColor, props.normal, props.uvParam, props.feature);
    }
    equals(rhs, tolerance) {
        if (this.fillColor !== rhs.fillColor)
            return false;
        if (0 !== compareFeatures(this.feature, rhs.feature))
            return false;
        if (undefined !== this.normal) {
            assert(undefined !== rhs.normal);
            if (this.normal.value !== rhs.normal.value)
                return false;
        }
        if (0 !== comparePositions(this.position, rhs.position, tolerance))
            return false;
        if (undefined !== this.uvParam) {
            assert(undefined !== rhs.uvParam);
            return this.uvParam.isAlmostEqual(rhs.uvParam, 0.0001);
        }
        return true;
    }
    compare(rhs, tolerance) {
        if (this === rhs)
            return 0;
        let diff = this.fillColor - rhs.fillColor;
        if (0 === diff) {
            diff = comparePositions(this.position, rhs.position, tolerance);
            if (0 === diff) {
                diff = compareFeatures(this.feature, rhs.feature);
                if (0 === diff) {
                    if (undefined !== this.normal) {
                        assert(undefined !== rhs.normal);
                        diff = this.normal.value - rhs.normal.value;
                    }
                    if (0 === diff && undefined !== this.uvParam) {
                        assert(undefined !== rhs.uvParam);
                        diff = compareWithTolerance(this.uvParam.x, rhs.uvParam.x);
                        if (0 === diff)
                            diff = compareWithTolerance(this.uvParam.x, rhs.uvParam.y);
                    }
                }
            }
        }
        return diff;
    }
}
/** @internal */
export class VertexMap extends IndexMap {
    constructor(tolerance) {
        super((lhs, rhs) => lhs.compare(rhs, tolerance));
        this._tolerance = tolerance;
    }
    insertKey(props, onInsert) {
        return this.insert(VertexKey.create(props), onInsert);
    }
    arePositionsAlmostEqual(p0, p1) {
        return 0 === this.comparePositions(p0, p1);
    }
    comparePositions(p0, p1) {
        return comparePositions(p0.position, p1.position, this._tolerance);
    }
}
//# sourceMappingURL=VertexKey.js.map