import { ISerializable } from "../common/ISerializable.js";
import { ShapeState } from "../common/ShapeState.js";
import { IShapeDefinition } from "../definitions/IShapeDefinition.js";
import { IShapeOptions } from "../options/interfaces/IShapeOptions.js";
import { IShapeStyle } from "../styles/interfaces/IShapeStyle.js";
import { Point } from "../types/Point.js";
import { IShape } from "./IShape.js";
/**
 * Abstract class representing a generic shape with observer functionality.
 *
 * @typeParam TDefinition - The type of shape definition implementing IShapeDefinition.
 * @typeParam TStyle - The type of shape style implementing IShapeStyle.
 * @typeParam TOptions - The type of shape options implementing IShapeOptions.
 */
export declare abstract class Shape<TDefinition extends IShapeDefinition, TStyle extends IShapeStyle, TOptions extends IShapeOptions> implements IShape, ISerializable {
    /** The shape definition, proxied to trigger observer notifications on change. */
    protected _definition: TDefinition;
    /** The style settings for the shape, proxied to trigger observer notifications on change. */
    protected _style: TStyle;
    /** The options for configuring the shape, proxied to trigger observer notifications on change. */
    protected _options: TOptions;
    /** The current state of the shape, representing its visual or interactive status. */
    protected _state: ShapeState;
    /** List of observer functions to be notified on shape changes. */
    protected observers: (() => void)[];
    /**
     * Abstract method to render the shape on the canvas.
     *
     * @param context - The 2D rendering context for the canvas.
     */
    abstract render(context: CanvasRenderingContext2D): void;
    /**
     * Constructs a Shape instance and wraps the definition, style, and options in a Proxy to handle change notifications.
     *
     * @param definition - The shape definition instance to be wrapped in a Proxy.
     * @param style - Optional style settings for the shape.
     * @param options - Optional configuration options for the shape.
     */
    constructor(definition: TDefinition, style?: TStyle, options?: TOptions);
    /**
     * Creates a proxy for the given object to track changes and notify observers.
     *
     * @param obj - The object to be proxied.
     * @returns A proxied object that triggers observer notifications on change.
     */
    private _createProxy;
    /**
     * Converts the shape's definition to an array.
     *
     * @returns An array representation of the shape's definition.
     */
    toArray(): Array<any>;
    /**
     * Converts the shape's definition to a JSON string.
     *
     * @returns A JSON string  representation of the shape's definition.
     */
    toJson(): string;
    /**
     * Makes the shape visible, allowing it to be rendered on the canvas.
     * If the shape was previously hidden, calling this method will make it appear
     * during the next rendering cycle.
     */
    show(): void;
    /**
     * Hides the shape, preventing it from being rendered on the canvas.
     * The shape will still exist and retain its properties, but it will not
     * appear during rendering until `show()` is called.
     */
    hide(): void;
    /**
     * Checks whether the shape is currently visible.
     *
     * @returns Returns true if the shape is visible and will be rendered on the canvas.
     *          Returns false if the shape is hidden and will not be rendered.
     */
    isVisible(): boolean;
    /**
     * Checks whether the shape is draggable or not.
     *
     * @returns Returns true if the shape is draggable.
     *          Returns false if the shape is not draggable.
     */
    isDraggable(): boolean;
    /**
     * Determines if the mouse is currently over the shape.
     *
     * @param mousePosition - The current mouse position.
     * @returns True if the mouse is over the shape, false otherwise.
     */
    abstract isMouseOver(mousePosition: Point): boolean;
    /**
     * Handles the drag operation by applying the given delta to the current position.
     *
     * @param delta - The change in position represented as a `Point`.
     */
    abstract onDrag(delta: Point): void;
    /**
     * Adds an observer function that will be called when the shape's state changes.
     *
     * @param observer - The observer callback function.
     */
    addObserver(observer: () => void): void;
    /**
     * Removes a previously added observer function.
     *
     * @param observer - The observer callback function to be removed.
     */
    removeObserver(observer: () => void): void;
    /**
     * Notifies all registered observers of a change in the shape's state.
     * This method is triggered when a property of the shape definition, style, or options is changed.
     */
    private notifyObservers;
    /**
     * Gets the style settings of the shape.
     *
     * @returns The current style settings.
     */
    get style(): TStyle;
    /**
     * Updates the style settings of the shape and notifies observers.
     *
     * @param style - The new style settings to apply.
     */
    set style(style: TStyle);
    /**
     * Gets the configuration options of the shape.
     *
     * @returns The current options.
     */
    get options(): TOptions;
    /**
     * Updates the configuration options of the shape and notifies observers.
     *
     * @param options - The new options to apply.
     */
    set options(options: TOptions);
    /**
     * Gets the current state of the shape.
     *
     * @returns The current state of the shape.
     */
    get state(): ShapeState;
    /**
     * Sets a new state for the shape.
     *
     * @param state - The new state to assign to the shape.
     */
    set state(state: ShapeState);
    /**
     * Retrieves the effective style of the shape based on its current state.
     *
     * @returns The computed style object for the current shape state, with state-specific overrides merged in as necessary.
     */
    get stateStyle(): TStyle;
    /**
     * Determines if the current state style includes a visible border.
     *
     * @returns `true` if `borderColor` and `borderWidth` are defined and indicate a visible border; otherwise, `false`.
     */
    protected hasBorder(): boolean;
}
