/** @packageDocumentation
 * @module CartesianGeometry
 */
import { Arc3d } from "../curve/Arc3d";
import { AnnounceNumberNumber, AnnounceNumberNumberCurvePrimitive, CurvePrimitive } from "../curve/CurvePrimitive";
import { GrowableXYZArray } from "../geometry3d/GrowableXYZArray";
import { IndexedXYZCollection } from "../geometry3d/IndexedXYZCollection";
import { Point3d } from "../geometry3d/Point3dVector3d";
import { Range1d } from "../geometry3d/Range";
import { GrowableXYZArrayCache } from "../geometry3d/ReusableObjectCache";
import { Clipper, PolygonClipper } from "./ClipUtils";
/** BooleanClipNode is an abstract base class for boolean actions by an array of clippers.
 * * Derived class must implement
 *   * The single point test `isPointOnOrInsideChildren`
 *   * Boolean operation on 1d intervals `combineIntervals`
 * * The `keepInside` flag controls an additional optional flip of the boolean result.
 *   * if `keepInside === true`, accept the "inside" of the clip clippers
 *   * if `keepInside === false`, accept the "outside" of the child clippers.
 * * Hence the combinations of derived classes for (OR, AND, XOR) and keepInside are
 *   * (OR, true) = simple union (OR), i.e. "in" one or more clips
 *   * (OR, false) = complement of union (NOR), i.e. "outside" all clips
 *   * (AND, true) = simple intersection (AND), i.e. "in" all clips
 *   * (AND, false) = complement of intersection (NAND), i.e. "outside" one or more clips
 *   * (XOR,true) = simple parity, i.e. "in" an odd number of clips
 *   * (XOR,false) = complement of parity ), i.e. "in" an even number of clips
 * @internal
 */
export declare abstract class BooleanClipNode implements Clipper {
    protected _clippers: Clipper[];
    protected _intervalsA: Range1d[];
    protected _intervalsB: Range1d[];
    protected _keepInside: boolean;
    constructor(keepInside: boolean);
    protected abstract isPointOnOrInsideChildren(point: Point3d): boolean;
    protected abstract combineIntervals(operandA: Range1d[], operandB: Range1d[]): Range1d[];
    abstract get operationName(): string;
    toJSON(): any;
    /** Capture a (reference to a) child node or nodes */
    captureChild(child: Clipper | Clipper[]): void;
    /** Toggle the "keepInside" behavior.  Return the prior value.  */
    toggleResult(): boolean;
    /** Set the "keepInside" behavior  */
    selectResult(keepInside: boolean): boolean;
    /**
     * Conditionally (if a1 > a0 strictly) call announce (a0, a1).
     * * Return 0 if not called, 1 if called.
     */
    protected testedAnnounceNN(a0: number, a1: number, announce?: AnnounceNumberNumber): number;
    /**
     * Conditionally (if a1 > a0 strictly) call announce (a0, a1, cp).
     * * Return 0 if not called, 1 if called.
     */
    protected testedAnnounceNNC(a0: number, a1: number, cp: CurvePrimitive, announce?: AnnounceNumberNumberCurvePrimitive): number;
    /** Swap the _intervalsA and _intervalsB */
    protected swapAB(): void;
    /**
     * Announce all "outside intervals" --not masked by intervals
     * * Return true if any intervals announced.
     */
    protected announcePartsNN(keepInside: boolean, intervals: Range1d[], f0: number, f1: number, announce?: AnnounceNumberNumber): boolean;
    /**
     * Announce all "outside intervals" --not masked by intervals
     * * Return true if any intervals announced.
     */
    protected announcePartsNNC(keepInside: boolean, intervals: Range1d[], f0: number, f1: number, cp: CurvePrimitive, announce?: AnnounceNumberNumberCurvePrimitive): boolean;
    /** Invoke callback to test if a point is "in" this clipper */
    isPointOnOrInside(point: Point3d): boolean;
    /** Announce "in" portions of a line segment. See `Clipper.announceClippedSegmentIntervals` */
    announceClippedSegmentIntervals(f0: number, f1: number, pointA: Point3d, pointB: Point3d, announce?: AnnounceNumberNumber): boolean;
    /** Announce "in" portions of a line segment.  See `Clipper.announceClippedSegmentIntervals` */
    announceClippedArcIntervals(arc: Arc3d, announce?: AnnounceNumberNumberCurvePrimitive): boolean;
}
/**
 * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
 * @internal
 */
export declare class BooleanClipNodeUnion extends BooleanClipNode {
    get operationName(): string;
    constructor(keepInside: boolean);
    /** Return true if inside any child clipper */
    isPointOnOrInsideChildren(point: Point3d): boolean;
    combineIntervals(operandA: Range1d[], operandB: Range1d[]): Range1d[];
    appendPolygonClip(xyz: IndexedXYZCollection, insideFragments: GrowableXYZArray[], outsideFragments: GrowableXYZArray[], arrayCache: GrowableXYZArrayCache): void;
}
/**
 * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
 * @internal
 */
export declare class BooleanClipNodeParity extends BooleanClipNode {
    get operationName(): string;
    constructor(keepInside: boolean);
    /** Return true if inside an odd number of clippers child clipper */
    isPointOnOrInsideChildren(point: Point3d): boolean;
    combineIntervals(operandA: Range1d[], operandB: Range1d[]): Range1d[];
    appendPolygonClip(xyz: IndexedXYZCollection, insideFragments: GrowableXYZArray[], outsideFragments: GrowableXYZArray[], arrayCache: GrowableXYZArrayCache): void;
}
/**
 * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
 * @internal
 */
export declare class BooleanClipNodeIntersection extends BooleanClipNode implements PolygonClipper {
    get operationName(): string;
    constructor(keepInside: boolean);
    /** Return false if outside of any child clipper */
    isPointOnOrInsideChildren(point: Point3d): boolean;
    combineIntervals(operandA: Range1d[], operandB: Range1d[]): Range1d[];
    appendPolygonClip(xyz: IndexedXYZCollection, insideFragments: GrowableXYZArray[], outsideFragments: GrowableXYZArray[], arrayCache: GrowableXYZArrayCache): void;
}
//# sourceMappingURL=BooleanClipNode.d.ts.map