/**
 * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @author David Sehnal <david.sehnal@gmail.com>
 */
import { BehaviorSubject } from 'rxjs';
import { now } from '../mol-util/now';
import { Vec3, Vec2 } from '../mol-math/linear-algebra';
import { InputObserver, ModifiersKeys, ButtonsType } from '../mol-util/input/input-observer';
import { RendererStats } from '../mol-gl/renderer';
import { GraphicsRenderObject } from '../mol-gl/render-object';
import { WebGLContext } from '../mol-gl/webgl/context';
import { Representation } from '../mol-repr/representation';
import { PickingId } from '../mol-geo/geometry/picking';
import { MarkerAction } from '../mol-util/marker-action';
import { Camera } from './camera';
import { ParamDefinition as PD } from '../mol-util/param-definition';
import { Canvas3dInteractionHelper } from './helper/interaction-events';
import { PickData } from './passes/pick';
import { ImagePass, ImageProps } from './passes/image';
import { Sphere3D } from '../mol-math/geometry';
import { Passes } from './passes/passes';
export declare const Canvas3DParams: {
    camera: PD.Group<PD.Normalize<{
        mode: "perspective" | "orthographic";
        helper: PD.Normalize<{
            axes: any;
        }>;
        stereo: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            eyeSeparation: any;
            focus: any;
        }>, "on">;
        manualReset: boolean;
    }>>;
    cameraFog: PD.Mapped<PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
        intensity: number;
    }>, "on">>;
    cameraClipping: PD.Group<PD.Normalize<{
        radius: number;
        far: boolean;
    }>>;
    viewport: PD.Mapped<PD.NamedParams<PD.Normalize<unknown>, "canvas"> | PD.NamedParams<PD.Normalize<{
        x: number;
        y: number;
        width: number;
        height: number;
    }>, "static-frame"> | PD.NamedParams<PD.Normalize<{
        x: number;
        y: number;
        width: number;
        height: number;
    }>, "relative-frame">>;
    cameraResetDurationMs: PD.Numeric;
    transparentBackground: PD.BooleanParam;
    multiSample: PD.Group<PD.Normalize<{
        mode: string;
        sampleLevel: number;
    }>>;
    postprocessing: PD.Group<PD.Normalize<{
        occlusion: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            samples: any;
            radius: any;
            bias: any;
            blurKernelSize: any;
        }>, "on">;
        outline: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            scale: any;
            threshold: any;
        }>, "on">;
        antialiasing: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            edgeThreshold: any;
            maxSearchSteps: any;
        }>, "smaa"> | PD.NamedParams<PD.Normalize<{
            edgeThresholdMin: any;
            edgeThresholdMax: any;
            iterations: any;
            subpixelQuality: any;
        }>, "fxaa">;
    }>>;
    marking: PD.Group<PD.Normalize<{
        enabled: boolean;
        highlightEdgeColor: import("../mol-util/color").Color;
        selectEdgeColor: import("../mol-util/color").Color;
        edgeScale: number;
        ghostEdgeStrength: number;
        innerEdgeFactor: number;
    }>>;
    renderer: PD.Group<PD.Normalize<{
        backgroundColor: import("../mol-util/color").Color;
        pickingAlphaThreshold: number;
        interiorDarkening: number;
        interiorColorFlag: boolean;
        interiorColor: import("../mol-util/color").Color;
        highlightColor: import("../mol-util/color").Color;
        selectColor: import("../mol-util/color").Color;
        highlightStrength: number;
        selectStrength: number;
        markerPriority: number;
        xrayEdgeFalloff: number;
        style: PD.NamedParams<PD.Normalize<unknown>, "flat"> | PD.NamedParams<PD.Normalize<unknown>, "metallic"> | PD.NamedParams<PD.Normalize<{
            lightIntensity: any;
            ambientIntensity: any;
            metalness: any;
            roughness: any;
            reflectivity: any;
        }>, "custom"> | PD.NamedParams<PD.Normalize<unknown>, "matte"> | PD.NamedParams<PD.Normalize<unknown>, "glossy"> | PD.NamedParams<PD.Normalize<unknown>, "plastic">;
        clip: PD.Normalize<{
            variant: any;
            objects: any;
        }>;
    }>>;
    trackball: PD.Group<PD.Normalize<{
        noScroll: boolean;
        rotateSpeed: number;
        zoomSpeed: number;
        panSpeed: number;
        spin: boolean;
        spinSpeed: number;
        staticMoving: boolean;
        dynamicDampingFactor: number;
        minDistance: number;
        maxDistance: number;
        gestureScaleFactor: number;
        maxWheelDelta: number;
        bindings: {
            dragRotate: import("../mol-util/binding").Binding;
            dragRotateZ: import("../mol-util/binding").Binding;
            dragPan: import("../mol-util/binding").Binding;
            dragZoom: import("../mol-util/binding").Binding;
            dragFocus: import("../mol-util/binding").Binding;
            dragFocusZoom: import("../mol-util/binding").Binding;
            scrollZoom: import("../mol-util/binding").Binding;
            scrollFocus: import("../mol-util/binding").Binding;
            scrollFocusZoom: import("../mol-util/binding").Binding;
        };
        autoAdjustMinMaxDistance: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            minDistanceFactor: any;
            minDistancePadding: any;
            maxDistanceFactor: any;
            maxDistanceMin: any;
        }>, "on">;
    }>>;
    interaction: PD.Group<PD.Normalize<{
        maxFps: number;
        preferAtomPixelPadding: number;
    }>>;
    debug: PD.Group<PD.Normalize<{
        sceneBoundingSpheres: boolean;
        visibleSceneBoundingSpheres: boolean;
        objectBoundingSpheres: boolean;
        instanceBoundingSpheres: boolean;
    }>>;
    handle: PD.Group<PD.Normalize<{
        handle: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            alpha: any;
            ignoreLight: any;
            colorX: any;
            colorY: any;
            colorZ: any;
            scale: any;
            doubleSided: any;
            flipSided: any;
            flatShaded: any;
            xrayShaded: any;
            quality: any;
        }>, "on">;
    }>>;
};
export declare const DefaultCanvas3DParams: PD.Values<{
    camera: PD.Group<PD.Normalize<{
        mode: "perspective" | "orthographic";
        helper: PD.Normalize<{
            axes: any;
        }>;
        stereo: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            eyeSeparation: any;
            focus: any;
        }>, "on">;
        manualReset: boolean;
    }>>;
    cameraFog: PD.Mapped<PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
        intensity: number;
    }>, "on">>;
    cameraClipping: PD.Group<PD.Normalize<{
        radius: number;
        far: boolean;
    }>>;
    viewport: PD.Mapped<PD.NamedParams<PD.Normalize<unknown>, "canvas"> | PD.NamedParams<PD.Normalize<{
        x: number;
        y: number;
        width: number;
        height: number;
    }>, "static-frame"> | PD.NamedParams<PD.Normalize<{
        x: number;
        y: number;
        width: number;
        height: number;
    }>, "relative-frame">>;
    cameraResetDurationMs: PD.Numeric;
    transparentBackground: PD.BooleanParam;
    multiSample: PD.Group<PD.Normalize<{
        mode: string;
        sampleLevel: number;
    }>>;
    postprocessing: PD.Group<PD.Normalize<{
        occlusion: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            samples: any;
            radius: any;
            bias: any;
            blurKernelSize: any;
        }>, "on">;
        outline: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            scale: any;
            threshold: any;
        }>, "on">;
        antialiasing: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            edgeThreshold: any;
            maxSearchSteps: any;
        }>, "smaa"> | PD.NamedParams<PD.Normalize<{
            edgeThresholdMin: any;
            edgeThresholdMax: any;
            iterations: any;
            subpixelQuality: any;
        }>, "fxaa">;
    }>>;
    marking: PD.Group<PD.Normalize<{
        enabled: boolean;
        highlightEdgeColor: import("../mol-util/color").Color;
        selectEdgeColor: import("../mol-util/color").Color;
        edgeScale: number;
        ghostEdgeStrength: number;
        innerEdgeFactor: number;
    }>>;
    renderer: PD.Group<PD.Normalize<{
        backgroundColor: import("../mol-util/color").Color;
        pickingAlphaThreshold: number;
        interiorDarkening: number;
        interiorColorFlag: boolean;
        interiorColor: import("../mol-util/color").Color;
        highlightColor: import("../mol-util/color").Color;
        selectColor: import("../mol-util/color").Color;
        highlightStrength: number;
        selectStrength: number;
        markerPriority: number;
        xrayEdgeFalloff: number;
        style: PD.NamedParams<PD.Normalize<unknown>, "flat"> | PD.NamedParams<PD.Normalize<unknown>, "metallic"> | PD.NamedParams<PD.Normalize<{
            lightIntensity: any;
            ambientIntensity: any;
            metalness: any;
            roughness: any;
            reflectivity: any;
        }>, "custom"> | PD.NamedParams<PD.Normalize<unknown>, "matte"> | PD.NamedParams<PD.Normalize<unknown>, "glossy"> | PD.NamedParams<PD.Normalize<unknown>, "plastic">;
        clip: PD.Normalize<{
            variant: any;
            objects: any;
        }>;
    }>>;
    trackball: PD.Group<PD.Normalize<{
        noScroll: boolean;
        rotateSpeed: number;
        zoomSpeed: number;
        panSpeed: number;
        spin: boolean;
        spinSpeed: number;
        staticMoving: boolean;
        dynamicDampingFactor: number;
        minDistance: number;
        maxDistance: number;
        gestureScaleFactor: number;
        maxWheelDelta: number;
        bindings: {
            dragRotate: import("../mol-util/binding").Binding;
            dragRotateZ: import("../mol-util/binding").Binding;
            dragPan: import("../mol-util/binding").Binding;
            dragZoom: import("../mol-util/binding").Binding;
            dragFocus: import("../mol-util/binding").Binding;
            dragFocusZoom: import("../mol-util/binding").Binding;
            scrollZoom: import("../mol-util/binding").Binding;
            scrollFocus: import("../mol-util/binding").Binding;
            scrollFocusZoom: import("../mol-util/binding").Binding;
        };
        autoAdjustMinMaxDistance: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            minDistanceFactor: any;
            minDistancePadding: any;
            maxDistanceFactor: any;
            maxDistanceMin: any;
        }>, "on">;
    }>>;
    interaction: PD.Group<PD.Normalize<{
        maxFps: number;
        preferAtomPixelPadding: number;
    }>>;
    debug: PD.Group<PD.Normalize<{
        sceneBoundingSpheres: boolean;
        visibleSceneBoundingSpheres: boolean;
        objectBoundingSpheres: boolean;
        instanceBoundingSpheres: boolean;
    }>>;
    handle: PD.Group<PD.Normalize<{
        handle: PD.NamedParams<PD.Normalize<unknown>, "off"> | PD.NamedParams<PD.Normalize<{
            alpha: any;
            ignoreLight: any;
            colorX: any;
            colorY: any;
            colorZ: any;
            scale: any;
            doubleSided: any;
            flipSided: any;
            flatShaded: any;
            xrayShaded: any;
            quality: any;
        }>, "on">;
    }>>;
}>;
export declare type Canvas3DProps = PD.Values<typeof Canvas3DParams>;
export declare type PartialCanvas3DProps = {
    [K in keyof Canvas3DProps]?: Canvas3DProps[K] extends {
        name: string;
        params: any;
    } ? Canvas3DProps[K] : Partial<Canvas3DProps[K]>;
};
export { Canvas3DContext };
/** Can be used to create multiple Canvas3D objects */
interface Canvas3DContext {
    readonly canvas: HTMLCanvasElement;
    readonly webgl: WebGLContext;
    readonly input: InputObserver;
    readonly passes: Passes;
    readonly attribs: Readonly<Canvas3DContext.Attribs>;
    readonly contextLost: BehaviorSubject<now.Timestamp>;
    readonly contextRestored: BehaviorSubject<now.Timestamp>;
    dispose: (options?: Partial<{
        doNotForceWebGLContextLoss: boolean;
    }>) => void;
}
declare namespace Canvas3DContext {
    const DefaultAttribs: {
        /** true by default to avoid issues with Safari (Jan 2021) */
        antialias: boolean;
        /** true to support multiple Canvas3D objects with a single context */
        preserveDrawingBuffer: boolean;
        pixelScale: number;
        pickScale: number;
        /** extra pixels to around target to check in case target is empty */
        pickPadding: number;
        enableWboit: boolean;
        preferWebGl1: boolean;
    };
    type Attribs = typeof DefaultAttribs;
    function fromCanvas(canvas: HTMLCanvasElement, attribs?: Partial<Attribs>): Canvas3DContext;
}
export { Canvas3D };
interface Canvas3D {
    readonly webgl: WebGLContext;
    add(repr: Representation.Any): void;
    remove(repr: Representation.Any): void;
    /**
     * This function must be called if animate() is not set up so that add/remove actions take place.
     */
    commit(isSynchronous?: boolean): void;
    /**
     * Function for external "animation" control
     * Calls commit.
     */
    tick(t: now.Timestamp, options?: {
        isSynchronous?: boolean;
        manualDraw?: boolean;
    }): void;
    update(repr?: Representation.Any, keepBoundingSphere?: boolean): void;
    clear(): void;
    syncVisibility(): void;
    requestDraw(force?: boolean): void;
    /** Reset the timers, used by "animate" */
    resetTime(t: number): void;
    animate(): void;
    /**
     * Pause animation loop and optionally any rendering
     * @param noDraw pause any rendering (drawPaused = true)
     */
    pause(noDraw?: boolean): void;
    /** Sets drawPaused = false without starting the built in animation loop */
    resume(): void;
    identify(x: number, y: number): PickData | undefined;
    mark(loci: Representation.Loci, action: MarkerAction, noDraw?: boolean): void;
    getLoci(pickingId: PickingId | undefined): Representation.Loci;
    notifyDidDraw: boolean;
    readonly didDraw: BehaviorSubject<now.Timestamp>;
    readonly commited: BehaviorSubject<now.Timestamp>;
    readonly reprCount: BehaviorSubject<number>;
    readonly resized: BehaviorSubject<any>;
    handleResize(): void;
    /** performs handleResize on the next animation frame */
    requestResize(): void;
    /** Focuses camera on scene's bounding sphere, centered and zoomed. */
    requestCameraReset(options?: {
        durationMs?: number;
        snapshot?: Camera.SnapshotProvider;
    }): void;
    readonly camera: Camera;
    readonly boundingSphere: Readonly<Sphere3D>;
    readonly boundingSphereVisible: Readonly<Sphere3D>;
    setProps(props: PartialCanvas3DProps | ((old: Canvas3DProps) => Partial<Canvas3DProps> | void), doNotRequestDraw?: boolean): void;
    getImagePass(props: Partial<ImageProps>): ImagePass;
    getRenderObjects(): GraphicsRenderObject[];
    /** Returns a copy of the current Canvas3D instance props */
    readonly props: Readonly<Canvas3DProps>;
    readonly input: InputObserver;
    readonly stats: RendererStats;
    readonly interaction: Canvas3dInteractionHelper['events'];
    dispose(): void;
}
declare namespace Canvas3D {
    interface HoverEvent {
        current: Representation.Loci;
        buttons: ButtonsType;
        button: ButtonsType.Flag;
        modifiers: ModifiersKeys;
        page?: Vec2;
        position?: Vec3;
    }
    interface DragEvent {
        current: Representation.Loci;
        buttons: ButtonsType;
        button: ButtonsType.Flag;
        modifiers: ModifiersKeys;
        pageStart: Vec2;
        pageEnd: Vec2;
    }
    interface ClickEvent {
        current: Representation.Loci;
        buttons: ButtonsType;
        button: ButtonsType.Flag;
        modifiers: ModifiersKeys;
        page?: Vec2;
        position?: Vec3;
    }
    function create({ webgl, input, passes, attribs }: Canvas3DContext, props?: Partial<Canvas3DProps>): Canvas3D;
}
