import '../../../assert/js/assert.js';
import '../../../globals.js';
import TProperty from '../../../axon/js/TProperty.js';
import TReadOnlyProperty from '../../../axon/js/TReadOnlyProperty.js';
import Bounds2 from '../../../dot/js/Bounds2.js';
import Matrix3 from '../../../dot/js/Matrix3.js';
import Vector2 from '../../../dot/js/Vector2.js';
import { Shape } from '../../../kite/js/imports.js';
import { CanvasContextWrapper, CanvasSelfDrawable, Instance, Node, NodeOptions, PaintableOptions, SVGSelfDrawable } from '../imports.js';
export type PathBoundsMethod = 'accurate' | 'unstroked' | 'tightPadding' | 'safePadding' | 'none';
/**
 * The valid parameter types are:
 * - Shape: (from Kite), normally used.
 * - string: Uses the SVG Path format, see https://www.w3.org/TR/SVG/paths.html (the PATH part of <path d="PATH"/>).
 *           This will immediately be converted to a Shape object when set, and getShape() or equivalents will return
 *           the parsed Shape instance instead of the original string. See "ParsedShape"
 * - null: Indicates that there is no Shape, and nothing is drawn. Usually used as a placeholder.
 *
 * NOTE: Be aware of the potential for memory leaks. If a Shape is not marked as immutable (with makeImmutable()),
 *       Path will add a listener so that it is updated when the Shape itself changes. If there is a listener
 *       added, keeping a reference to the Shape will also keep a reference to the Path object (and thus whatever
 *       Nodes are connected to the Path). For now, set path.shape = null if you need to release the reference
 *       that the Shape would have, or call dispose() on the Path if it is not needed anymore.
 */
export type InputShape = Shape | string | null;
/**
 * See InputShape for details, but this type differs in that it only supports a Shape, and any "string" data will
 * be parsed into a Shape instance.
 */
type ParsedShape = Shape | null;
type SelfOptions = {
    /**
     * This sets the shape of the Path, which determines the shape of its appearance. It should generally not be called
     * on Path subtypes like Line, Rectangle, etc. See InputShape for details about what to provide for the shape.
     *
     * NOTE: When you create a Path with a shape in the constructor, this setter will be called (don't overload the option).
     */
    shape?: InputShape;
    /**
     * Similar to `shape`, but allows setting the shape as a Property.
     */
    shapeProperty?: TReadOnlyProperty<InputShape>;
    /**
     * Sets the bounds method for the Path. This determines how our (self) bounds are computed, and can particularly
     * determine how expensive to compute our bounds are if we have a stroke.
     *
     * There are the following options:
     * - 'accurate' - Always uses the most accurate way of getting bounds. Computes the exact stroked bounds.
     * - 'unstroked' - Ignores any stroke, just gives the filled bounds.
     *                 If there is a stroke, the bounds will be marked as inaccurate
     * - 'tightPadding' - Pads the filled bounds by enough to cover everything except mitered joints.
     *                     If there is a stroke, the bounds wil be marked as inaccurate.
     * - 'safePadding' - Pads the filled bounds by enough to cover all line joins/caps.
     * - 'none' - Returns Bounds2.NOTHING. The bounds will be marked as inaccurate.
     *            NOTE: It's important to provide a localBounds override if you use this option, so its bounds cover the
     *            Path's shape. (path.localBounds = ...)
     */
    boundsMethod?: PathBoundsMethod;
};
type ParentOptions = PaintableOptions & NodeOptions;
export type PathOptions = SelfOptions & ParentOptions;
declare const Path_base: typeof Node & import("../../../phet-core/js/types/Constructor.js").default<import("./Paintable.js").TPaintable>;
export default class Path extends Path_base {
    _shape: ParsedShape;
    private readonly _shapeProperty;
    private _strokedShape;
    _boundsMethod: PathBoundsMethod;
    private readonly _invalidShapeListener;
    private _invalidShapeListenerAttached;
    /**
     * Creates a Path with a given shape specifier (a Shape, a string in the SVG path format, or null to indicate no
     * shape).
     *
     * Path has two additional options (above what Node provides):
     * - shape: The actual Shape (or a string representing an SVG path, or null).
     * - boundsMethod: Determines how the bounds of a shape are determined.
     *
     * @param shape - The initial Shape to display. See onShapePropertyChange() for more details and documentation.
     * @param [providedOptions] - Path-specific options are documented in PATH_OPTION_KEYS above, and can be provided
     *                             along-side options for Node
     */
    constructor(shape: InputShape | TReadOnlyProperty<InputShape>, providedOptions?: PathOptions);
    setShape(shape: InputShape): this;
    set shape(value: InputShape);
    get shape(): ParsedShape;
    /**
     * Returns the shape that was set for this Path (or for subtypes like Line and Rectangle, will return an immutable
     * Shape that is equivalent in appearance).
     *
     * It is best to generally assume modifications to the Shape returned is not supported. If there is no shape
     * currently, null will be returned.
     */
    getShape(): ParsedShape;
    private onShapePropertyChange;
    /**
     * See documentation for Node.setVisibleProperty, except this is for the shape
     */
    setShapeProperty(newTarget: TReadOnlyProperty<InputShape> | null): this;
    set shapeProperty(property: TReadOnlyProperty<InputShape> | null);
    get shapeProperty(): TProperty<InputShape>;
    /**
     * Like Node.getVisibleProperty(), but for the shape. Note this is not the same as the Property provided in
     * setShapeProperty. Thus is the nature of TinyForwardingProperty.
     */
    getShapeProperty(): TProperty<InputShape>;
    /**
     * Returns a lazily-created Shape that has the appearance of the Path's shape but stroked using the current
     * stroke style of the Path.
     *
     * NOTE: It is invalid to call this on a Path that does not currently have a Shape (usually a Path where
     *       the shape is set to null).
     */
    getStrokedShape(): Shape;
    /**
     * Returns a bitmask representing the supported renderers for the current configuration of the Path or subtype.
     *
     * Should be overridden by subtypes to either extend or restrict renderers, depending on what renderers are
     * supported.
     *
     * @returns - A bitmask that includes supported renderers, see Renderer for details.
     */
    protected getPathRendererBitmask(): number;
    /**
     * Triggers a check and update for what renderers the current configuration of this Path or subtype supports.
     * This should be called whenever something that could potentially change supported renderers happen (which can
     * be the shape, properties of the strokes or fills, etc.)
     */
    invalidateSupportedRenderers(): void;
    /**
     * Notifies the Path that the Shape has changed (either the Shape itself has be mutated, a new Shape has been
     * provided).
     *
     * NOTE: This should not be called on subtypes of Path after they have been constructed, like Line, Rectangle, etc.
     */
    private invalidateShape;
    /**
     * Invalidates the node's self-bounds and any other recorded metadata about the outline or bounds of the Shape.
     *
     * This is meant to be used for all Path subtypes (unlike invalidateShape).
     */
    protected invalidatePath(): void;
    /**
     * Attaches a listener to our Shape that will be called whenever the Shape changes.
     */
    private attachShapeListener;
    /**
     * Detaches a previously-attached listener added to our Shape (see attachShapeListener).
     */
    private detachShapeListener;
    /**
     * Computes a more efficient selfBounds for our Path.
     *
     * @returns - Whether the self bounds changed.
     */
    protected updateSelfBounds(): boolean;
    setBoundsMethod(boundsMethod: PathBoundsMethod): this;
    set boundsMethod(value: PathBoundsMethod);
    get boundsMethod(): PathBoundsMethod;
    /**
     * Returns the current bounds method. See setBoundsMethod for details.
     */
    getBoundsMethod(): PathBoundsMethod;
    /**
     * Computes the bounds of the Path (or subtype when overridden). Meant to be overridden in subtypes for more
     * efficient bounds computations (but this will work as a fallback). Includes the stroked region if there is a
     * stroke applied to the Path.
     */
    computeShapeBounds(): Bounds2;
    /**
     * Whether this Node's selfBounds are considered to be valid (always containing the displayed self content
     * of this node). Meant to be overridden in subtypes when this can change (e.g. Text).
     *
     * If this value would potentially change, please trigger the event 'selfBoundsValid'.
     */
    areSelfBoundsValid(): boolean;
    /**
     * Returns our self bounds when our rendered self is transformed by the matrix.
     */
    getTransformedSelfBounds(matrix: Matrix3): Bounds2;
    /**
     * Returns our safe self bounds when our rendered self is transformed by the matrix.
     */
    getTransformedSafeSelfBounds(matrix: Matrix3): Bounds2;
    /**
     * Called from (and overridden in) the Paintable trait, invalidates our current stroke, triggering recomputation of
     * anything that depended on the old stroke's value. (scenery-internal)
     */
    invalidateStroke(): void;
    /**
     * Returns whether this Path has an associated Shape (instead of no shape, represented by null)
     */
    hasShape(): boolean;
    /**
     * Draws the current Node's self representation, assuming the wrapper's Canvas context is already in the local
     * coordinate frame of this node.
     *
     * @param wrapper
     * @param matrix - The transformation matrix already applied to the context.
     */
    protected canvasPaintSelf(wrapper: CanvasContextWrapper, matrix: Matrix3): void;
    /**
     * Creates a SVG drawable for this Path. (scenery-internal)
     *
     * @param renderer - In the bitmask format specified by Renderer, which may contain additional bit flags.
     * @param instance - Instance object that will be associated with the drawable
     */
    createSVGDrawable(renderer: number, instance: Instance): SVGSelfDrawable;
    /**
     * Creates a Canvas drawable for this Path. (scenery-internal)
     *
     * @param renderer - In the bitmask format specified by Renderer, which may contain additional bit flags.
     * @param instance - Instance object that will be associated with the drawable
     */
    createCanvasDrawable(renderer: number, instance: Instance): CanvasSelfDrawable;
    /**
     * Whether this Node itself is painted (displays something itself).
     */
    isPainted(): boolean;
    /**
     * Computes whether the provided point is "inside" (contained) in this Path's self content, or "outside".
     *
     * @param point - Considered to be in the local coordinate frame
     */
    containsPointSelf(point: Vector2): boolean;
    /**
     * Returns a Shape that represents the area covered by containsPointSelf.
     */
    getSelfShape(): Shape;
    /**
     * Returns whether this Path's selfBounds is intersected by the specified bounds.
     *
     * @param bounds - Bounds to test, assumed to be in the local coordinate frame.
     */
    intersectsBoundsSelf(bounds: Bounds2): boolean;
    /**
     * Returns whether we need to apply a transform workaround for https://github.com/phetsims/scenery/issues/196, which
     * only applies when we have a pattern or gradient (e.g. subtypes of Paint).
     */
    private requiresSVGBoundsWorkaround;
    /**
     * Override for extra information in the debugging output (from Display.getDebugHTML()). (scenery-internal)
     */
    getDebugHTMLExtras(): string;
    /**
     * Disposes the path, releasing shape listeners if needed (and preventing new listeners from being added).
     */
    dispose(): void;
    mutate(options?: PathOptions): this;
    static readonly DEFAULT_PATH_OPTIONS: PathOptions;
}
export {};
//# sourceMappingURL=Path.d.ts.map