import '../../../assert/js/assert.js';
import '../../../globals.js';
/**
 * Isolates Image handling with HTML/Canvas images, with mipmaps and general support.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import TEmitter from '../../../axon/js/TEmitter.js';
import TProperty from '../../../axon/js/TProperty.js';
import TReadOnlyProperty from '../../../axon/js/TReadOnlyProperty.js';
import Matrix3 from '../../../dot/js/Matrix3.js';
import Vector2 from '../../../dot/js/Vector2.js';
import { Shape } from '../../../kite/js/imports.js';
import Constructor from '../../../phet-core/js/types/Constructor.js';
export type Mipmap = {
    width: number;
    height: number;
    url: string;
    canvas?: HTMLCanvasElement;
    img?: HTMLImageElement;
    updateCanvas?: () => void;
}[];
/**
 * The available ways to specify an image as an input to Imageable. See onImagePropertyChange() for parsing logic.
 * We support a few different 'image' types that can be passed in:
 *
 * HTMLImageElement - A normal HTML <img>. If it hasn't been fully loaded yet, Scenery will take care of adding a
 *   listener that will update Scenery with its width/height (and load its data) when the image is fully loaded.
 *   NOTE that if you just created the <img>, it probably isn't loaded yet, particularly in Safari. If the Image
 *   node is constructed with an <img> that hasn't fully loaded, it will have a width and height of 0, which may
 *   cause issues if you are using bounds for layout. Please see initialWidth/initialHeight notes below.
 *
 * URL - Provide a {string}, and Scenery will assume it is a URL. This can be a normal URL, or a data URI, both will
 *   work. Please note that this has the same loading-order issues as using HTMLImageElement, but that it's almost
 *   always guaranteed to not have a width/height when you create the Image node. Note that data URI support for
 *   formats depends on the browser - only JPEG and PNG are supported broadly. Please see initialWidth/initialHeight
 *   notes below.
 *   Additionally, note that if a URL is provided, accessing image.getImage() or image.image will result not in the
 *   original URL (currently), but with the automatically created HTMLImageElement.
 *
 * HTMLCanvasElement - It's possible to pass an HTML5 Canvas directly into the Image node. It will immediately be
 *   aware of the width/height (bounds) of the Canvas, but NOTE that the Image node will not listen to Canvas size
 *   changes. It is assumed that after you pass in a Canvas to an Image node that it will not be modified further.
 *   Additionally, the Image node will only be rendered using Canvas or WebGL if a Canvas is used as input.
 *
 * Mipmap data structure - Image supports a mipmap data structure that provides rasterized mipmap levels. The 'top'
 *   level (level 0) is the entire full-size image, and every other level is twice as small in every direction
 *   (~1/4 the pixels), rounding dimensions up. This is useful for browsers that display the image badly if the
 *   image is too large. Instead, Scenery will dynamically pick the most appropriate size of the image to use,
 *   which improves the image appearance.
 *   The passed in 'image' should be an Array of mipmap objects of the format:
 *   {
 *     img: {HTMLImageElement}, // preferably preloaded, but it isn't required
 *     url: {string}, // URL (usually a data URL) for the image level
 *     width: {number}, // width of the mipmap level, in pixels
 *     height: {number} // height of the mipmap level, in pixels,
 *     canvas: {HTMLCanvasElement} // Canvas element containing the image data for the img.
 *     [updateCanvas]: {function} // If available, should be called before using the Canvas directly.
 *   }
 *   At least one level is required (level 0), and each mipmap level corresponds to the index in the array, e.g.:
 *   [
 *     level 0 (full size, e.g. 100x64)
 *     level 1 (half size, e.g. 50x32)
 *     level 2 (quarter size, e.g. 25x16)
 *     level 3 (eighth size, e.g. 13x8 - note the rounding up)
 *     ...
 *     level N (single pixel, e.g. 1x1 - this is the smallest level permitted, and there should only be one)
 *   ]
 *   Additionally, note that (currently) image.getImage() will return the HTMLImageElement from the first level,
 *   not the mipmap data.
 *
 *  Also note that if the underlying image (like Canvas data) has changed, it is recommended to call
 *  invalidateImage() instead of changing the image reference (calling setImage() multiple times)
 */
export type ImageableImage = string | HTMLImageElement | HTMLCanvasElement | Mipmap;
type ParsedImage = HTMLImageElement | HTMLCanvasElement;
export type ImageableOptions = {
    image?: ImageableImage;
    imageProperty?: TReadOnlyProperty<ImageableImage>;
    imageOpacity?: number;
    initialWidth?: number;
    initialHeight?: number;
    mipmap?: boolean;
    mipmapBias?: number;
    mipmapInitialLevel?: number;
    mipmapMaxLevel?: number;
    hitTestPixels?: boolean;
};
export interface TImageable {
    _image: ParsedImage | null;
    _imageOpacity: number;
    _mipmap: boolean;
    _mipmapBias: number;
    _mipmapInitialLevel: number;
    _mipmapMaxLevel: number;
    _hitTestPixels: boolean;
    _mipmapData: Mipmap | null;
    _hitTestImageData: ImageData | null;
    mipmapEmitter: TEmitter;
    isDisposed?: boolean;
    setImage(image: ImageableImage): this;
    set image(value: ImageableImage);
    get image(): ParsedImage;
    getImage(): ParsedImage;
    setImageProperty(newTarget: TReadOnlyProperty<ImageableImage> | null): null;
    set imageProperty(property: TReadOnlyProperty<ImageableImage> | null);
    get imageProperty(): TProperty<ImageableImage>;
    getImageProperty(): TProperty<ImageableImage>;
    invalidateImage(): void;
    setImageWithSize(image: ImageableImage, width: number, height: number): this;
    setImageOpacity(imageOpacity: number): void;
    set imageOpacity(value: number);
    get imageOpacity(): number;
    getImageOpacity(): number;
    setInitialWidth(width: number): this;
    set initialWidth(value: number);
    get initialWidth(): number;
    getInitialWidth(): number;
    setInitialHeight(height: number): this;
    set initialHeight(value: number);
    get initialHeight(): number;
    getInitialHeight(): number;
    setMipmap(mipmap: boolean): this;
    set mipmap(value: boolean);
    get mipmap(): boolean;
    isMipmap(): boolean;
    setMipmapBias(bias: number): this;
    set mipmapBias(value: number);
    get mipmapBias(): number;
    getMipmapBias(): number;
    setMipmapInitialLevel(level: number): this;
    set mipmapInitialLevel(value: number);
    get mipmapInitialLevel(): number;
    getMipmapInitialLevel(): number;
    setMipmapMaxLevel(level: number): this;
    set mipmapMaxLevel(value: number);
    get mipmapMaxLevel(): number;
    getMipmapMaxLevel(): number;
    setHitTestPixels(hitTestPixels: boolean): this;
    set hitTestPixels(value: boolean);
    get hitTestPixels(): boolean;
    getHitTestPixels(): boolean;
    invalidateMipmaps(): void;
    getMipmapLevel(matrix: Matrix3, additionalBias?: number): number;
    getMipmapLevelFromScale(scale: number, additionalBias?: number): number;
    getMipmapCanvas(level: number): HTMLCanvasElement;
    getMipmapURL(level: number): string;
    hasMipmaps(): boolean;
    getImageWidth(): number;
    get imageWidth(): number;
    getImageHeight(): number;
    get imageHeight(): number;
    getImageURL(): string;
}
declare const Imageable: {
    <SuperType extends Constructor>(type: SuperType): SuperType & Constructor<TImageable>;
    getHitTestData(image: ParsedImage, width: number, height: number): ImageData | null;
    testHitTestData(imageData: ImageData, width: number, height: number, point: Vector2): boolean;
    hitTestDataToShape(imageData: ImageData, width: number, height: number): Shape;
    createSVGImage(url: string, width: number, height: number): SVGImageElement;
    createFastMipmapFromCanvas(baseCanvas: HTMLCanvasElement): Mipmap;
    getApproximateMatrixScale(matrix: Matrix3): number;
    CANVAS_MIPMAP_BIAS_ADJUSTMENT: number;
    DEFAULT_OPTIONS: {
        readonly imageOpacity: 1;
        readonly initialWidth: 0;
        readonly initialHeight: 0;
        readonly mipmap: false;
        readonly mipmapBias: 0;
        readonly mipmapInitialLevel: 4;
        readonly mipmapMaxLevel: 5;
        readonly hitTestPixels: false;
    };
};
export default Imageable;
//# sourceMappingURL=Imageable.d.ts.map