import { EventEmitter } from '../../stencil-public-runtime';
import { vertexvis } from '@vertexvis/frame-streaming-protos';
import { BoundingBox, Plane, Point, Ray, Vector3 } from '@vertexvis/geometry';
import { StreamApi } from '@vertexvis/stream-api';
import { Disposable } from '@vertexvis/utils';
import { ReceivedFrame } from '../..';
import { Cursor, CursorManager } from '../cursors';
import { Camera, CameraRenderOptions, Scene } from '../scenes';
import { DepthBuffer, EntityType, FrameCameraBase, Interactions, Viewport } from '../types';
import { TapEventDetails, TapEventKeys } from './tapEventDetails';
export type SceneProvider = () => Promise<Scene>;
export type InteractionConfigProvider = () => Interactions.InteractionConfig;
export type CameraTransform<T extends Camera = Camera, R extends Camera = Camera> = (data: {
    camera: T;
    viewport: Viewport;
    scale: Point.Point;
    boundingBox: BoundingBox.BoundingBox;
    frame: ReceivedFrame;
    depthBuffer?: DepthBuffer;
}) => R;
export interface PanData {
    hitPt: Vector3.Vector3;
    hitPlane: Plane.Plane;
    startingCamera: FrameCameraBase;
}
export interface ZoomData {
    hitPt: Vector3.Vector3;
    hitPlane: Plane.Plane;
}
/**
 * The `InteractionApi` provides methods that API developers can use to modify
 * the internal state of an interaction.
 */
export declare abstract class InteractionApi<T extends Camera = Camera> {
    protected stream: StreamApi;
    private cursors;
    protected getConfig: InteractionConfigProvider;
    protected getScene: SceneProvider;
    protected getFrame: () => ReceivedFrame | undefined;
    getViewport: () => Viewport;
    private tapEmitter;
    private doubleTapEmitter;
    private longPressEmitter;
    private interactionStartedEmitter;
    private interactionFinishedEmitter;
    protected currentCamera?: Camera;
    private sceneLoadingPromise?;
    private lastAngle;
    private worldRotationPoint?;
    protected panData?: PanData;
    protected zoomData?: ZoomData;
    constructor(stream: StreamApi, cursors: CursorManager, getConfig: InteractionConfigProvider, getScene: SceneProvider, getFrame: () => ReceivedFrame | undefined, getViewport: () => Viewport, tapEmitter: EventEmitter<TapEventDetails>, doubleTapEmitter: EventEmitter<TapEventDetails>, longPressEmitter: EventEmitter<TapEventDetails>, interactionStartedEmitter: EventEmitter<void>, interactionFinishedEmitter: EventEmitter<void>);
    /**
     * Displays a cursor over the viewer with the given priority. Cursors with
     * higher priority will take precedence over cursors with lower priorities if
     * there's more than a single cursor added.
     *
     * @param cursor The cursor to add.
     * @param priority The priority of the cursor.
     * @returns A `Disposable` that can be used to remove the cursor.
     */
    addCursor(cursor: Cursor, priority?: number): Disposable;
    /**
     * Returns a 3D point in world space for the given 2D point in viewport space.
     *
     * @param point A point in 2D viewport space to transform.
     * @returns A 3D point in world space.
     */
    getWorldPointFromViewport(point: Point.Point): Promise<Vector3.Vector3 | undefined>;
    /**
     * Returns the entity at the given point in viewport space.
     *
     * @param point A point in viewport space.
     * @returns The entity that was found.
     */
    getEntityTypeAtPoint(point: Point.Point): Promise<EntityType>;
    /**
     * Generates a ray from the given point, in viewport coordinates.
     *
     * @param point A point in viewport coordinates.
     * @returns A ray representing the direction of the point in world
     * coordinates.
     */
    getRayFromPoint(point: Point.Point): Ray.Ray;
    /**
     * Emits a tap event with the provided position relative to the viewer
     * canvas, along with the set of modifier keys held (if applicable).
     *
     * @param position An {x, y} coordinate marking the position of the tap.
     * @param keyDetails A set of pressed keyboard keys that you want to include
     *  in the tap event.
     */
    tap(position: Point.Point, keyDetails?: Partial<TapEventKeys>, buttons?: number): Promise<void>;
    doubleTap(position: Point.Point, keyDetails?: Partial<TapEventKeys>, buttons?: number): Promise<void>;
    longPress(position: Point.Point, keyDetails?: Partial<TapEventKeys>, buttons?: number): Promise<void>;
    /**
     * Marks the start of an interaction. This method must be called before
     * performing any additional interaction operations. Use `endInteraction()` to
     * mark the end of an interaction.
     */
    beginInteraction(): Promise<void>;
    /**
     * Invokes a function to transform the scene's camera and request a new image
     * for the updated scene.
     *
     * @param t A function to transform the camera. Function will be passed the
     *  camera and scene viewport and is expected to return an updated camera.
     */
    transformCamera(t: CameraTransform<T>): Promise<void>;
    transformCamera(t: CameraTransform<T>, renderOptions?: CameraRenderOptions): Promise<void>;
    /**
     * Performs a twist operation of the scene's camera, and requests a new image
     * for the updated scene.
     *
     * @param delta A position delta `{x, y}` in the 2D coordinate space of the
     *  viewer or the angle to twist the camera by around the view vector.
     */
    twistCamera(delta: number): Promise<void>;
    twistCamera(delta: Point.Point): Promise<void>;
    /**
     * Moves the camera's position and look at to the given screen coordinate.
     *
     * If the screen coordinate intersects with an object, the camera will track
     * the hit point so the mouse position is always under the mouse.
     *
     * If the screen coordinate doesn't intersect with an object, then ???.
     *
     * @param screenPt A point in screen coordinates.
     */
    panCameraToScreenPoint(screenPt: Point.Point): Promise<void>;
    /**
     * Performs a view all operation for the scene's bounding box, and requests a
     * new image for the updated scene.
     */
    viewAll(): Promise<void>;
    /**
     * Performs a rotate operation of the scene around the camera's look at point,
     * and requests a new image for the updated scene.
     *
     * @param delta A position delta `{x, y}` in the 2D coordinate space of the
     *  viewer.
     */
    rotateCamera(delta: Point.Point): Promise<void>;
    rotateCameraAtPoint(delta: Point.Point, point: Point.Point): Promise<void>;
    /**
     * Performs a zoom operation of the scene's camera, and requests a new image
     * for the updated scene.
     *
     * @param delta The distance to zoom. Positive values zoom in and negative
     *  values zoom out.
     */
    zoomCamera(delta: number): Promise<void>;
    /**
     * Performs a pivot operation of the scene's camera, updating the lookAt
     * while maintaining the position, and requests a new image for the
     * updated scene.
     *
     * @param degreesLocalX The angle to rotate the lookAt point around the local x-axis
     * @param degreesLocalY The angle to rotate the lookAt point around the local y-axis
     */
    pivotCamera(degreesLocalX: number, degreesLocalY: number): Promise<void>;
    /**
     * Marks the end of an interaction.
     */
    endInteraction(): Promise<void>;
    /**
     * resets the last recorded angle for a twist op
     */
    resetLastAngle(): void;
    /**
     * Indicates if the API is in an interacting state.
     */
    isInteracting(): boolean;
    /**
     * Returns the pixel threshold that should be used to detect
     * movement based on the type of pointer input being coarse or fine.
     * This threshold is based on the configured `coarsePointerThreshold`
     * or the `finePointerThreshold` respectively.
     *
     * @param isTouch - Whether the event is a touch or not, if false or
     * undefined, a media query will be used to determine pointer type
     * @returns The pixel threshold.
     */
    pixelThreshold(isTouch?: boolean): number;
    /**
     * Performs a hit test at the given point and returns a list of hit results
     * indicating any scene items that exist at the given point.
     *
     * @param pt A point, in viewport coordinates.
     * @returns A promise that resolves with the list of hit results.
     */
    hitItems(pt: Point.Point): Promise<vertexvis.protobuf.stream.IHit[]>;
    private emitTapEvent;
    private isCoarseInputDevice;
    protected getWorldPoint(point: Point.Point, depthBuffer: DepthBuffer, fallbackPoint: Vector3.Vector3): Vector3.Vector3;
    /**
     * Performs a pan operation of the scene's camera, and requests a new image
     * for the updated scene.
     *
     * @param delta A position delta `{x, y}` in the 2D coordinate space of the
     *  viewer.
     */
    abstract panCameraByDelta(delta: Point.Point): Promise<void>;
    abstract zoomCameraToPoint(point: Point.Point, delta: number): Promise<void>;
}
