import {InputEvent, InputDirection} from './input-consts';
import type {Recognizer} from '../recognizer/recognizer';

export type Point = {x: number; y: number};
export type Vector = {x: number; y: number};
export type PointerEventLike = {clientX: number; clientY: number};

export type DeviceInputEvent = MouseEvent | PointerEvent;

/**
 * Transitional type generated by Input classes for processing */
export type RawInput = {
  pointers: DeviceInputEvent[];
  changedPointers: DeviceInputEvent[];
  pointerType: string;
  srcEvent: DeviceInputEvent;
  eventType: InputEvent;

  // Populated during processing
  /** Timestamp of the event. */
  timeStamp?: number;
  /** Total time since the first input. */
  deltaTime?: number;

  /** Center position for multi-touch, or the position of the single pointer. */
  center?: Point;
  /** Movement along the X axis. */
  deltaX?: number;
  /** Movement along the Y axis. */
  deltaY?: number;
  /** Angle moved, in degrees */
  angle?: number;
  /** Distance moved */
  distance?: number;
  /** Scaling that has been done with multi-touch. 1 on a single touch. */
  scale?: number;
  /** Rotation (in degrees) that has been done with multi-touch. 0 on a single touch. */
  rotation?: number;

  /** Direction moved. */
  direction?: InputDirection;
  /** Direction moved from its starting point. */
  offsetDirection?: InputDirection;

  /** Highest velocityX/Y value. */
  velocity?: number;
  /** Velocity along the X axis, in px/ms */
  velocityX?: number;
  /** Velocity along the Y axis, in px/ms */
  velocityY?: number;

  overallVelocity?: number;
  overallVelocityX?: number;
  overallVelocityY?: number;

  maxPointers?: number;
  target?: HTMLElement;

  /** Internal flag */
  additionalEvent?: string;
  /** Internal flag */
  isFirst?: boolean;
  /** Internal flag */
  isFinal?: boolean;
};

/**
 * Emitted input event */
export type HammerInput = Omit<Required<RawInput>, 'isFirst' | 'isFinal'> & {
  /** Number of consecutive taps recognized. Populated if emitted by TapRecognizer */
  tapCount?: number;
};

/**
 * Simplified HammerInput object retained in memory to help event processing */
export type SimpleInput = {
  pointers: PointerEventLike[];
  timeStamp: number;
  center: Point;
  deltaX?: number;
  deltaY?: number;
};

/**
 * Information about an input session (pointers down-move-up)
 */
export type Session = {
  pointerEvents?: PointerEvent[];
  stopped?: number;
  curRecognizer?: Recognizer | null;
  offsetDelta?: Vector;
  prevDelta?: Vector;

  firstInput?: SimpleInput;
  firstMultiple?: SimpleInput | false;

  prevInput?: HammerInput;
  lastInterval?: HammerInput;

  prevented?: boolean;
};
