/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { CurveChainWithDistanceIndex } from "./CurveChainWithDistanceIndex";
import { CurveChain } from "./CurveCollection";
import { LineString3d } from "./LineString3d";
/**
 * A `Loop` is a curve chain that is the boundary of a closed (planar) loop.
 * @see [Curve Collections]($docs/learning/geometry/CurveCollection.md) learning article.
 * @public
 */
export class Loop extends CurveChain {
    /** String name for schema properties */
    curveCollectionType = "loop";
    /** Tag value that can be set to true for user code to mark inner and outer loops. */
    isInner = false;
    /** Test if `other` is a `Loop` */
    isSameGeometryClass(other) {
        return other instanceof Loop;
    }
    constructor() {
        super();
    }
    /**
     * Create a loop from a variable length list of [[CurvePrimitive]]s.
     * * A significant gap between the end of one curve and the start of the next, or between chain start and end,
     * is not bridged and may cause unexpected behavior.
     * @param curves array of individual curve primitives, assumed to form a closed planar loop.
     */
    static create(...curves) {
        const result = new Loop();
        for (const curve of curves) {
            if (curve instanceof CurveChainWithDistanceIndex)
                result.children.push(...curve.path.children);
            else
                result.children.push(curve);
        }
        return result;
    }
    /**
     * Create a loop from an array of [[CurvePrimitive]]s.
     * * A significant gap between the end of one curve and the start of the next, or between chain start and end,
     * is not bridged and may cause unexpected behavior.
     * @param curves array of individual curve primitives, assumed to form a closed planar loop.
     */
    static createArray(curves) {
        return this.create(...curves);
    }
    /**
     * Create a loop from an array of coplanar points.
     * @param points vertices of polygon, closure point optional.
    */
    static createPolygon(points) {
        const linestring = LineString3d.create(points);
        linestring.addClosurePoint();
        return Loop.create(linestring);
    }
    /** Create a loop with the stroked form of this loop. */
    cloneStroked(options) {
        const strokes = LineString3d.create();
        for (const curve of this.children)
            curve.emitStrokes(strokes, options);
        // eliminate near-duplicate points between children
        strokes.removeDuplicatePoints();
        if (strokes.isPhysicallyClosed) {
            strokes.popPoint();
            strokes.addClosurePoint();
        }
        return Loop.create(strokes);
    }
    /** Return the boundary type (2) of a corresponding  MicroStation CurveVector */
    dgnBoundaryType() {
        /**
         * All "Loop" become "outer". TypeScript Loop object is equivalent to a native CurveVector with
         * boundaryType = BOUNDARY_TYPE_Outer. In other words, TypeScript has no flavor of Loop that
         * carries "hole" semantics.
         */
        return 2;
    }
    /** Invoke `processor.announceLoop(this, indexInParent)` */
    announceToCurveProcessor(processor, indexInParent = -1) {
        return processor.announceLoop(this, indexInParent);
    }
    /** Create a new `Loop` with no children */
    cloneEmptyPeer() {
        return new Loop();
    }
    /** Second step of double dispatch:  call `handler.handleLoop(this)` */
    dispatchToGeometryHandler(handler) {
        return handler.handleLoop(this);
    }
}
/**
 * Structure carrying a pair of loops with curve geometry.
 * @public
 */
export class LoopCurveLoopCurve {
    /** First loop */
    loopA;
    /** A curve (typically an edge of loopA) */
    curveA;
    /** second loop */
    loopB;
    /** A curve (typically an edge of loopB) */
    curveB;
    /** Constructor */
    constructor(loopA, curveA, loopB, curveB) {
        this.loopA = loopA;
        this.curveA = curveA;
        this.loopB = loopB;
        this.curveB = curveB;
    }
    /** Set the loopA and curveA members */
    setA(loop, curve) {
        this.loopA = loop;
        this.curveA = curve;
    }
    /** Set the loopB and curveB members */
    setB(loop, curve) {
        this.loopB = loop;
        this.curveB = curve;
    }
}
//# sourceMappingURL=Loop.js.map