import type { BBox } from 'gis-tools/index.js';
import type { ColorArray } from 'style/color/index.js';
import type { GlyphImages } from 'workers/source/glyphSource.js';
import type { MapOptions } from 'ui/s2mapUI.js';
import type { Painter } from '../painter.spec.js';
import type { SpriteImageMessage } from 'workers/worker.spec.js';
import type { TileGL as Tile } from 'source/tile.spec.js';
import type { GPUType, Projection } from 'style/style.spec.js';
import type { MaskSource, TileMaskSource, Workflow } from '../workflows/workflow.spec.js';
/** Frame buffer object like wrapper */
export interface FBO {
    width: number;
    height: number;
    texSize: number[];
    texture: WebGLTexture;
    stencil: WebGLRenderbuffer;
    glyphFramebuffer: WebGLFramebuffer;
}
/** Context presentation */
export interface ContextPresentation {
    width: number;
    height: number;
}
/**
 * # Context
 *
 * ## Description
 * A WebGL(1|2) context with GPU information.
 * A useful wrapper to store state and reduce costly GPU calls when unnecessary
 */
export default class Context {
    #private;
    gl: WebGLRenderingContext | WebGL2RenderingContext;
    painter: Painter;
    type: GPUType;
    projection: Projection;
    presentation: ContextPresentation;
    renderer: string;
    devicePixelRatio: number;
    interactive: boolean;
    depthState: boolean;
    cullState: boolean;
    stencilState: boolean;
    blendState: boolean;
    stencilRef: number;
    blendMode: number;
    zTestMode: number;
    zLow: number;
    zHigh: number;
    currWorkflow: undefined | Workflow;
    clearColorRGBA: ColorArray;
    featurePoint: Uint8Array;
    masks: Map<number, MaskSource>;
    vao: WebGLVertexArrayObject;
    vertexBuffer: WebGLBuffer;
    interactTexture: WebGLTexture;
    stencilBuffer: WebGLRenderbuffer;
    interactFramebuffer: WebGLFramebuffer;
    defaultBounds: BBox;
    nullTexture: WebGLTexture;
    sharedFBO: FBO;
    /**
     * @param context - The WebGL1 or WebGL2 context to read from
     * @param options - Map options
     * @param painter - The painter that will use this context to manage rendering state
     */
    constructor(context: WebGLRenderingContext | WebGL2RenderingContext, options: MapOptions, painter: Painter);
    /**
     * Inject a glyph/icon image to the GPU
     * @param maxHeight - the maximum height of the texture required to hold the image
     * @param images - the glyph/icon images
     */
    injectImages(maxHeight: number, images: GlyphImages): void;
    /**
     * Inject a sprite image to the GPU
     * @param data - the raw image data of the sprite
     */
    injectSpriteImage(data: SpriteImageMessage): void;
    /** Resize the size of the canvas and all associating buffers */
    resize(): void;
    /**
     * Set the interactive mode
     * @param interactive - the interactive mode (true means it is interactive)
     */
    setInteractive(interactive: boolean): void;
    /**
     * Set the projection type (S2 or WM)
     * @param projection - the projection
     */
    setProjection(projection: Projection): void;
    /** Resize the interactive buffer */
    resizeInteract(): void;
    /**
     * Get the collection of features found at the mouse position
     * @param x - x mouse position
     * @param y - y mouse position
     * @returns the collection of features found
     */
    getFeatureAtMousePosition(x: number, y: number): Promise<number[]>;
    /** Delete/cleanup the context */
    delete(): void;
    /** CONSTRUCTION */
    /** Create a default quad for cases where a quad is needed (avoid allocation for every quad) */
    _createDefaultQuad(): void;
    /**
     * Get the mask for a tile
     * the zoom determines the number of divisions necessary to maintain a visually
     * asthetic spherical shape. As we zoom in, the tiles are practically flat,
     * so division is less useful.
     * 0, 1 => 16  ;  2, 3 => 8  ;  4, 5 => 4  ;  6, 7 => 2  ;  8+ => 1
     * context stores masks so we don't keep recreating them and put excess stress and memory on the GPU
     * @param division - number of division to slice the geometry by
     * @param tile - the tile to create the mask for
     * @returns the mask
     */
    getMask(division: number, tile: Tile): TileMaskSource;
    /** Draw a quad */
    drawQuad(): void;
    /** Reset the viewport */
    resetViewport(): void;
    /** Bind to the main buffer */
    bindMainBuffer(): void;
    /**
     * Set a clear color for the initialization draws (like the background color)
     * @param clearColor - the clear color
     */
    setClearColor(clearColor: ColorArray): void;
    /** Setup a new scene for future draw calls */
    newScene(): void;
    /** Reset the current workflow */
    resetWorkflow(): void;
    /**
     * Set the current workflow
     * @param workflow - the workflow to set as the current
     * @param use - flag to say we want to also activate the workflow
     */
    setWorkflow(workflow: Workflow, use?: boolean): void;
    /** Clear the interact buffer */
    clearInteractBuffer(): void;
    /** Clear the canvas using the current clear color */
    clearColor(): void;
    /** Clear both the color and depth buffers */
    clearColorDepthBuffers(): void;
    /** Clear the color buffer */
    clearColorBuffer(): void;
    /**
     * Build a new texture
     * @param imageData - the raw image data to inject to the texture
     * @param width - width of the texture
     * @param height - height of the texture
     * @param repeat - should the texture repeat
     * @returns the texture
     */
    buildTexture(imageData: null | ArrayBufferView | ImageBitmap, width: number, height?: number, repeat?: boolean): WebGLTexture;
    /**
     * Update an existing texture
     * @param texture - the texture to update
     * @param imageData - the new image data to inject
     * @param width - the new width
     * @param height - the new height
     */
    updateTexture(texture: WebGLTexture, imageData: null | ArrayBufferView | ImageBitmap, width: number, height: number): void;
    /** Enable depth testing */
    enableDepthTest(): void;
    /** Disable depth testing */
    disableDepthTest(): void;
    /** Always pass depth test */
    alwaysDepth(): void;
    /** Depth testing should pass if the depth is less than the reference value */
    lessDepth(): void;
    /** Depth testing should pass if the depth is less than or equal to the reference value */
    lequalDepth(): void;
    /**
     * Set the depth range
     * @param depthPos - the depth position
     */
    setDepthRange(depthPos: number): void;
    /** Reset the depth range to the full depth range */
    resetDepthRange(): void;
    /** Enable face culling */
    enableCullFace(): void;
    /** Disable face culling */
    disableCullFace(): void;
    /** Enable blending */
    enableBlend(): void;
    /** Disable blending */
    disableBlend(): void;
    /** Set the blending mode to a default state */
    defaultBlend(): void;
    /** Set the blending mode to blend mode */
    shadeBlend(): void;
    /** Set the blending mode to inversion mode */
    inversionBlend(): void;
    /** Set the blending mode to zero mode */
    zeroBlend(): void;
    /** Set the blending mode to one mode */
    oneBlend(): void;
    /** Enable stencil testing */
    enableStencilTest(): void;
    /** Disable stencil testing */
    disableStencilTest(): void;
    /**
     * Set the stencil function to always pass but you can still update the reference value
     * @param ref - the reference value
     */
    stencilFuncAlways(ref: number): void;
    /**
     * Set the stencil function to pass if the stencil value is equal to the reference value
     * @param ref - the reference value
     */
    stencilFuncEqual(ref: number): void;
    /** Set the stenci mode to default */
    stencilDefault(): void;
    /** Set the stencil mode to invert */
    stencilInvert(): void;
    /** Set the stencil mode to zero */
    stencilZero(): void;
    /** enable mask testing */
    enableMaskTest(): void;
    /** setup to "flush" a mask's coverage */
    flushMask(): void;
    /**
     * Build a vertex array object
     * @returns the vertex array object
     */
    buildVAO(): WebGLVertexArrayObject;
    /**
     * Bind a vertex attribute
     * @param ab - the array buffer
     * @param indx - the index
     * @param size - the size
     * @param type - the type
     * @param normalized - if true, normalize the input data
     * @param stride - the stride
     * @param offset - the offset
     * @param instance - if true, the VAO is used for instancing
     * @returns the buffer
     */
    bindEnableVertexAttr(ab: ArrayBufferView, indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number, instance?: boolean): WebGLBuffer;
    /**
     * Bind mulitiple vertex attribute
     * @param ab - the array buffer
     * @param attributes - the collection of attributes that use the same buffer
     * @param instance - if true, the resulting VAO is used for instancing
     * @returns the buffer
     */
    bindEnableVertexAttrMulti(ab: ArrayBufferView, attributes: Array<[
        index: number,
        size: number,
        type: number,
        normalized: boolean,
        stride: number,
        offset: number
    ]>, instance?: boolean): WebGLBuffer;
    /**
     * Bind and buffer an input array
     * @param ab - the array buffer
     * @returns the buffer
     */
    bindAndBuffer(ab: ArrayBufferView): WebGLBuffer;
    /**
     * Define the state of a vertex attribute
     * @param indx - the index
     * @param size - the size
     * @param type - the type
     * @param normalized - if true, normalize the input data
     * @param stride - the stride
     * @param offset - the offset
     * @param instance - if true, the VAO is used for instancing
     */
    defineBufferState(indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number, instance?: boolean): void;
    /**
     * Bind an element array
     * @param ab - the array buffer to bind
     * @returns the buffer
     */
    bindElementArray(ab: ArrayBufferView): WebGLBuffer;
    /** At the end of rendering a frame/scene, call this function to cleanup the state */
    finish(): void;
}
