/********************************************************************************
 * Copyright (c) 2024 EclipseSource and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/
import { Bounds, Dimension, GModelElement, GRoutingHandle, Locateable, Movement, Point, ResolvedElementMove, TypeGuard, Vector } from '@eclipse-glsp/sprotty';
import { BoundsAwareModelElement, MoveableElement, ResizableModelElement } from '../../../utils/gmodel-util';
import { GResizeHandle, ResizeHandleLocation } from '../../change-bounds/model';
import { DiagramMovementCalculator } from '../../change-bounds/tracker';
import { ChangeBoundsManager } from './change-bounds-manager';
export interface ElementTrackingOptions {
    /** Snap position. Default: true. */
    snap: boolean | MouseEvent | KeyboardEvent | any;
    /** Restrict position. Default: true */
    restrict: boolean | MouseEvent | KeyboardEvent | any;
    /** Validate operation. Default: true */
    validate: boolean;
    /** Skip operations that do not trigger change. Default: true */
    skipStatic: boolean;
}
export interface MoveOptions extends ElementTrackingOptions {
    /** Skip operations are invalid. Default: false */
    skipInvalid: boolean;
}
export declare const DEFAULT_MOVE_OPTIONS: MoveOptions;
export type MoveableElements = MoveableElement[] | {
    ctx: GModelElement;
    elementIDs: string[];
    guard?: TypeGuard<MoveableElement>;
};
export interface TrackedElementMove extends ResolvedElementMove {
    moveVector: Vector;
    sourceVector: Vector;
    valid: boolean;
}
export declare namespace TrackedElementMove {
    function is(obj: any): obj is TrackedElementMove;
}
export type TypedElementMove<T extends MoveableElement> = TrackedElementMove & {
    element: T;
};
export interface TrackedMove extends Movement {
    elementMoves: TrackedElementMove[];
    valid: boolean;
    options: MoveOptions;
}
export declare namespace TrackedMove {
    function is(obj: any): obj is TrackedMove;
}
export interface ResizeOptions extends ElementTrackingOptions {
    /** Skip resizes that do not actually change the dimension of the element. Default: true. */
    skipStatic: boolean;
    /** Perform symmetric resize on the opposite side. Default: false. */
    symmetric: boolean | MouseEvent | KeyboardEvent | any;
    /**
     * Avoids resizes smaller than the minimum size which will result in invalid sizes.
     * Please note that the snapping will be applied before the constraining so an element may still be resized to an unsnapped size.
     *
     * Default: true.
     */
    constrainResize: boolean;
    /** Skip resizes that produce an invalid size. Default: false. */
    skipInvalidSize: boolean;
    /** Skip resizes that produce an invalid move. Default: false. */
    skipInvalidMove: boolean;
}
export declare const DEFAULT_RESIZE_OPTIONS: ResizeOptions;
export interface TrackedHandleMove extends TypedElementMove<MoveableResizeHandle> {
}
export interface TrackedElementResize {
    element: BoundsAwareModelElement;
    fromBounds: Bounds;
    toBounds: Bounds;
    valid: {
        size: boolean;
        move: boolean;
    };
}
export declare namespace TrackedElementResize {
    function is(obj: any): obj is TrackedElementResize;
}
export interface TrackedResize extends Movement {
    handleMove: TrackedHandleMove;
    elementResizes: TrackedElementResize[];
    valid: {
        size: boolean;
        move: boolean;
    };
    options: ResizeOptions;
}
export declare class ChangeBoundsTracker {
    readonly manager: ChangeBoundsManager;
    protected diagramMovement: DiagramMovementCalculator;
    constructor(manager: ChangeBoundsManager);
    startTracking(): this;
    updateTrackingPosition(param: Vector | Movement | TrackedMove): void;
    isTracking(): boolean;
    stopTracking(): this;
    moveElements(elements: MoveableElements, opts?: Partial<MoveOptions>): TrackedMove;
    protected resolveMoveOptions(opts?: Partial<MoveOptions>): MoveOptions;
    protected calculateDiagramMovement(): Movement;
    protected getMoveableElements(elements: MoveableElements, options: MoveOptions): MoveableElement[];
    protected skipElementMove(elementMove: TrackedElementMove, options: MoveOptions): boolean;
    protected calculateElementMove<T extends MoveableElement>(element: T, vector: Vector, options: MoveOptions): TypedElementMove<T>;
    protected snapPosition(elementMove: TrackedElementMove, opts: MoveOptions): Point;
    protected restrictMovement(elementMove: TrackedElementMove, opts: MoveOptions): Point;
    protected validateElementMove(elementMove: TrackedElementMove, opts: MoveOptions): boolean;
    resizeElements(handle: GResizeHandle, opts?: Partial<ResizeOptions>): TrackedResize;
    protected resolveResizeOptions(opts?: Partial<ResizeOptions>): ResizeOptions;
    protected calculateHandleMove(handle: MoveableResizeHandle, diagramMovement: Vector, opts?: Partial<ResizeOptions>): TrackedHandleMove;
    protected getResizableElements(handle: GResizeHandle, options: ResizeOptions): ResizableModelElement[];
    protected skipElementResize(elementResize: TrackedElementResize, options: ResizeOptions): boolean;
    protected calculateElementResize(element: ResizableModelElement, handleMove: TrackedHandleMove, options: ResizeOptions): TrackedElementResize;
    protected calculateElementBounds(element: ResizableModelElement, handleMove: TrackedHandleMove, options: ResizeOptions): Bounds;
    protected calculateSymmetricHandleMove(handleMove: TrackedHandleMove, options: ResizeOptions): TrackedHandleMove;
    protected calculateBounds(src: Readonly<Bounds>, handleMove?: TrackedHandleMove): Bounds;
    protected doCalculateBounds(src: Readonly<Bounds>, vector: Vector, location: ResizeHandleLocation): Bounds;
    protected constrainResizeVector(src: Readonly<Bounds>, handleMove: TrackedHandleMove, minimum: Dimension): Vector;
    dispose(): void;
}
export declare class MoveableResizeHandle extends GResizeHandle implements Locateable {
    protected handle: GResizeHandle;
    location: ResizeHandleLocation;
    readonly position: Point;
    constructor(handle: GResizeHandle, location?: ResizeHandleLocation, position?: Point);
    opposite(): MoveableResizeHandle;
}
export declare class MoveableRoutingHandle extends GRoutingHandle implements Locateable {
    protected handle: GRoutingHandle;
    readonly position: Point;
    constructor(handle: GRoutingHandle, position: Point);
}
//# sourceMappingURL=change-bounds-tracker.d.ts.map