package com.pspdfkit.labs.vangogh.api;

import android.support.annotation.NonNull;
import android.view.View;
import android.view.animation.CycleInterpolator;

import com.pspdfkit.labs.vangogh.base.AnimationBuilder;
import com.pspdfkit.labs.vangogh.rx.AnimationCompletable;

import io.reactivex.Completable;

/**
 * Class containing convenient animations for "shaking" the views.
 */
public final class ShakeAnimations {

    /** Amount of 'shakes' applied to the view inside one second (by default). */
    private static final float CYCLES_PER_SECOND_DEFAULT = 10f;

    /** Amount of 'shakes' applied to the view inside one second (slow). */
    private static final float CYCLES_PER_SECOND_SLOW = 4f;

    /** Amount of 'shakes' applied to the view inside one second (quick). */
    private static final float CYCLES_PER_SECOND_QUICK = 20f;

    /**
     * Shakes the given view.
     * @param view View on which to apply the animation.
     * @return     Completable executing animation once subscribed to.
     */
    public static Completable shake(@NonNull View view) {
        return shake(view, AnimationConstants.DURATION_DEFAULT);
    }

    /**
     * Shakes the given view.
     * @param view       View on which to apply the animation.
     * @param durationMs Duration of the animation in milliseconds.
     * @return           Completable executing animation once subscribed to.
     */
    public static Completable shake(@NonNull View view, long durationMs) {
        return shake(view, durationMs, CYCLES_PER_SECOND_DEFAULT);
    }

    /**
     * Shakes the given view.
     * @param view            View on which to apply the animation.
     * @param durationMs      Duration of the animation in milliseconds.
     * @param cyclesPerSecond Cycles per second, presenting a number of shakes per second,
     *                        defaults to {@value #CYCLES_PER_SECOND_DEFAULT}.
     * @return                Completable executing animation once subscribed to.
     */
    public static Completable shake(@NonNull View view, long durationMs, float cyclesPerSecond) {
        final float numberOfCycles = durationMs * (cyclesPerSecond / 1000);
        final CycleInterpolator interpolator = new CycleInterpolator(numberOfCycles / 2);
        final AnimationCompletable shakeFirst = AnimationBuilder.forView(view)
                .translationXBy(10f)
                .interpolator(interpolator)
                .duration(durationMs / 2)
                .buildCompletable();
        final AnimationCompletable shakeSecond = AnimationBuilder.forView(view)
                .translationXBy(-10f)
                .interpolator(interpolator)
                .duration(durationMs / 2)
                .buildCompletable();
        return shakeFirst.andThen(shakeSecond);
    }

    /**
     * Shakes the given view quickly.
     * @param view View on which to apply the animation.
     * @return     Completable executing animation once subscribed to.
     */
    public static Completable shakeQuickly(@NonNull View view) {
        return shake(view, AnimationConstants.DURATION_DEFAULT, CYCLES_PER_SECOND_QUICK);
    }

    /**
     * Shakes the given view quickly.
     * @param view       View on which to apply the animation.
     * @param durationMs Duration of the animation in milliseconds.
     * @return           Completable executing animation once subscribed to.
     */
    public static Completable shakeQuickly(@NonNull View view, long durationMs) {
        return shake(view, durationMs, CYCLES_PER_SECOND_QUICK);
    }

    /**
     * Shakes the given view slowly.
     * @param view View on which to apply the animation.
     * @return     Completable executing animation once subscribed to.
     */
    public static Completable shakeSlowly(@NonNull View view) {
        return shake(view, AnimationConstants.DURATION_DEFAULT, CYCLES_PER_SECOND_SLOW);
    }

    /**
     * Shakes the given view slowly.
     * @param view       View on which to apply the animation.
     * @param durationMs Duration of the animation in milliseconds.
     * @return           Completable executing animation once subscribed to.
     */
    public static Completable shakeSlowly(@NonNull View view, long durationMs) {
        return shake(view, durationMs, CYCLES_PER_SECOND_SLOW);
    }

}

@@ -519,36 +519,36 @@
 tic final float 
-CYCL
+SHAK
 ES_PER_SECOND_DE
@@ -660,36 +660,36 @@
 tic final float 
-CYCL
+SHAK
 ES_PER_SECOND_SL
@@ -806,20 +806,20 @@
 l float 
-CYCL
+SHAK
 ES_PER_S
@@ -1502,36 +1502,36 @@
 ew, durationMs, 
-CYCL
+SHAK
 ES_PER_SECOND_DE
@@ -1738,20 +1738,20 @@
  @param 
-cycl
+shak
 esPerSec
@@ -1758,98 +1758,36 @@
 ond 
-Cycles per second, presenting a number of shakes per second,%0A     *                       
+Number of shakes per second,
  def
@@ -1804,20 +1804,20 @@
 @value #
-CYCL
+SHAK
 ES_PER_S
@@ -2001,20 +2001,20 @@
 , float 
-cycl
+shak
 esPerSec
@@ -2075,12 +2075,12 @@
  * (
-cycl
+shak
 esPe
@@ -3024,36 +3024,36 @@
 RATION_DEFAULT, 
-CYCL
+SHAK
 ES_PER_SECOND_QU
@@ -3440,36 +3440,36 @@
 ew, durationMs, 
-CYCL
+SHAK
 ES_PER_SECOND_QU
@@ -3790,20 +3790,20 @@
 EFAULT, 
-CYCL
+SHAK
 ES_PER_S
@@ -4207,12 +4207,12 @@
 Ms, 
-CYCL
+SHAK
 ES_P

Use shakes instead of cycles