/**
   * Create a pair of {@link FlipAnimation} that can be used to flip 3D transition from {@code
   * fromView} to {@code toView}. A typical use case is with {@link ViewAnimator} as an out and in
   * transition.
   *
   * <p>NOTE: Avoid using this method. Instead, use {@link #flipTransition}.
   *
   * @param fromView the view transition away from
   * @param toView the view transition to
   * @param dir the flip direction
   * @param duration the transition duration in milliseconds
   * @param interpolator the interpolator to use (pass {@code null} to use the {@link
   *     AccelerateInterpolator} interpolator)
   * @return
   */
  public static Animation[] flipAnimation(
      final View fromView,
      final View toView,
      FlipDirection dir,
      long duration,
      Interpolator interpolator) {
    Animation[] result = new Animation[2];
    float centerX;
    float centerY;

    centerX = fromView.getWidth() / 2.0f;
    centerY = fromView.getHeight() / 2.0f;

    Animation outFlip =
        new FlipAnimation(
            dir.getStartDegreeForFirstView(),
            dir.getEndDegreeForFirstView(),
            centerX,
            centerY,
            FlipAnimation.SCALE_DEFAULT,
            FlipAnimation.ScaleUpDownEnum.SCALE_DOWN);
    outFlip.setDuration(duration);
    outFlip.setFillAfter(true);
    outFlip.setInterpolator(interpolator == null ? new AccelerateInterpolator() : interpolator);

    AnimationSet outAnimation = new AnimationSet(true);
    outAnimation.addAnimation(outFlip);
    result[0] = outAnimation;

    // Uncomment the following if toView has its layout established (not the case if using
    // ViewFlipper and on first show)
    // centerX = toView.getWidth() / 2.0f;
    // centerY = toView.getHeight() / 2.0f;

    Animation inFlip =
        new FlipAnimation(
            dir.getStartDegreeForSecondView(),
            dir.getEndDegreeForSecondView(),
            centerX,
            centerY,
            FlipAnimation.SCALE_DEFAULT,
            FlipAnimation.ScaleUpDownEnum.SCALE_UP);
    inFlip.setDuration(duration);
    inFlip.setFillAfter(true);
    inFlip.setInterpolator(interpolator == null ? new AccelerateInterpolator() : interpolator);
    inFlip.setStartOffset(duration);

    AnimationSet inAnimation = new AnimationSet(true);
    inAnimation.addAnimation(inFlip);
    result[1] = inAnimation;

    return result;
  }
  /**
   * Create a pair of {@link FlipAnimation} that can be used to flip 3D transition from {@code
   * fromView} to {@code toView}. A typical use case is with {@link ViewAnimator} as an out and in
   * transition.
   *
   * <p>NOTE: Avoid using this method. Instead, use {@link #flipTransition}.
   *
   * @param fromView the view transition away from
   * @param toView the view transition to
   * @param dir the flip direction
   * @param duration the transition duration in milliseconds
   * @param interpolator the interpolator to use (pass {@code null} to use the {@link
   *     AccelerateInterpolator} interpolator)
   * @return
   */
  public static Animation[] flipAnimation(
      final View fromView, final View toView, FlipDirection dir, long duration) {

    Animation[] result = new Animation[2];
    float centerY;

    centerY = fromView.getHeight() / 2.0f;

    Animation outFlip =
        new FlipAnimation(
            dir.getStartDegreeForFirstView(),
            dir.getEndDegreeForFirstView(),
            true,
            centerY,
            dir,
            fromView.getWidth());
    outFlip.setDuration(duration);
    outFlip.setFillAfter(true);
    outFlip.setInterpolator(new AccelerateInterpolator());

    AnimationSet outAnimation = new AnimationSet(true);
    outAnimation.addAnimation(outFlip);
    result[0] = outAnimation;

    Animation inFlip =
        new FlipAnimation(
            dir.getStartDegreeForSecondView(),
            dir.getEndDegreeForSecondView(),
            false,
            centerY,
            dir,
            fromView.getWidth());
    inFlip.setDuration(duration);
    inFlip.setFillAfter(true);
    inFlip.setInterpolator(new DecelerateInterpolator());
    inFlip.setStartOffset(duration);

    AnimationSet inAnimation = new AnimationSet(true);
    inAnimation.addAnimation(inFlip);
    result[1] = inAnimation;

    return result;
  }
  /**
   * Flip to the next view of the {@code ViewAnimator}'s subviews. A call to this method will
   * initiate a {@link FlipAnimation} to show the next View. If the currently visible view is the
   * last view, flip direction will be reversed for this transition.
   *
   * @param viewAnimator the {@code ViewAnimator}
   * @param dir the direction of flip
   */
  public static void flipTransition(final ViewAnimator viewAnimator, FlipDirection dir) {

    final View fromView = viewAnimator.getCurrentView();
    final int currentIndex = viewAnimator.getDisplayedChild();
    final int nextIndex = (currentIndex + 1) % viewAnimator.getChildCount();

    final View toView = viewAnimator.getChildAt(nextIndex);

    Animation[] animc =
        AnimationFactory.flipAnimation(
            fromView,
            toView,
            (nextIndex < currentIndex ? dir.theOtherDirection() : dir),
            500,
            null);

    viewAnimator.setOutAnimation(animc[0]);
    viewAnimator.setInAnimation(animc[1]);

    viewAnimator.showNext();
  }