import type { Loadable, LoadableMixinProperties } from "../../core/Loadable.js";
import type { MultiOriginJSONSupportMixin } from "../../core/MultiOriginJSONSupport.js";
import type { Georeference } from "../media/types.js";
import type { ControlPointsGeoreferenceProperties } from "./ControlPointsGeoreference.js";
import type { ExtentAndRotationGeoreferenceProperties } from "./ExtentAndRotationGeoreference.js";
import type { CornersGeoreferenceProperties } from "./CornersGeoreference.js";

export interface MediaElementBaseProperties extends LoadableMixinProperties, Partial<Pick<MediaElementBase, "opacity">> {
  /**
   * The geographic location of the image or video element to be placed on the map. The location can be set by either specifying
   * extent and rotation of the element, the corner points of the bounding box, or by defining control points.
   *
   * @example
   * // create a new ExtentAndRotationGeoreference
   * const geoReference = new ExtentAndRotationGeoreference({
   *   extent: new Extent({
   *     spatialReference: {
   *       wkid: 102100
   *     },
   *     xmin: -10047456.27662979,
   *     ymin: 3486722.2723874687,
   *     xmax: -10006982.870152846,
   *     ymax: 3514468.91365495
   *   })
   * });
   * const imageElement = new ImageElement({
   *   image: "https://arcgis.github.io/arcgis-samples-javascript/sample-data/media-layer/new-orleans/neworleans1891.png",
   *   georeference: geoReference
   * });
   * @example
   * // create a canvas image element by setting its corner points of the bounding box
   * const canvasElement = new ImageElement({
   *   image: canvas,
   *   georeference: new CornersGeoreference({
   *     bottomRight: new Point({
   *       x: -121.369,
   *       y: 45.061
   *     }),
   *     bottomLeft: new Point({
   *       x: -122.363,
   *       y: 45.061
   *     }),
   *     topRight: new Point({
   *       x: -121.369,
   *       y: 45.678
   *     }),
   *     topLeft: new Point({
   *       x: -122.363,
   *       y: 45.678
   *     })
   *   })
   * });
   * @example
   * // georeference an ImageElement, using ControlPointsGeoreference in the
   * // North American Datum 1927 spatial reference
   * const spatialReference = new SpatialReference({ wkid: 4267 });
   * const swCorner = {
   *     sourcePoint: { x: 80, y: 1732 },
   *     mapPoint: new Point({ x: -107.875, y: 37.875, spatialReference })
   * };
   *
   * const nwCorner = {
   *     sourcePoint: { x: 75, y: 102 },
   *     mapPoint: new Point({ x: -107.875, y: 38, spatialReference })
   * };
   *
   * const neCorner = {
   *    sourcePoint: { x: 1353, y: 99 },
   *    mapPoint: new Point({ x: -107.75, y: 38, spatialReference })
   * };
   *
   * const seCorner = {
   *    sourcePoint: { x: 1361, y: 1721 },
   *    mapPoint: new Point({ x: -107.75, y: 37.875, spatialReference })
   * };
   *
   * const controlPoints = [swCorner, nwCorner, neCorner, seCorner];
   *
   * const georeference = new ControlPointsGeoreference({ controlPoints, width: 1991, height: 2500 });
   *
   * const imageElement = new ImageElement({
   *     image: "https://jsapi.maps.arcgis.com/sharing/rest/content/items/1a3df04e7d734535a3a6a09dfec5a6b2/data",
   *     georeference
   * });
   */
  georeference?: ((CornersGeoreferenceProperties & { type: "corners" }) | (ExtentAndRotationGeoreferenceProperties & { type: "extent-and-rotation" }) | (ControlPointsGeoreferenceProperties & { type: "control-points" })) | null;
}

/**
 * Mixin for ImageElement and VideoElement.
 *
 * @since 4.24
 */
export default abstract class MediaElementBase extends MediaElementBaseSuperclass {
  /**
   * The geographic location of the image or video element to be placed on the map. The location can be set by either specifying
   * extent and rotation of the element, the corner points of the bounding box, or by defining control points.
   *
   * @example
   * // create a new ExtentAndRotationGeoreference
   * const geoReference = new ExtentAndRotationGeoreference({
   *   extent: new Extent({
   *     spatialReference: {
   *       wkid: 102100
   *     },
   *     xmin: -10047456.27662979,
   *     ymin: 3486722.2723874687,
   *     xmax: -10006982.870152846,
   *     ymax: 3514468.91365495
   *   })
   * });
   * const imageElement = new ImageElement({
   *   image: "https://arcgis.github.io/arcgis-samples-javascript/sample-data/media-layer/new-orleans/neworleans1891.png",
   *   georeference: geoReference
   * });
   * @example
   * // create a canvas image element by setting its corner points of the bounding box
   * const canvasElement = new ImageElement({
   *   image: canvas,
   *   georeference: new CornersGeoreference({
   *     bottomRight: new Point({
   *       x: -121.369,
   *       y: 45.061
   *     }),
   *     bottomLeft: new Point({
   *       x: -122.363,
   *       y: 45.061
   *     }),
   *     topRight: new Point({
   *       x: -121.369,
   *       y: 45.678
   *     }),
   *     topLeft: new Point({
   *       x: -122.363,
   *       y: 45.678
   *     })
   *   })
   * });
   * @example
   * // georeference an ImageElement, using ControlPointsGeoreference in the
   * // North American Datum 1927 spatial reference
   * const spatialReference = new SpatialReference({ wkid: 4267 });
   * const swCorner = {
   *     sourcePoint: { x: 80, y: 1732 },
   *     mapPoint: new Point({ x: -107.875, y: 37.875, spatialReference })
   * };
   *
   * const nwCorner = {
   *     sourcePoint: { x: 75, y: 102 },
   *     mapPoint: new Point({ x: -107.875, y: 38, spatialReference })
   * };
   *
   * const neCorner = {
   *    sourcePoint: { x: 1353, y: 99 },
   *    mapPoint: new Point({ x: -107.75, y: 38, spatialReference })
   * };
   *
   * const seCorner = {
   *    sourcePoint: { x: 1361, y: 1721 },
   *    mapPoint: new Point({ x: -107.75, y: 37.875, spatialReference })
   * };
   *
   * const controlPoints = [swCorner, nwCorner, neCorner, seCorner];
   *
   * const georeference = new ControlPointsGeoreference({ controlPoints, width: 1991, height: 2500 });
   *
   * const imageElement = new ImageElement({
   *     image: "https://jsapi.maps.arcgis.com/sharing/rest/content/items/1a3df04e7d734535a3a6a09dfec5a6b2/data",
   *     georeference
   * });
   */
  get georeference(): Georeference | null | undefined;
  set georeference(value: ((CornersGeoreferenceProperties & { type: "corners" }) | (ExtentAndRotationGeoreferenceProperties & { type: "extent-and-rotation" }) | (ControlPointsGeoreferenceProperties & { type: "control-points" })) | null | undefined);
  /**
   * The opacity of the element. This value can range between 1 and 0, where 0 is 100 percent transparent and 1 is completely opaque.
   *
   * @default 1
   */
  accessor opacity: number;
}
declare const MediaElementBaseSuperclass: typeof Loadable & typeof MultiOriginJSONSupportMixin