/**
   * Add {@link Decor} into this layout. Decor will be added to the layout based on its start page
   * and end page. Calling this method will also enables children drawing order, which follows the
   * order of the parameters, e.g the first Decor will be drawn first.
   *
   * @param decor Decor object to be added to this layout.
   * @throws IllegalStateException when ViewPager is not set in this layout.
   */
  @SuppressWarnings("unused")
  public void addDecor(Decor decor) {
    if (mViewPager == null) {
      throw new IllegalStateException(
          "ViewPager is not found in SparkleViewPagerLayout, please provide a ViewPager first");
    }

    if (decor == null) {
      return;
    }

    // Make sure there is no duplicate.
    if (mDecors.contains(decor)) {
      return;
    }

    mDecors.add(decor);

    // Add slide in and slide out animations to the presenter.
    SparkleAnimationPresenter presenter = SparkleMotionCompat.getAnimationPresenter(mViewPager);
    if (presenter == null) {
      throw new IllegalStateException("Failed initializing animation");
    }

    presenter.addAnimation(decor, decor.slideInAnimation, decor.slideOutAnimation);

    if (decor.layoutBehindViewPage) {
      addView(decor.contentView, mViewPagerIndex);
      mViewPagerIndex++;
    } else {
      addView(decor.contentView);
    }

    layoutDecors(mViewPager.getCurrentItem(), 0);
  }
  /**
   * Assign target {@link Decor} to SparkleMotion, which will assign the animations stored in {@link
   * #animate(Animation...)} to {@link SparkleAnimationPresenter}. This is the last method to call
   * in order to build a functional ViewPager. Once this is called, a {@link
   * SparkleAnimationPresenter} will be associated to the ViewPager, and the animations will be run
   * when scrolling.
   *
   * <p>Note that to use this method, a {@link SparkleViewPagerLayout} must be provided.
   *
   * @param decors Target Decors.
   * @throws IllegalStateException when a ViewPagerLayout is not provided.
   */
  public void on(final Decor... decors) {
    if (mViewPagerLayout == null) {
      throw new IllegalStateException("A ViewPagerLayout must be provided for animating Decor");
    }

    Animation[] animations = new Animation[mAnimations.size()];
    mAnimations.toArray(animations);

    for (Decor decor : decors) {
      mPresenter.addAnimation(decor, animations);
    }

    mAnimations.clear();

    ViewPager viewPager = mViewPagerLayout.getViewPager();
    if (viewPager == null) {
      throw new NullPointerException("ViewPager cannot be null");
    }

    SparkleMotionCompat.installAnimationPresenter(viewPager, false, mPresenter);

    for (Decor decor : decors) {
      mViewPagerLayout.addDecor(decor);
    }
  }
  /**
   * Assign target Views to SparkleMotion, which will assign the animations stored in {@link
   * #animate(Animation...)} to {@link SparkleAnimationPresenter}. This is the last method to call
   * in order to build a functional ViewPager. Once this is called, a {@link
   * SparkleAnimationPresenter} will be associated to the ViewPager, and the animations will be run
   * when scrolling.
   *
   * @param ids Target View ids.
   */
  public void on(final int... ids) {
    Animation[] anims = new Animation[mAnimations.size()];
    mAnimations.toArray(anims);

    for (int id : ids) {
      mPresenter.addAnimation(id, anims);
    }

    mAnimations.clear();

    ViewPager viewPager;
    if (mViewPagerLayout != null && mViewPager == null) {
      viewPager = mViewPagerLayout.getViewPager();
    } else {
      viewPager = mViewPager;
    }

    if (viewPager == null) {
      throw new NullPointerException("ViewPager cannot be null");
    }

    SparkleMotionCompat.installAnimationPresenter(viewPager, false, mPresenter);
  }