import type Color from "../../Color.js";
import type MeshMaterial from "./MeshMaterial.js";
import type MeshTexture from "./MeshTexture.js";
import type MeshTextureTransform from "./MeshTextureTransform.js";
import type { MeshTextureData } from "../types.js";
import type { MeshMaterialProperties } from "./MeshMaterial.js";
import type { ColorLike } from "../../Color.js";
import type { MeshTextureProperties } from "./MeshTexture.js";
import type { MeshTextureTransformProperties } from "./MeshTextureTransform.js";

export interface MeshMaterialMetallicRoughnessProperties extends MeshMaterialProperties, Partial<Pick<MeshMaterialMetallicRoughness, "emissiveStrength" | "metallic" | "roughness">> {
  /**
   * Specifies a single, uniform emissive color for the [MeshComponent](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshComponent/).
   * The emissiveColor is added to the base color of the component.
   * This can be autocast with a named string, hex string, array of rgb values, an object with `r`, `g`, `b`
   * properties, or a [Color](https://developers.arcgis.com/javascript/latest/references/core/Color/) object. Note that the alpha channel is ignored for emissive colors.
   */
  emissiveColor?: ColorLike | null;
  /**
   * Specifies a texture from which to get emissive color information. The texture is accessed using the uv coordinate
   * specified for each vertex in the mesh vertex attributes. The colors in the texture are added to the base color of
   * the component. When using both an `emissiveTexture` and an [emissiveColor](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterialMetallicRoughness/#emissiveColor) their values are
   * multiplied and then added to the base color of the component.
   */
  emissiveTexture?: MeshTextureProperties | string | MeshTextureData | null;
  /**
   * A transformation of UV mesh coordinates used to sample the emissive 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
   */
  emissiveTextureTransform?: MeshTextureTransformProperties | null;
  /**
   * Specifies a texture from which to get the combined metallic/roughness information. The metallic value should be
   * stored in the `blue` channel, while the roughness value should be stored in the `green` channel. The `red` and
   * `alpha` channels are ignored.
   *
   * The texture is accessed using the uv coordinate specified for each vertex in the mesh vertex attributes.
   */
  metallicRoughnessTexture?: MeshTextureProperties | string | MeshTextureData | null;
  /**
   * Allows to specify a texture to get the occlusion information from. This can be used to simulate the effect of
   * ambient light on the object. The texture is accessed using the uv coordinate specified for each vertex in the mesh
   * vertex attributes. The occlusion value should be encoded in the red channel of the texture.
   */
  occlusionTexture?: MeshTextureProperties | string | MeshTextureData | null;
  /**
   * A transformation of UV mesh coordinates used to sample the occlusion 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
   */
  occlusionTextureTransform?: MeshTextureTransformProperties | null;
}

/**
 * A material determines how a [MeshComponent](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshComponent/) is visualized. This particular
 * material (based on [MeshMaterial](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterial/)) uses the metallic/roughness lighting model to
 * enable physically based lighting. The metallic and roughness properties can be used to model various realistic
 * materials including metals and plastics.
 *
 * In this image you can see how [metallic](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterialMetallicRoughness/#metallic) and [roughness](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterialMetallicRoughness/#roughness) property values influence the display
 * of the material:
 *
 * <img src="https://developers.arcgis.com/javascript/latest/assets/references/core/geometry/mesh-metal-roughness.png" width="400"/>
 *
 * The [metallicRoughnessTexture](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterialMetallicRoughness/#metallicRoughnessTexture) can be used to map specific metallic/roughness properties
 * on different parts of the model.
 *
 * @since 4.15
 * @see [MeshComponent](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshComponent/)
 * @see [MeshMaterial](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterial/)
 * @see [Sample - Low poly terrain using mesh geometry](https://developers.arcgis.com/javascript/latest/sample-code/geometry-mesh-elevation/)
 */
export default class MeshMaterialMetallicRoughness extends MeshMaterial {
  constructor(properties?: MeshMaterialMetallicRoughnessProperties);
  /**
   * Specifies a single, uniform emissive color for the [MeshComponent](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshComponent/).
   * The emissiveColor is added to the base color of the component.
   * This can be autocast with a named string, hex string, array of rgb values, an object with `r`, `g`, `b`
   * properties, or a [Color](https://developers.arcgis.com/javascript/latest/references/core/Color/) object. Note that the alpha channel is ignored for emissive colors.
   */
  get emissiveColor(): Color | null | undefined;
  set emissiveColor(value: ColorLike | null | undefined);
  /**
   * Specifies a strength value as multiplier for emissive color for the [MeshComponent](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshComponent/).
   * Emissive strength will be read or stored using the [KHR_materials_emissive_strength](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)
   * extension when importing or exporting GLTFs.
   */
  accessor emissiveStrength: number | null | undefined;
  /**
   * Specifies a texture from which to get emissive color information. The texture is accessed using the uv coordinate
   * specified for each vertex in the mesh vertex attributes. The colors in the texture are added to the base color of
   * the component. When using both an `emissiveTexture` and an [emissiveColor](https://developers.arcgis.com/javascript/latest/references/core/geometry/support/MeshMaterialMetallicRoughness/#emissiveColor) their values are
   * multiplied and then added to the base color of the component.
   */
  get emissiveTexture(): MeshTexture | null | undefined;
  set emissiveTexture(value: MeshTextureProperties | string | MeshTextureData | null | undefined);
  /**
   * A transformation of UV mesh coordinates used to sample the emissive 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 emissiveTextureTransform(): MeshTextureTransform | null | undefined;
  set emissiveTextureTransform(value: MeshTextureTransformProperties | null | undefined);
  /**
   * Specifies how much the material behaves like a metal. Values must be in the range 0 (non metal material) to 1
   * (metal material). Physically accurate materials are usually either a metal (1) or a non-metal (0) and not something
   * in between.
   *
   * @default 1
   */
  accessor metallic: number;
  /**
   * Specifies a texture from which to get the combined metallic/roughness information. The metallic value should be
   * stored in the `blue` channel, while the roughness value should be stored in the `green` channel. The `red` and
   * `alpha` channels are ignored.
   *
   * The texture is accessed using the uv coordinate specified for each vertex in the mesh vertex attributes.
   */
  get metallicRoughnessTexture(): MeshTexture | null | undefined;
  set metallicRoughnessTexture(value: MeshTextureProperties | string | MeshTextureData | null | undefined);
  /**
   * Allows to specify a texture to get the occlusion information from. This can be used to simulate the effect of
   * ambient light on the object. The texture is accessed using the uv coordinate specified for each vertex in the mesh
   * vertex attributes. The occlusion value should be encoded in the red channel of the texture.
   */
  get occlusionTexture(): MeshTexture | null | undefined;
  set occlusionTexture(value: MeshTextureProperties | string | MeshTextureData | null | undefined);
  /**
   * A transformation of UV mesh coordinates used to sample the occlusion 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 occlusionTextureTransform(): MeshTextureTransform | null | undefined;
  set occlusionTextureTransform(value: MeshTextureTransformProperties | null | undefined);
  /**
   * Indicates how rough the surface of the material is. Values must be in the range 0 (fully smooth surface) to 1
   * (fully diffuse surface).
   *
   * @default 1
   */
  accessor roughness: number;
}