import type Accessor from "../../../core/Accessor.js";
import type Point from "../../../geometry/Point.js";
import type SpatialReference from "../../../geometry/SpatialReference.js";
import type CoordinateConversionViewModel from "../CoordinateConversionViewModel.js";
import type { ConversionInfo, CoordinateSegment } from "../../types.js";
import type { SpatialReferenceProperties } from "../../../geometry/SpatialReference.js";

export interface FormatProperties extends Partial<Pick<Format, "conversionInfo" | "coordinateSegments" | "defaultPattern" | "name" | "viewModel">> {
  /**
   * A string that serves as a pattern describing how this Format should be displayed.  The pattern should
   * contain all of aliases specified by the Format's [coordinateSegments property](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html#coordinateSegments).
   *
   * @example
   * // Remove the spaces from an mgrs coordinate
   * let format = coordinateConversionWidget.formats.find(function(format) {
   *   return format.name === "mgrs";
   * });
   *
   * console.log.(format.currentPattern);
   * // > Z S X Y
   *
   * format.currentPattern = "ZSXY"
   */
  currentPattern?: string | null;
  /**
   * A string that is used to label this Format in the UI. If not set, it will default to
   * [name](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html#name)
   *
   * @since 4.24
   */
  label?: string | null;
  /**
   * The [SpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) for this format.  Coordinates generated for a format
   * will be derived from points in this spatial reference.
   */
  spatialReference?: SpatialReferenceProperties;
}

/**
 * The Format class represents one of the [CoordinateConversion#formats](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html#formats)
 * in the [Coordinate Conversion widget](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html).  Each format describes how
 * a [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) should be transformed into a coordinate for display purposes.
 *
 * @since 4.7
 * @see [CoordinateConversionViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-CoordinateConversionViewModel.html)
 * @see [CoordinateConversion](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html)
 * @see [Sample - Add custom coordinate formats](https://developers.arcgis.com/javascript/latest/sample-code/widgets-coordinateconversion-custom/)
 */
export default class Format extends Accessor {
  constructor(properties?: FormatProperties);
  /**
   * Contains information that describes how this Format should be converted.  This property should only be
   * set when creating a custom Format.
   */
  accessor conversionInfo: ConversionInfo | null | undefined;
  /**
   * A array of [Coordinate Segments](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-types.html#CoordinateSegment).  Each segment represents a section of the Format's
   * coordinate.
   */
  accessor coordinateSegments: CoordinateSegment[] | null | undefined;
  /**
   * A string that serves as a pattern describing how this Format should be displayed.  The pattern should
   * contain all of aliases specified by the Format's [coordinateSegments property](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html#coordinateSegments).
   *
   * @example
   * // Remove the spaces from an mgrs coordinate
   * let format = coordinateConversionWidget.formats.find(function(format) {
   *   return format.name === "mgrs";
   * });
   *
   * console.log.(format.currentPattern);
   * // > Z S X Y
   *
   * format.currentPattern = "ZSXY"
   */
  get currentPattern(): string;
  set currentPattern(value: string | null | undefined);
  /** The default pattern describing how this Format should be displayed.  See [currentPattern](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html#currentPattern). */
  accessor defaultPattern: string | null | undefined;
  /**
   * A string that is used to label this Format in the UI. If not set, it will default to
   * [name](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html#name)
   *
   * @since 4.24
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * The name of the coordinate.  A [CoordinateConversion](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html)
   * widget should not contain multiple Formats with the same name.
   */
  accessor name: string | null | undefined;
  /**
   * The [SpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) for this format.  Coordinates generated for a format
   * will be derived from points in this spatial reference.
   */
  get spatialReference(): SpatialReference;
  set spatialReference(value: SpatialReferenceProperties);
  /** The view model of the [CoordinateConversion](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html) widget that is utilizing this format. */
  accessor viewModel: CoordinateConversionViewModel | null | undefined;
  /**
   * Attempt to convert a valid string for this [Format](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion-support-Format.html) into a [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html)
   *
   * @param coordinate - The coordinate string.
   * @returns When resolved, returns a [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html)
   * @since 4.34
   * @see [CoordinateConversion#reverseConvert()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-CoordinateConversion.html#reverseConvert)
   */
  reverseConvert(coordinate: string): Promise<Point | null | undefined>;
}