"use strict";
/*---------------------------------------------------------------------------------------------
* 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
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.CurveExtendOptions = exports.CurveExtendMode = void 0;
const Geometry_1 = require("../Geometry");
/**
 * Enumeration of condition for extending a curve beyond start or end point.
 * * Not all CurvePrimitives support these modes.
 * @public
 */
var CurveExtendMode;
(function (CurveExtendMode) {
    /** No extension allowed. */
    CurveExtendMode[CurveExtendMode["None"] = 0] = "None";
    /** Extend along continuation of the end tangent. */
    CurveExtendMode[CurveExtendMode["OnTangent"] = 1] = "OnTangent";
    /** Extend along continuation of the curve. */
    CurveExtendMode[CurveExtendMode["OnCurve"] = 2] = "OnCurve";
})(CurveExtendMode || (exports.CurveExtendMode = CurveExtendMode = {}));
/**
 * Logic for deciding how a curve may be extended for closest point or intersection searches.
 * @public
 */
class CurveExtendOptions {
    /**
     * Given a `VariantCurveExtendParameter`, isolate the particular CurveExtendMode in effect at an end.
     * * Return `CurveExtendMode.None` if `param === false`.
     * * Return `CurveExtendMode.OnCurve` if `param === true`.
     * * Return the param if it is a single CurveExtendMode.
     * * Return dereferenced array at entry `endIndex` if the param is an array of CurveExtendMode.
     */
    static resolveVariantCurveExtendParameterToCurveExtendMode(param, endIndex) {
        if (param === false)
            return CurveExtendMode.None;
        if (param === true)
            return CurveExtendMode.OnCurve;
        if (Array.isArray(param))
            return param.length > endIndex ? param[endIndex] : CurveExtendMode.None;
        return param;
    }
    /**
     * Correct fraction to be within [0,1].
     * * If fraction is in [0,1] return it unchanged.
     * * If fraction is less than 0 use `extendParam` to decide whether to return it unchanged, or to return 0.
     * * If fraction is greater than 1 use `extendParam` to decide whether to return it unchanged, or to return 1.
     */
    static correctFraction(extendParam, fraction) {
        if (fraction < 0) {
            const mode = CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extendParam, 0);
            if (mode === CurveExtendMode.None)
                fraction = 0.0;
        }
        else if (fraction > 1.0) {
            const mode = CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extendParam, 1);
            if (mode === CurveExtendMode.None)
                fraction = 1.0;
        }
        return fraction;
    }
    /**
     * Adjust a radians value to an angle sweep, extending beyond or clamping to [0,1] according to `extendParam`:
     * * If `radians` is within the sweep, convert it to a fraction of the sweep.
     * * If `radians` is outside the sweep and `extendParam` does not allow extension at both ends, adjust the fraction:
     *   * fraction below 0 if `extendParam` allows extension only at start
     *   * fraction above 1 if `extendParam` allows extension only at end
     *   * fraction clamped to [0,1] if `extendParam` disallows extension at both ends
     * @returns adjusted fraction of sweep, and a boolean indicating whether it is valid, i.e. whether `radians` lies in
     * the sweep extended per `extendParam`.
     */
    static resolveRadiansToValidSweepFraction(extendParam, radians, sweep) {
        let fraction = sweep.radiansToSignedPeriodicFraction(radians);
        let isValid = true;
        if (!sweep.isRadiansInSweep(radians)) {
            const fractionPeriod = sweep.fractionPeriod();
            const mode0 = CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extendParam, 0);
            const mode1 = CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(extendParam, 1);
            if (mode0 !== CurveExtendMode.None) {
                if (mode1 === CurveExtendMode.None) { // only extend to negative
                    if (fraction > 1.0)
                        fraction -= fractionPeriod;
                }
            }
            else if (mode1 !== CurveExtendMode.None) { // only extend to positive
                if (fraction < 0.0)
                    fraction += fractionPeriod;
            }
            else { // no extension allowed
                fraction = Geometry_1.Geometry.clamp(fraction, 0, 1);
                isValid = false;
            }
        }
        return { fraction, isValid };
    }
    /** Call [[resolveRadiansToValidSweepFraction]] and return only the fraction. */
    static resolveRadiansToSweepFraction(extendParam, radians, sweep) {
        return this.resolveRadiansToValidSweepFraction(extendParam, radians, sweep).fraction;
    }
}
exports.CurveExtendOptions = CurveExtendOptions;
//# sourceMappingURL=CurveExtendMode.js.map