import type MediaElementBase from "./MediaElementBase.js";
import type { AnimationOptions, ImageBinarySource, ImageSource } from "../media/types.js";
import type { MediaElementBaseProperties } from "./MediaElementBase.js";

export interface ImageElementProperties extends MediaElementBaseProperties, Partial<Pick<ImageElement, "animationOptions" | "image">> {}

/**
 * Represents an image element referenced in the MediaLayer's [MediaLayer.source](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/#source).
 * MediaLayer can display images that are supported by web browsers. Refer to the [common image file types](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types#common_image_file_types)
 * document for supported image types.
 *
 * Coordinates of the image and video elements can be specified in any spatial reference and are projected to the view's [spatial reference](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#spatialReference).
 * The content is stretched linearly between the coordinates, therefore it's recommended for the image or video to match the view's spatial reference to align correctly, especially for content
 * covering large areas like the entire earth.
 *
 * Note that the maximum size of the image depends on the machine's GPU. The safest maximum size is 2048 x 2048 pixels. The larger the image size, the longer it will take to be fetched and displayed.
 *
 * ```js
 * // add a new imageElement and use extent and rotation
 * // to place the element on the map.
 * const imageElement = new ImageElement({
 *   image: "https://arcgis.github.io/arcgis-samples-javascript/sample-data/media-layer/neworleans1891.png",
 *   georeference: new ExtentAndRotationGeoreference({
 *     extent: new Extent({
 *       spatialReference: {
 *         wkid: 102100
 *       },
 *       xmin: -10047456.27662979,
 *       ymin: 3486722.2723874687,
 *       xmax: -10006982.870152846,
 *       ymax: 3514468.91365495
 *     })
 *   })
 * });
 * ```
 *
 * @since 4.24
 * @see [MediaLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/)
 * @see [Sample - MediaLayer with images](https://developers.arcgis.com/javascript/latest/sample-code/layers-medialayer-images/)
 */
export default class ImageElement extends MediaElementBase {
  constructor(properties?: ImageElementProperties);
  /**
   * The animation options for the image element. This property is only valid when the [image](https://developers.arcgis.com/javascript/latest/references/core/layers/support/ImageElement/#image) is an animated GIF or APNG.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > animationOptions is not supported in 3D [SceneViews](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
   *
   * @since 4.28
   * @example
   * imageElement.animationOptions = {
   *   playing: true,
   *   duration: 10,
   *   repeatType: "loop",
   *   repeatDelay: 0
   * };
   */
  accessor animationOptions: AnimationOptions | null | undefined;
  /** The image content referenced in the image element instance. The content matches the image referenced in [image](https://developers.arcgis.com/javascript/latest/references/core/layers/support/ImageElement/#image) parameter. */
  get content(): ImageBinarySource | null | undefined;
  /**
   * The image element to be added to the [media layer's source](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/#source). The image
   * element can be URL string pointing the image for example.
   *
   * @example
   * // create an image element pointing url of the image file
   * const stHelen = new ImageElement({
   *   image: "https://ubatsukh.github.io/arcgis-js-api-demos/data/nasa/mount_st_helens.jpeg",
   *   georeference: new CornersGeoreference({
   *     extent: new Extent({
   *       spatialReference: {
   *         wkid: 102100
   *       },
   *       xmax: -13544247.66023844,
   *       xmin: -13659744.009977184,
   *       ymax: 5858405.227033072,
   *       ymin: 5767445.163373847
   *     })
   *   })
   * });
   * @example
   * // create an image element pointing to image data
   * const arr = new Uint8ClampedArray(40000);
   *
   * // Iterate through every pixel
   * for (let i = 0; i < arr.length; i += 4) {
   *   arr[i] = 0;    // R value
   *   arr[i + 1] = 190;  // G value
   *   arr[i + 2] = 0;    // B value
   *   arr[i + 3] = 255;  // A value
   * }
   *
   * // Initialize a new ImageData object
   * let imageData = new ImageData(arr, 200);
   *
   * // create a new image element pointing to the
   * // image data and set location of the image on the map
   * const imageDataElement = new ImageElement({
   *   image: imageData,
   *   georeference: extent
   * });
   * @example
   * // create a canvas
   * const canvas = document.createElement("canvas");
   * const ctx = canvas.getContext("2d");
   * canvas.width = 200;
   * canvas.height = 200;
   * ctx.fillStyle = "blue";
   * ctx.fillRect(0, 0, 200, 200);
   *
   * // add the canvas as an image element
   * const canvasElement = new ImageElement({
   *   image: canvas,
   *   georeference: extent
   * });
   */
  accessor image: ImageSource | null | undefined;
  /** The element type. */
  get type(): "image";
}