import type Color from "../../Color.js";
import type MeshTexture from "./MeshTexture.js";
import type MeshTextureTransform from "./MeshTextureTransform.js";
import type { ClonableMixin } from "../../core/Clonable.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { MeshTextureData } from "../types.js";
import type { ColorLike } from "../../Color.js";
import type { MeshTextureProperties } from "./MeshTexture.js";
import type { MeshTextureTransformProperties } from "./MeshTextureTransform.js";

export interface MeshMaterialProperties extends Partial<Pick<MeshMaterial, "alphaCutoff" | "alphaMode" | "doubleSided">> {
  /**
   * Specifies a single, uniform color for the mesh component. This can be autocast with
   * a named string, hex string, array of rgb or rgba values, an object with `r`, `g`, `b`, and `a`
   * properties, or a [Color](https://developers.arcgis.com/javascript/latest/api-reference/esri-Color.html) object.
   */
  color?: ColorLike | null;
  /**
   * Specifies a texture from which to get color information.
   * The texture is accessed using the UV coordinates specified for each vertex
   * in the [Mesh.vertexAttributes](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html#vertexAttributes).
   */
  colorTexture?: MeshTextureProperties | string | MeshTextureData | null;
  /**
   * A transformation of UV mesh coordinates used to sample the color texture. Texture transformations
   * can be used to optimize re-use of textures, for example by packing many images into a single
   * texture "atlas" and using the texture transform offset and scale to sample a specific region
   * within this larger texture.
   *
   * @since 4.27
   */
  colorTextureTransform?: MeshTextureTransformProperties | null;
  /**
   * Specifies a texture from which to get normal information.
   * The texture is accessed using the UV coordinates specified for each vertex
   * in the [Mesh.vertexAttributes](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html#vertexAttributes).
   */
  normalTexture?: MeshTextureProperties | string | MeshTextureData | null;
  /**
   * A transformation of UV mesh coordinates used to sample the normal texture. Texture transformations
   * can be used to optimize re-use of textures, for example by packing many images into a single
   * texture "atlas" and using the texture transform offset and scale to sample a specific region
   * within this larger texture.
   *
   * @since 4.27
   */
  normalTextureTransform?: MeshTextureTransformProperties | null;
}

/**
 * The material determines how a [MeshComponent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshComponent.html) is visualized.
 * One of the major characteristics of a material is its [color](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#color). The [color](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#color) property
 * can be used to set a uniform color for the whole [MeshComponent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshComponent.html).
 * Use the [colorTexture](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#colorTexture) property to map an image onto the mesh component, using the UV
 * coordinate specified for each vertex in the [Mesh.vertexAttributes](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html#vertexAttributes).
 *
 * The material properties support a number of convenience autocast types, including
 * hex color strings and well-known color strings (autocasts to
 * [Color](https://developers.arcgis.com/javascript/latest/api-reference/esri-Color.html)), or strings representing URLs to images,
 * [HTMLImageElements](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement),
 * [HTMLCanvasElements](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement),
 * [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement),
 * or [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData)
 * (autocasts to [MeshTexture](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshTexture.html)).
 *
 * ```js
 *
 * // create a material that uses a color
 *
 * const meshWithColor = new MeshComponent({
 *   // autocasts to MeshMaterial
 *   material: {
 *     color: "#ff00ff"
 *   }
 * });
 *
 * // create a material that uses a texture by linking to
 * // an image url
 *
 * const meshTextureByUrl = new MeshTexture({
 *   url: "./image.png"
 * });
 *
 * const boxMesh = Mesh.createBox(location, {
 *   material: {
 *     colorTexture: meshTextureByUrl
 *   }
 * });
 *
 * // create a material that uses a texture from
 * // a canvas element
 *
 * function createLinearGradient() {
 *   const canvas = document.createElement("canvas");
 *   canvas.width = 32;
 *   canvas.height = 32;
 *
 *   const ctx = canvas.getContext("2d");
 *
 *   // Create the linear gradient with which to fill the canvas
 *   const gradient = ctx.createLinearGradient(0, 0, 0, 32);
 *   gradient.addColorStop(0, "#00ff00");
 *   gradient.addColorStop(1, "#009900");
 *
 *   // Fill the canvas with the gradient pattern
 *   ctx.fillStyle = gradient;
 *   ctx.fillRect(0, 0, 32, 32);
 *
 *   return canvas;
 * }
 *
 * const component = new MeshComponent({
 *   material: {
 *     // Autocast canvas element to MeshTexture instance
 *     colorTexture: createLinearGradient()
 *   }
 * });
 * ```
 *
 * @since 4.11
 * @see [MeshComponent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshComponent.html)
 * @see [Sample - Working with 3d mesh primitives](https://developers.arcgis.com/javascript/latest/sample-code/geometry-mesh-primitives/)
 * @see [Sample - Low poly terrain using mesh geometry](https://developers.arcgis.com/javascript/latest/sample-code/geometry-mesh-elevation/)
 */
export default class MeshMaterial extends MeshMaterialSuperclass {
  constructor(properties?: MeshMaterialProperties);
  /**
   * Specifies how transparency on the object is handled.
   * If [alphaMode](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#alphaMode) is set to either `mask` or `auto` this property specifies the cutoff value below which
   * masking happens (that is, the corresponding part of the Mesh is rendered fully transparent).
   *
   * @default 0.5
   */
  accessor alphaCutoff: number;
  /**
   * Specifies how transparency on the object is handled. See also [alphaCutoff](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#alphaCutoff).
   *
   * | Type | Description |
   * |------|-------------|
   * | opaque | Alpha is ignored, and the object is rendered fully opaque. |
   * | blend | Alpha values are used for gradual transparency, blending between the object and its background. |
   * | mask | Alpha values are used for binary transparency, either displaying the object or its background. See also [alphaCutoff](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-support-MeshMaterial.html#alphaCutoff). |
   * | auto | The implementation mixes the `mask` and `blend` settings, masking below `alphaCutoff` and blending above it. |
   *
   * @default "auto"
   */
  accessor alphaMode: MeshMaterialAlphaMode;
  /**
   * Specifies a single, uniform color for the mesh component. This can be autocast with
   * a named string, hex string, array of rgb or rgba values, an object with `r`, `g`, `b`, and `a`
   * properties, or a [Color](https://developers.arcgis.com/javascript/latest/api-reference/esri-Color.html) object.
   */
  get color(): Color | null | undefined;
  set color(value: ColorLike | null | undefined);
  /**
   * Specifies a texture from which to get color information.
   * The texture is accessed using the UV coordinates specified for each vertex
   * in the [Mesh.vertexAttributes](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html#vertexAttributes).
   */
  get colorTexture(): MeshTexture | null | undefined;
  set colorTexture(value: MeshTextureProperties | string | MeshTextureData | null | undefined);
  /**
   * A transformation of UV mesh coordinates used to sample the color texture. Texture transformations
   * can be used to optimize re-use of textures, for example by packing many images into a single
   * texture "atlas" and using the texture transform offset and scale to sample a specific region
   * within this larger texture.
   *
   * @since 4.27
   */
  get colorTextureTransform(): MeshTextureTransform | null | undefined;
  set colorTextureTransform(value: MeshTextureTransformProperties | null | undefined);
  /**
   * Specifies whether both sides of each triangle are displayed, or only the front sides.
   *
   * @default true
   */
  accessor doubleSided: boolean;
  /**
   * Specifies a texture from which to get normal information.
   * The texture is accessed using the UV coordinates specified for each vertex
   * in the [Mesh.vertexAttributes](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html#vertexAttributes).
   */
  get normalTexture(): MeshTexture | null | undefined;
  set normalTexture(value: MeshTextureProperties | string | MeshTextureData | null | undefined);
  /**
   * A transformation of UV mesh coordinates used to sample the normal texture. Texture transformations
   * can be used to optimize re-use of textures, for example by packing many images into a single
   * texture "atlas" and using the texture transform offset and scale to sample a specific region
   * within this larger texture.
   *
   * @since 4.27
   */
  get normalTextureTransform(): MeshTextureTransform | null | undefined;
  set normalTextureTransform(value: MeshTextureTransformProperties | null | undefined);
}
declare const MeshMaterialSuperclass: typeof JSONSupport & typeof ClonableMixin

export type MeshMaterialAlphaMode = "opaque" | "blend" | "mask" | "auto";