import type Viewpoint from "../Viewpoint.js";
import type { EsriPromise, EsriPromiseMixinProperties } from "../core/Promise.js";

export interface ViewAnimationProperties extends EsriPromiseMixinProperties, Partial<Pick<ViewAnimation, "target">> {}

/**
 * Contains a [state](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-ViewAnimation.html#state) property used for checking the state of the animation.
 * The view animation is resolved when the animation has `finished` and is
 * rejected if it is `stopped`.
 *
 * ```js
 * reactiveUtils.when(() => view.animation, function(animation) {
 *   console.log(animation.state); // prints out "running"
 *   animation.when(function(animation) {
 *       console.log(animation.state); // prints out "finished"
 *     })
 *     .catch(function(animation) {
 *       console.log(animation.state); // prints out "stopped"
 *     });
 * });
 * ```
 *
 * Alternatively the [state](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-ViewAnimation.html#state) property can be watched for changes:
 *
 * ```js
 * let animation = view.goTo(target, { speedFactor: 0.1 });
 *
 * reactiveUtils.watch(
 *   () => animation.state,
 *   (state) => {
 *     switch (state) {
 *       case "finished":
 *         console.log("Animation finished.");
 *         break;
 *       case "stopped":
 *         console.log("Animation stopped.");
 *         break;
 *     }
 *   }
 * );
 *
 * @since 4.0
 * @see [SceneView#goTo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html#goTo)
 * @see [MapView#animation](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#animation)
 */
export default class ViewAnimation extends EsriPromise {
  constructor(properties?: ViewAnimationProperties);
  /**
   * The state of the animation.
   *
   * The animation terminates when the state is either `finished` or `stopped`
   * and cannot transition again to `running`. The `finished` state
   * indicates the animation has successfully ended, while the `stopped`
   * state indicates that the animation was interrupted before it reached
   * its final target.
   *
   * @default "running"
   */
  get state(): ViewAnimationStateType;
  /** The target of the animation. */
  accessor target: Viewpoint | Promise<Viewpoint> | null | undefined;
  /**
   * Finishes the view animation by immediately going to the target and sets
   * the state of the animation to `finished`.
   */
  finish(): void;
  /**
   * Stops the view animation at its current state and sets the state of
   * the animation to `stopped`.
   */
  stop(): void;
}

export type ViewAnimationStateType = "running" | "finished" | "stopped" | "waiting-for-target";