"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Path = void 0;
const Point3dVector3d_1 = require("../geometry3d/Point3dVector3d");
const CurveChainWithDistanceIndex_1 = require("./CurveChainWithDistanceIndex");
const CurveCollection_1 = require("./CurveCollection");
const CurveExtendMode_1 = require("./CurveExtendMode");
const CurveLocationDetail_1 = require("./CurveLocationDetail");
const CurvePrimitive_1 = require("./CurvePrimitive");
const LineString3d_1 = require("./LineString3d");
/**
 * * A `Path` object is a collection of curves that join head-to-tail to form a path.
 * * A `Path` object does not bound a planar region. Use `Loop` to indicate region bounding.
 * @see [Curve Collections]($docs/learning/geometry/CurveCollection.md) learning article.
 * @public
 */
class Path extends CurveCollection_1.CurveChain {
    /** String name for schema properties */
    curveCollectionType = "path";
    /** Test if `other` is an instance of `Path` */
    isSameGeometryClass(other) {
        return other instanceof Path;
    }
    /** Invoke `processor.announcePath(this, indexInParent)` */
    announceToCurveProcessor(processor, indexInParent = -1) {
        return processor.announcePath(this, indexInParent);
    }
    /** Construct an empty path. */
    constructor() {
        super();
    }
    /**
     * Create a path from a variable length list of curve primitives
     * * CurvePrimitive params are captured.
     * @param curves variable length list of individual curve primitives or point arrays.
     */
    static create(...curves) {
        const result = new Path();
        for (const curve of curves) {
            if (curve instanceof CurveChainWithDistanceIndex_1.CurveChainWithDistanceIndex)
                result.children.push(...curve.path.children);
            else if (curve instanceof CurvePrimitive_1.CurvePrimitive)
                result.children.push(curve);
            else if (Array.isArray(curve) && curve.length > 0 && curve[0] instanceof Point3dVector3d_1.Point3d) {
                result.children.push(LineString3d_1.LineString3d.create(curve));
            }
        }
        return result;
    }
    /**
     * Create a path from a an array of curve primitives.
     * @param curves array of individual curve primitives.
     */
    static createArray(curves) {
        return this.create(...curves);
    }
    /** Return a deep copy, with leaf-level curve primitives stroked. */
    cloneStroked(options) {
        const strokes = LineString3d_1.LineString3d.create();
        for (const curve of this.children)
            curve.emitStrokes(strokes, options);
        return Path.create(strokes);
    }
    /**
     * Return the closest point on the contained curves.
     * @param spacePoint point in space.
     * @param extend compute the closest point to the path extended according to variant type:
     * * false: do not extend the path
     * * true: extend the path at both start and end
     * * CurveExtendOptions: extend the path in the specified manner at both start and end
     * * CurveExtendOptions[]: first entry applies to path start; second, to path end; any other entries ignored
     * @param result optional pre-allocated detail to populate and return.
     * @returns details of the closest point.
     */
    closestPoint(spacePoint, extend = false, result) {
        let detailA;
        const detailB = new CurveLocationDetail_1.CurveLocationDetail();
        if (this.children !== undefined) {
            for (let i = 0; i < this.children.length; i++) {
                const child = this.children[i]; // head only extends at start; tail, only at end. NOTE: child may be both head and tail!
                const mode0 = (i === 0) ? CurveExtendMode_1.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extend, 0) : CurveExtendMode_1.CurveExtendMode.None;
                const mode1 = (i === this.children.length - 1) ? CurveExtendMode_1.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extend, 1) : CurveExtendMode_1.CurveExtendMode.None;
                if (child.closestPoint(spacePoint, [mode0, mode1], detailB))
                    detailA = result = CurveLocationDetail_1.CurveLocationDetail.chooseSmallerA(detailA, detailB).clone(result);
            }
        }
        return detailA;
    }
    /** Return the boundary type (1) of a corresponding MicroStation CurveVector */
    dgnBoundaryType() {
        return 1;
    }
    /** Clone as a new `Path` with no primitives */
    cloneEmptyPeer() {
        return new Path();
    }
    /** Second step of double dispatch: call `handler.handlePath(this)` */
    dispatchToGeometryHandler(handler) {
        return handler.handlePath(this);
    }
}
exports.Path = Path;
//# sourceMappingURL=Path.js.map