import { vertexvis } from '@vertexvis/frame-streaming-protos';
import { BoundingBox, Dimensions, Point } from '@vertexvis/geometry';
import { StreamApi } from '@vertexvis/stream-api';
import { UUID } from '@vertexvis/utils';
import { CameraType } from '../../interfaces';
import { CameraTypeEncoder, FrameDecoder } from '../mappers';
import { SceneViewStateIdentifier } from '../types';
import { Frame } from '../types/frame';
import { Camera, CameraRenderOptions } from '.';
import { ColorMaterial } from './colorMaterial';
import { CrossSectioner } from './crossSectioner';
import { ItemOperation, ItemOperationBuilder, PmiAnnotationOperation, PmiAnnotationOperationBuilder, PmiAnnotationOperations, RepresentationId, SceneItemOperations } from './operations';
import { QueryExpression, SceneElementQueryExecutor, SceneItemQueryExecutor } from './queries';
import { Raycaster } from './raycaster';
export interface SceneExecutionOptions {
    suppliedCorrelationId?: string;
}
export interface SceneElementsExecutionOptions extends SceneExecutionOptions {
    /**
     * Skips the wait for a frame correlated to this alteration before
     * completing the Promise returned by the `execute()` method.
     */
    skipAwaitCorrelatedFrame?: boolean;
}
export interface SceneItemsExecutionOptions extends SceneExecutionOptions {
    /**
     * Waits for the frame correlated to this alteration before
     * completing the Promise returned by the `execute()` method.
     */
    awaitCorrelatedFrame?: boolean;
}
export interface ApplySceneViewStateOptions extends SceneElementsExecutionOptions, CameraRenderOptions {
    waitForAnimation?: boolean;
    cameraTypeOverride?: CameraType;
}
export interface ResetViewOptions {
    includeCamera?: boolean;
    cameraTypeOverride?: CameraType;
    suppliedCorrelationId?: string;
}
export interface SceneElementOperationsBuilder {
    isItemBuilder(): this is SceneItemOperationsBuilder;
    isAnnotationBuilder(): this is PmiAnnotationOperationsBuilder;
}
/**
 * A class that is responsible for building operations on scene items for a specific scene.
 * This executor requires a query, and expects `execute()` to be invoked in
 * order for the changes to take effect.
 */
export declare class SceneItemOperationsBuilder implements SceneItemOperations<SceneItemOperationsBuilder>, SceneElementOperationsBuilder {
    private query;
    private builder;
    constructor(query: QueryExpression, givenBuilder?: ItemOperationBuilder);
    isItemBuilder(): this is SceneItemOperationsBuilder;
    isAnnotationBuilder(): this is PmiAnnotationOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their default
     * material overridden to match the specified material.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Override the material for the item with the `item-uuid` ID to
     * // be red with an opacity of 0.5.
     * await scene.elements((op) => [
     *   op
     *     .items.where((q) => q.withItemId('item-uuid'))
     *     .materialOverride(ColorMaterial.create(255, 0, 0, 0.5)),
     * ]);
     *
     * // Override the material for the item with the `item-uuid` ID to
     * // be red with an opacity of 1.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).materialOverride('#ff0000'),
     * ]).execute();
     * ```
     */
    materialOverride(color: ColorMaterial | string): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should be hidden.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Hide the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).hide(),
     * ]).execute();
     * ```
     */
    hide(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should be shown.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Show the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).show(),
     * ]).execute();
     * ```
     */
    show(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should be selected.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Select the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).select(),
     * ]).execute();
     * ```
     */
    select(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should be deselected.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Deselect the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).deselect(),
     * ]).execute();
     * ```
     */
    deselect(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have any overridden
     * material removed.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Clear the overridden material on the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearMaterialOverrides(),
     * ]);
     * ```
     */
    clearMaterialOverrides(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their
     * transformation matrix overridden to match the specified transformation
     * matrix.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Override the transformation matrix for the item with the `item-uuid` ID to
     * // move the element along the x-axis
     * await scene.elements((op) => [
     *   op
     *     .items.where((q) => q.withItemId('item-uuid'))
     *     .transform(Matrix4.makeTranslation(Vector3.create(100, 0, 0))),
     * ]);
     * ```
     */
    transform(matrix: vertexvis.protobuf.core.IMatrix4x4f | number[]): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their overridden
     * transformation matrix removed. The `cascade` flag determines whether
     * children of the scene items matching the query should also have their overridden
     * transformation matrix removed, and defaults to `true`.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Clear the overridden the transformation matrix for the item with the `item-uuid` ID
     * // and do not cascade to preserve transformations on children
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearTransforms(false),
     * ]);
     *
     * // Clear the overridden the transformation matrix for the item with the `item-uuid` ID
     * // and cascade to clear overridden transformations on children
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearTransforms(true),
     * ]);
     * ```
     */
    clearTransforms(cascade?: boolean): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their phantom state
     * overridden to match the specified `phantomState` flag. If the
     * `phantomState` flag is not provided, it will default to `true`.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Mark the item with the `item-uuid` ID as phantom
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).setPhantom(true),
     * ]);
     *
     * // Unmark the item with the `item-uuid` ID as phantom
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).setPhantom(false),
     * ]);
     * ```
     */
    setPhantom(phantomState?: boolean): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their overridden
     * phantom state removed.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Clear the overridden phantom state of the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearPhantom(),
     * ]);
     * ```
     */
    clearPhantom(): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their end item
     * state overridden to match the specified `endItemState` flag. If the
     * `endItemState` flag is not provided, it will default to `true`.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Mark the item with the `item-uuid` ID as an end item
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).setEndItem(true),
     * ]);
     *
     * // Unmark the item with the `item-uuid` ID as an end item
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).setEndItem(false),
     * ]);
     * ```
     *
     * @remarks
     * End item states do not propagate to children similar to other states like
     * other operations. I.e. calling setEndItem(false) on an item will cause it
     * to be unmarked as an end item, but any children where setEndItem(true) was
     * called previously will remain as end items.
     */
    setEndItem(endItemState?: boolean): SceneItemOperationsBuilder;
    /**
     * Specifies that the scene items matching the query should have their overridden
     * end item state removed.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Clear the overridden end item state of the item with the `item-uuid` ID
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearEndItem(),
     * ]);
     * ```
     */
    clearEndItem(): SceneItemOperationsBuilder;
    /**
     * Changes the rendition of a scene item matching the query. This operation only
     * applies to scene items that reference a revision that contains the given
     * rendition.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the matching item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).viewRenditionById('rendition-uuid'),
     * ]);
     * ```
     */
    viewRenditionById(id: UUID.UUID): SceneItemOperationsBuilder;
    /**
     * Changes the rendition of any scene item matching the query that contains a
     * rendition with the given supplied ID. This operation only applies to scene items
     * that reference a revision that contain a rendition with a matching supplied
     * ID.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the given item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).viewRenditionBySuppliedId('rendition-supplied-id'),
     * ]);
     * ```
     */
    viewRenditionBySuppliedId(suppliedId: string): SceneItemOperationsBuilder;
    /**
     * Changes the rendition of scene items matching the query back to their revision's
     * default rendition. This operation only applies to scene items that reference a
     * revision.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the given item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).viewDefaultRendition(),
     * ]);
     * ```
     */
    viewDefaultRendition(): SceneItemOperationsBuilder;
    /**
     * Clears the rendition of scene items matching the query, which will revert the
     * scene item back to the rendition used when creating the item.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the given item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearRendition(),
     * ]);
     * ```
     */
    clearRendition(): SceneItemOperationsBuilder;
    /**
     * Changes the representation of scene items matching a query. This operation only
     * applies to scene items that reference a rendition with the given representation
     * ID.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the given item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).viewRepresentation('rep-id'),
     * ]);
     * ```
     */
    viewRepresentation(id: RepresentationId): SceneItemOperationsBuilder;
    /**
     * Clears the representation for scene items matching the query.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Switch the rendition of the given item.
     * await scene.elements((op) => [
     *   op.items.where((q) => q.withItemId('item-uuid')).clearRepresentation(),
     * ]);
     * ```
     */
    clearRepresentation(): SceneItemOperationsBuilder;
    /**
     * @internal
     */
    build(): QueryOperation;
}
/**
 * @ignore
 * @beta PMI Annotation operations are being actively developed. These APIs
 * should be considered unstable, and will potentially change with following
 * releases.
 *
 * A class that is responsible for building operations on pmi annotations for a specific scene.
 * This executor requires a query, and expects `execute()` to be invoked in
 * order for the changes to take effect.
 */
export declare class PmiAnnotationOperationsBuilder implements PmiAnnotationOperations<PmiAnnotationOperationsBuilder>, SceneElementOperationsBuilder {
    private query;
    private builder;
    constructor(query: QueryExpression, givenBuilder?: PmiAnnotationOperationBuilder);
    isItemBuilder(): this is SceneItemOperationsBuilder;
    isAnnotationBuilder(): this is PmiAnnotationOperationsBuilder;
    /**
     * @ignore
     * @beta PMI Annotation operations are being actively developed. These APIs
     * should be considered unstable, and will potentially change with following
     * releases.
     *
     * Specifies that the PMI annotations matching the query should be hidden.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Hide the annotation with the `annotation-uuid` ID
     * await scene.elements((op) => [
     *   op.annotations.where((q) => q.withAnnotationId('annotation-uuid')).hide(),
     * ]).execute();
     * ```
     */
    hide(): PmiAnnotationOperationsBuilder;
    /**
     * @ignore
     * @beta PMI Annotation operations are being actively developed. These APIs
     * should be considered unstable, and will potentially change with following
     * releases.
     *
     * Specifies that the PMI annotations matching the query should be shown.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Show the annotation with the `annotation-uuid` ID
     * await scene.elements((op) => [
     *   op.annotations.where((q) => q.withAnnotationId('annotation-uuid')).show(),
     * ]).execute();
     * ```
     */
    show(): PmiAnnotationOperationsBuilder;
    /**
     * @ignore
     * @beta PMI Annotation operations are being actively developed. These APIs
     * should be considered unstable, and will potentially change with following
     * releases.
     *
     * Specifies that the PMI annotations matching the query should be selected.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Select the annotation with the `annotation-uuid` ID
     * await scene.elements((op) => [
     *   op.annotations.where((q) => q.withAnnotationId('annotation-uuid')).select(),
     * ]).execute();
     * ```
     */
    select(): PmiAnnotationOperationsBuilder;
    /**
     * @ignore
     * @beta PMI Annotation operations are being actively developed. These APIs
     * should be considered unstable, and will potentially change with following
     * releases.
     *
     * Specifies that the PMI annotations matching the query should be deselected.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Deselect the annotation with the `annotation-uuid` ID
     * await scene.elements((op) => [
     *   op.annotations.where((q) => q.withAnnotationId('annotation-uuid')).deselect(),
     * ]).execute();
     * ```
     */
    deselect(): PmiAnnotationOperationsBuilder;
    /**
     * @internal
     */
    build(): QueryAnnotationOperation;
}
export interface QueryOperation {
    query: QueryExpression;
    operations: ItemOperation[];
}
export interface QueryAnnotationOperation {
    query: QueryExpression;
    operations: PmiAnnotationOperation[];
}
export declare class OperationExecutor<T extends SceneExecutionOptions> {
    protected sceneViewId: UUID.UUID;
    protected stream: StreamApi;
    protected decodeFrame: FrameDecoder;
    protected dimensions: Dimensions.Dimensions;
    protected sceneItemQueryOperations: QueryOperation[];
    protected pmiAnnotationQueryOperations: QueryAnnotationOperation[];
    constructor(sceneViewId: UUID.UUID, stream: StreamApi, decodeFrame: FrameDecoder, dimensions: Dimensions.Dimensions, sceneItemQueryOperations: QueryOperation[], pmiAnnotationQueryOperations: QueryAnnotationOperation[]);
    execute(executionOptions?: T): Promise<void>;
}
export declare class SceneItemsOperationExecutor extends OperationExecutor<SceneItemsExecutionOptions> {
    execute(executionOptions?: SceneItemsExecutionOptions): Promise<void>;
}
export declare class SceneElementsOperationExecutor extends OperationExecutor<SceneElementsExecutionOptions> {
    execute(executionOptions?: SceneElementsExecutionOptions): Promise<void>;
}
export type TerminalItemOperationBuilder = PmiAnnotationOperationsBuilder | SceneItemOperationsBuilder | Array<SceneItemOperationsBuilder | PmiAnnotationOperationsBuilder>;
export type ImageScaleProvider = () => Point.Point | undefined;
/**
 * The features of a scene view state that can be applied to the current scene
 */
export type SceneViewStateFeature = 'camera' | 'cross_section' | 'material_overrides' | 'selection' | 'transforms' | 'visibility' | 'phantom' | 'shading';
/**
 * A class that represents the `Scene` that has been loaded into the viewer. On
 * it, you can retrieve attributes of the scene, such as the camera. It also
 * contains methods for updating the scene and performing requests to rerender
 * the scene.
 */
export declare class Scene {
    private stream;
    private frame;
    private decodeFrame;
    private encodeCameraType;
    private imageScaleProvider;
    private dimensions;
    readonly sceneId: UUID.UUID;
    readonly sceneViewId: UUID.UUID;
    private sceneViewStateLoader;
    constructor(stream: StreamApi, frame: Frame, decodeFrame: FrameDecoder, encodeCameraType: CameraTypeEncoder, imageScaleProvider: ImageScaleProvider, dimensions: Dimensions.Dimensions, sceneId: UUID.UUID, sceneViewId: UUID.UUID);
    /**
     * Applies the provided scene view state to the scene.
     */
    applySceneViewState(sceneViewStateId: UUID.UUID | SceneViewStateIdentifier.SceneViewStateIdentifier, opts?: ApplySceneViewStateOptions): Promise<vertexvis.protobuf.stream.ILoadSceneViewStateResult | undefined>;
    /**
     * Applies the specified features of the provided scene view state to the scene.
     */
    applyPartialSceneViewState(sceneViewStateId: UUID.UUID | SceneViewStateIdentifier.SceneViewStateIdentifier, featuresToApply: SceneViewStateFeature[], opts?: ApplySceneViewStateOptions): Promise<vertexvis.protobuf.stream.ILoadSceneViewStateResult | undefined>;
    /**
     * Resets the view to its default state, with the ability to reset the camera to that of the base scene.
     */
    reset(opts?: ResetViewOptions): Promise<vertexvis.protobuf.stream.IResetViewResult | undefined>;
    /**
     * Returns an executor that accepts a function as a parameter that contains one or more operations to apply
     * to the scene view. The operations will be applied transactionally.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Deselect everything, then select a specific item by ID
     * await scene.items(op => [
     *   op.items.where(q => q.all()).deselect(),
     *   op.items.where(q => q.withItemId('item-id')).select(),
     * ]).execute();
     * ```
     *
     * @see {@link RootQuery} for more information on available queries.
     *
     * @see {@link SceneItemOperationsBuilder} for more information on available operations.
     *
     * @param operations
     */
    items(operations: (q: SceneItemQueryExecutor) => TerminalItemOperationBuilder): SceneItemsOperationExecutor;
    /**
     * Returns an executor that accepts a function as a parameter that contains one or more operations to apply
     * to items or annotations in the scene view. The operations will be applied transactionally.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     *
     * // Deselect everything, then select a specific scene item by ID
     * await scene.elements(op => [
     *   op.items.where(q => q.all()).deselect(),
     *   op.annotations.where(q => q.all()).deselect(),
     *   op.items.where(q => q.withItemId('item-id')).select(),
     * ]).execute();
     * ```
     *
     * @see {@link RootQuery} for more information on available queries on scene items.
     *
     * @see {@link SceneItemOperationsBuilder} for more information on available operations to the scene items.
     *
     * @see {@link PmiAnnotationRootQuery} for more information on available queries on PMI annotations.
     *
     * @see {@link PmiAnnotationOperationsBuilder} for more information on available operations to the PMI annotations.
     *
     * @param operations
     */
    elements(operations: (q: SceneElementQueryExecutor) => TerminalItemOperationBuilder): SceneElementsOperationExecutor;
    /**
     * An instance of the current camera of the scene. The camera provides a number of
     * methods that can be used in combination with the `render` method to make programmatic
     * updates to the scene's camera.
     *
     * @example
     * ```typescript
     * const viewer = document.querySelector('vertex-viewer');
     * const scene = await viewer.scene();
     * const camera = scene.camera();
     *
     * // Fit the camera to the visible bounding box of the scene with a 1 second animation
     * await camera.viewAll().render({ animation: { milliseconds: 1000 } });
     * ```
     *
     * @see {@link Camera} for more information on available camera operations.
     */
    camera(): Camera;
    isOrthographic(): boolean;
    /**
     * Returns the current visible BoundingBox for the scene.
     */
    boundingBox(): BoundingBox.BoundingBox;
    /**
     * CrossSectioner to update cross sectioning planes and get current configuration.
     */
    crossSectioning(): CrossSectioner;
    /**
     * Raycaster to request items that intersect a point.
     */
    raycaster(): Raycaster;
    /**
     * The current viewport of the scene, in pixels.
     */
    viewport(): Dimensions.Dimensions;
    /**
     * The current x and y scale of the rendered image.
     */
    scale(): Point.Point;
}
