// Type definitions for ui/Touchable

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;

export interface TouchableConfig extends Object {
  /**
   * Configures the prop name to pass the active state to the wrapped component
   */
  activeProp?: string;
}
export interface TouchableProps {
  /**
   * Disables the component.
   */
  disabled?: boolean;
  /**
   * Instance-specific overrides of the drag configuration.
   */
  dragConfig?: object;
  /**
   * Instance-specific overrides of the flick configuration.
   */
  flickConfig?: object;
  /**
   * Instance-specific overrides of the hold configuration.
   */
  holdConfig?: object;
  /**
   * Prevents resuming the touch events and gestures when re-entering the component.
   */
  noResume?: boolean;
  /**
   * Event handler for 'down' pointer events.
   */
  onDown?: Function;
  /**
   * Event handler for a drag gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onDrag'`
   * *  `x`  - Horizontal position of the drag, relative to the viewport
   * *  `y`  - Vertical position of the drag, relative to the viewport
   */
  onDrag?: Function;
  /**
   * Event handler for the end of a drag gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onDragEnd'`
   */
  onDragEnd?: Function;
  /**
   * Event handler for the start of a drag gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onDragStart'`
   * *  `x`  - Horizontal position of the drag, relative to the viewport
   * *  `y`  - Vertical position of the drag, relative to the viewport
   */
  onDragStart?: Function;
  /**
   * Event handler for a flick gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onFlick'`
   * *  `direction`  - Primary direction of the flick, either  `'horizontal'`  or  `'vertical'`
   * *  `velocity`  - Velocity of flick
   * *  `velocityX`  - Velocity of flick along te horizontal axis
   * *  `velocityY`  - Velocity of flick along te vertical axis
   */
  onFlick?: Function;
  /**
   * Event handler for hold pulse events.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onHold'`
   * *  `time`  - Time, in milliseconds, since the hold began
   */
  onHold?: Function;
  /**
   * Event handler for the end of hold events.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onHoldEnd'`
   * *  `time`  - Time, in milliseconds, since the hold began
   */
  onHoldEnd?: Function;
  /**
 * Event handler for hold events.
 * 
 * Event payload includes:
 * *  `type`  - Type of event,  `'onHoldStart'`
 * *  `name`  - The name of the hold as configured in the events list
 * *  `time`  - Time, in milliseconds, configured for this hold which may vary slightly
from time since the hold began
 */
  onHoldStart?: Function;
  /**
   * Event handler for 'move' pointer events.
   */
  onMove?: Function;
  /**
 * Event handler for a pinch gesture.
 * 
 * Event payload includes:
 * *  `type`  - Type of event,  `'onPinch'`
 * *  `scale`  - The scale factor, calculated from the distance while pinching.
The default value is 1.0. The value would be a number between
pinchConfig.minScale and pinchConfig.maxScale.
 * *  `coords`  - The coordinates array of the touch point, relative to the viewport
 */
  onPinch?: Function;
  /**
   * Event handler for the end of a pinch gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onPinchEnd'`
   */
  onPinchEnd?: Function;
  /**
   * Event handler for the start of a pinch gesture.
   *
   * Event payload includes:
   * *  `type`  - Type of event,  `'onPinchStart'`
   * *  `coords`  - The coordinates array of the touch point, relative to the viewport
   */
  onPinchStart?: Function;
  /**
   * Event handler for 'tap' pointer events.
   */
  onTap?: Function;
  /**
   * Event handler for 'up' pointer events.
   */
  onUp?: Function;
  /**
   * Instance-specific overrides of the pinch configuration.
   */
  pinchConfig?: object;
}
export function Touchable<P>(
  config: TouchableConfig,
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & TouchableProps>;

export function Touchable<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & TouchableProps>;

/**
 * Configures the global gesture configuration for the application.
 * 
 * Example:
 * ```
// Updates the `maxMoves`, `moveTolerance`, and `frequency` configurations while retaining the
// current value of all other configurations
configure({
    flick: {
        maxMoves: 10
    },
    hold: {
        moveTolerance: 32,
        frequency: 400
    }
});
```
 
 * Each type of gesture has its own set of configuration properties grouped within a separate object
keyed by the name of the gesture. Partial configurations may be passed and will be merged with
the current configuration.
 * 
 * `drag`
 * *  `boxSizing`  - The part of the component's box model is used as the bounds of the constraint.
Only applies when  `global`  is  `false` .
 * *  `'border-box'`  - the default, includes the padding and border but excludes the margin.
 * *  `'content-box'`  - excludes the padding, border, and margin.
 * *  `global`  - When  `true` , drag gestures will continue when leaving the bounds of the component
or blurring the component.
 * *  `moveTolerance`  - The number of pixels from the start position of the drag that the pointer
may move before cancelling the drag. Defaults to  `16` .
 * 
 * `flick`
 * *  `maxDuration`  - The amount of time, in milliseconds, to complete a flick gesture before it
is cancelled. Defaults to 250.
 * *  `maxMoves`  - The number of moves tracked to determine if a flick occurred. Defaults to  `5` .
 * *  `minVelocity`  - The minimum threshold, measured as the change in pixels over the change in
time per move, that must be exceeded to generate a  `onFlick`  event.
 * 
 * `hold`
 * *  `cancelOnMove`  - When  `true` , the hold is cancelled when moving beyond the  `moveTolerance` .
Defaults to  `false`
 * *  `global`  - When  `true` , hold gestures will continue when leaving the bounds of the component
or blurring the component.
 * *  `moveTolerance`  - The number of pixels from the start position of the hold that the pointer
may move before cancelling the hold. Ignored when  `cancelOnMove`  is  `false` . Defaults to
 `16` .
 * *  `frequency`  - The time, in milliseconds, to poll for hold events. Defaults to  `200` .
 * *  `events`  - An array of  `onHoldStart`  events which each contain a  `name`  and  `time` . The  `time` 
controls the amount of time that must pass before this  `onHoldStart`  event is fired and should
be a multiple of  `frequency` .
 * 
 * `pinch`
 * *  `boxSizing`  - The part of the component's box model is used as the bounds of the constraint.
Only applies when  `global`  is  `false` .
 * *  `'border-box'`  - the default, includes the padding and border but excludes the margin.
 * *  `'content-box'`  - excludes the padding, border, and margin.
 * *  `global`  - When  `true` , pinch gestures will continue when leaving the bounds of the component
or blurring the component.
 * *  `maxScale`  - The maximum scale value. Defaults to  `4` .
 * *  `minScale`  - The minimum scale value. Defaults to  `0.5` .
 * *  `moveTolerance`  - The distance difference from the previous distance that the pointer may move
before cancelling the scaling. Defaults to  `16` .
 */
export function configure(cfg: object): void;

export default Touchable;
