export type EaseFn = (t: number) => number;

export type SpringParams = {
  mass?: number;
  stiffness?: number;
  damping?: number;
  velocity?: number;
  duration?: number;
};

export type Ease = {
  /** Ease-in easing functions. */
  in: Ease_in_out_inOut;

  /** Ease-out easing functions. */
  out: Ease_in_out_inOut;

  /** Ease-in-out easing functions. */
  inOut: Ease_in_out_inOut;

  /** Default linear easing function. */
  linear: EaseFn;

  /**
   * Defines a [cubic Bézier curve](https://developer.mozilla.org/en-US/docs/Glossary/Bezier_curve),
   * similar to CSS's **cubic-bezier** easing function.
   *
   * **CubicBezier** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#cubicBezier) to learn more.
   *
   * @example
   * ```js
   * import animare from 'animare';
   * import { ease } from 'animare/plugins';
   *
   * animare.timeline([{ name: 'anim', to: 100, ease: ease.cubicBezier(0.25, 0.1, 0.25, 1) }], onUpdate);
   * ```
   */
  cubicBezier: (x1: number, y1: number, x2: number, y2: number) => EaseFn;

  /**
   * Creates a custom easing function from an SVG path `d` attribute string.
   *
   * ⚠️ **Warning** ⚠️ Only accepts strings generated by the [Animare Ease Visualizer](https://animare-ease-visualizer.netlify.app/) tool.
   *
   * @param pathString - The SVG path `d` attribute.
   */
  custom: (pathString: string) => EaseFn;

  /**
   * Creates a custom easing function from an array of points.
   *
   * Use the [Animare Ease Visualizer](https://animare-ease-visualizer.netlify.app/) tool to create the easing function.
   *
   * **FromPoints** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#frompoints) to learn more.
   *
   * @example
   * ```js
   * import animare from 'animare';
   * import { ease } from 'animare/plugins';
   * // Custom easing function generated by Animare Ease Visualizer tool
   * import myEase from './myEase.js';
   *
   * animare.timeline([{ name: 'anim', to: 100, ease: ease.fromPoints(myEase) }], onUpdate);
   * ```
   */
  fromPoints: (values: Float32List) => EaseFn;

  /**
   * Creates a staircase easing function.
   *
   * **Steps** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#steps) to learn more.
   *
   * @param steps - The number of steps.
   * @param start - Whether to start at the beginning or at the end of each interval.
   *
   * @example
   * ```js
   * import animare from 'animare';
   * import { ease } from 'animare/plugins';
   *
   * animare.timeline([{ name: 'anim', to: 100, ease: ease.steps(5) }], onUpdate);
   * ```
   */
  steps(steps?: number, start?: boolean): EaseFn;

  /**
   * Creates a spring easing function.
   *
   * ⚠️ **Warning** ⚠️ The spring easing function will only look smooth at certain durations and with certain parameters.
   *
   * **Spring** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#spring) to learn more.
   *
   * @example
   * ```js
   * import animare from 'animare';
   * import { ease } from 'animare/plugins';
   *
   * animare.timeline([
   * {
   *   name: 'anim',
   *   to: 100,
   *   ease: ease.spring({ mass: 1, stiffness: 100, damping: 10, velocity: 0, duration: 1000 })
   * }
   * ], onUpdate);
   * ```
   */
  spring: (options?: SpringParams) => EaseFn;
};

export type Ease_in_out_inOut = {
  /** **Back** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#back) to learn more.*/
  back: (c1?: number) => EaseFn;

  /** **Bounce** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#bounce) to learn more.*/
  bounce: EaseFn;

  /** **Cric** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#cric) to learn more.*/
  circ: EaseFn;

  /** **Cubic** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#cubic) to learn more.*/
  cubic: EaseFn;

  /** **Elastic** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#elastic) to learn more.*/
  elastic: EaseFn;

  /** **Expo** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#expo) to learn more.*/
  expo: EaseFn;

  /** **Sine** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#sine) to learn more.*/
  sine: EaseFn;

  /** **Quad** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#quad) to learn more.*/
  quad: EaseFn;

  /** **Quart** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#quart) to learn more.*/
  quart: EaseFn;

  /** **Quint** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#quint) to learn more.*/
  quint: EaseFn;

  /** A power function. Position is equal to the Nth power of elapsed time. */
  poly: (n: number) => EaseFn;

  /**
   * Creates a simple elastic interaction, similar to a spring oscillating back and forth.
   *
   * The default bounciness is `1`, which overshoots a little bit once.
   * A bounciness of `0` doesn't overshoot at all,
   * and a bounciness of `N > 1` will overshoot about `N` times.
   *
   * **Wobble** check out [animare docs](https://alabsi91.github.io/animare/api/plugins/ease/#wobble) to learn more.
   */
  wobble: (bounciness?: number) => EaseFn;
};
