import type Accessor from "../../core/Accessor.js";

export interface OutputQuantizationParametersProperties extends Partial<Pick<OutputQuantizationParameters, "extent" | "quantizeMode" | "tolerance">> {}

/**
 * Used to project the geometry onto a virtual grid, likely representing
 * pixels on the screen. Geometry coordinates are converted to integers
 * by building a grid with a resolution matching the [tolerance](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-OutputQuantizationParameters.html#tolerance).
 * Each coordinate is then snapped to one pixel on the grid.
 *
 * @since 4.25
 * @see [GraphQueryStreaming](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-GraphQueryStreaming.html)
 * @example
 * //sample implementation of an output quantization parameter
 *
 * //query entities within a bounding box
 * const query = "MATCH (n) WHERE esri.graph.ST_Intersects($param_filter_geom, n.geometry) RETURN n"
 *
 * KnowledgeGraphModule.executeQueryStreaming(
 *   knowledgeGraph,
 *   {
 *     openCypherQuery: query,
 *     bindParameters: {
 *       param_filter_geom: new Polygon({
 *         rings: [
 *           [
 *             [-89, -89],
 *             [89, -89],
 *             [89, 89],
 *             [-89, 89],
 *             [-89, -89],
 *           ],
 *         ],
 *       }),
 *     },
 *     outputQuantizationParameters: {
 *       extent: {
 *         xmax: 30,
 *         xmin: 20,
 *         ymax: 30,
 *         ymin: 20,
 *       },
 *       tolerance: 0.001,
 *       quantizeMode: "view",
 *     }
 *    }
 *   }
 * );
 */
export default class OutputQuantizationParameters extends Accessor {
  constructor(properties?: OutputQuantizationParametersProperties);
  /**
   * An extent defining the quantization grid bounds. Its
   * [SpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) matches the input geometry spatial reference if one is
   * specified for the query. Otherwise, the extent will be in the layer's spatial reference.
   */
  accessor extent: OutputQuantizationParametersExtent | null | undefined;
  /**
   * Geometry coordinates are optimized for viewing and displaying of data.
   * The `view` value specifies that geometry coordinates should be optimized for viewing and displaying of data.
   * The `edit` value specifies that full-resolution geometries should be returned, which can support lossless editing.
   */
  accessor quantizeMode: QuantizeModeCode | null | undefined;
  /**
   * The size of one pixel in the units of the [SpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html).
   * This number is used to convert coordinates to integers by building a grid with a resolution matching the tolerance.
   * Each coordinate is then snapped to one pixel on the grid. Consecutive coordinates snapped to the same pixel are removed
   * for reducing the overall response size. The units of tolerance will match the units of spatial reference.
   * If `outSpatialReference` is not specified, then tolerance is assumed to be in the units of the spatial
   * reference of the layer. If tolerance is not specified, a 10,000 * 10,000 grid is used by default.
   */
  accessor tolerance: number | null | undefined;
}

export interface OutputQuantizationParametersExtent {
  /** Maximum horizontal grid bounds. */
  xmax: number;
  /** Minimum horizontal grid bounds. */
  xmin: number;
  /** Maximum vertical grid bounds. */
  ymax: number;
  /** Minimum vertical grid bounds. */
  ymin: number;
}

export type QuantizeModeCode = "view" | "edit";