/* @flow */
import {Animated, PixelRatio} from 'react-native'
import {visibleHeight} from './layout'

const density = PixelRatio.get()

const MAX = 0
const MIN = -visibleHeight

const TIME_CONTANT: number = 325

type AnimationConfig = {
  velocity: number,
  fromValue: number,
  amplitude?: number
};

export default class FlickAnimation {
  _active: boolean;

  _velocity: number;
  _amplitude: number;
  _startTime: number;

  _toValue: number;
  _animationFrame: any;
  _animation: Animated.Value;

  constructor(animation: Animated.Value) {
    this._animation = animation
  }

  _scroll(toValue: number): void {
    // eslint-disable-next-line no-nested-ternary
    const offset = (toValue > MAX) ? MAX : (toValue < MIN) ? MIN : toValue
    this._animation.setValue(offset)

    if (offset === MIN || offset === MAX) {
      this.stop()
    }
  }

  start(config: AnimationConfig): void {
    this._active = true
    // eslint-disable-next-line eqeqeq
    this._amplitude = config.amplitude != null ? config.amplitude : 0.8
    this._velocity = -config.velocity * density * 10
    this._toValue = config.fromValue
    this._startTime = Date.now()
    this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this))
  }

  onUpdate(): void {
    if (!this._active) {
      return
    }

    const elapsedTime = Date.now() - this._startTime
    const delta = -(this._amplitude * this._velocity) * Math.exp(-elapsedTime / TIME_CONTANT)

    if (Math.abs(delta) < 0.5) {
      return
    }

    this._toValue += delta
    this._scroll(this._toValue)
    this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this))
  }

  stop(): void {
    this._active = false
    this._animation.stopAnimation()
    global.cancelAnimationFrame(this._animationFrame)
  }
}

@@ -1,34 +1,12 @@
-/* @flow */%0Aimport %7BAnimated, 
+import %7B
 Pixe
@@ -171,313 +171,53 @@
 TANT
-: number = 325%0A%0Atype AnimationConfig = %7B%0A  velocity: number,%0A  fromValue: number,%0A  amplitude?: number%0A%7D;%0A%0Aexport default class FlickAnimation %7B%0A  _active: boolean;%0A%0A  _velocity: number;%0A  _amplitude: number;%0A  _startTime: number;%0A%0A  _toValue: number;%0A  _animationFrame: any;%0A  _animation: Animated.Value;
+ = 325%0A%0Aexport default class FlickAnimation %7B
 %0A%0A  
@@ -241,24 +241,8 @@
 tion
-: Animated.Value
 ) %7B%0A
@@ -299,23 +299,9 @@
 alue
-: number): void
+)
  %7B%0A 
@@ -553,32 +553,9 @@
 nfig
-: AnimationConfig): void
+)
  %7B%0A 
@@ -903,22 +903,16 @@
 Update()
-: void
  %7B%0A    i
@@ -1303,14 +1303,8 @@
 op()
-: void
  %7B%0A 

remove Flow type-checking in FlickAnimation