/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Curve
 */
import { Range1d } from "../../geometry3d/Range";
import { Ray3d } from "../../geometry3d/Ray3d";
import { GaussMapper } from "../../numerics/Quadrature";
/**
 * Context for computing the length of a CurvePrimitive.
 * @internal
 */
export class CurveLengthContext {
    _curve;
    _summedLength;
    _ray;
    _fraction0;
    _fraction1;
    _gaussMapper;
    tangentMagnitude(fraction) {
        this._ray = this._curve.fractionToPointAndDerivative(fraction, this._ray);
        return this._ray.direction.magnitude();
    }
    /** Return the fraction0 installed at construction time. */
    get getFraction0() {
        return this._fraction0;
    }
    /** Return the fraction1 installed at construction time. */
    get getFraction1() {
        return this._fraction1;
    }
    getSum() {
        return this._summedLength;
    }
    constructor(fraction0 = 0.0, fraction1 = 1.0, numGaussPoints = 5) {
        this.startCurvePrimitive(undefined);
        this._summedLength = 0.0;
        this._ray = Ray3d.createZero();
        if (fraction0 < fraction1) {
            this._fraction0 = fraction0;
            this._fraction1 = fraction1;
        }
        else {
            this._fraction0 = fraction1;
            this._fraction1 = fraction0;
        }
        this._gaussMapper = new GaussMapper(numGaussPoints);
    }
    startCurvePrimitive(curve) {
        this._curve = curve;
    }
    startParentCurvePrimitive(_curve) {
    }
    endParentCurvePrimitive(_curve) {
    }
    endCurvePrimitive() {
    }
    announceIntervalForUniformStepStrokes(cp, numStrokes, fraction0, fraction1) {
        const range = Range1d.createXX(fraction0, fraction1);
        range.intersectRangeXXInPlace(this._fraction0, this._fraction1);
        if (!range.isNull) {
            this.startCurvePrimitive(cp);
            if (numStrokes < 1)
                numStrokes = 1;
            const df = 1.0 / numStrokes;
            for (let i = 1; i <= numStrokes; i++) {
                const fractionA = range.fractionToPoint((i - 1) * df);
                const fractionB = i === numStrokes ? range.high : range.fractionToPoint(i * df);
                const numGauss = this._gaussMapper.mapXAndW(fractionA, fractionB);
                for (let k = 0; k < numGauss; k++) {
                    this._summedLength += this._gaussMapper.gaussW[k] * this.tangentMagnitude(this._gaussMapper.gaussX[k]);
                }
            }
        }
    }
    announceSegmentInterval(_cp, point0, point1, _numStrokes, fraction0, fraction1) {
        const segmentLength = point0.distance(point1);
        if (this._fraction0 <= fraction0 && fraction1 <= this._fraction1)
            this._summedLength += segmentLength;
        else {
            const range = Range1d.createXX(fraction0, fraction1);
            range.intersectRangeXXInPlace(this._fraction0, this._fraction1);
            if (!range.isNull)
                this._summedLength += segmentLength * range.length() / (fraction1 - fraction0);
        }
    }
    announcePointTangent(_xyz, _fraction, _tangent) {
        // uh oh -- need to retain point for next interval
    }
}
//# sourceMappingURL=CurveLengthContext.js.map