package com.airbnb.lottie.animation.keyframe;

import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.airbnb.lottie.L;
import com.airbnb.lottie.value.Keyframe;
import com.airbnb.lottie.value.LottieValueCallback;

import java.util.ArrayList;
import java.util.List;

/**
 * @param <K> Keyframe type
 * @param <A> Animation type
 */
public abstract class BaseKeyframeAnimation<K, A> {
  public interface AnimationListener {
    void onValueChanged();
  }

  // This is not a Set because we don't want to create an iterator object on every setProgress.
  final List<AnimationListener> listeners = new ArrayList<>(1);
  private boolean isDiscrete = false;

  private final KeyframesWrapper<K> keyframesWrapper;
  protected float progress = 0f;
  @Nullable protected LottieValueCallback<A> valueCallback;

  @Nullable private A cachedGetValue = null;

  private float cachedStartDelayProgress = -1f;
  private float cachedEndProgress = -1f;

  BaseKeyframeAnimation(List<? extends Keyframe<K>> keyframes) {
    keyframesWrapper = wrap(keyframes);
  }

  public void setIsDiscrete() {
    isDiscrete = true;
  }

  public void addUpdateListener(AnimationListener listener) {
    listeners.add(listener);
  }

  public void setProgress(@FloatRange(from = 0f, to = 1f) float progress) {
    if (keyframesWrapper.isEmpty()) {
      return;
    }
    if (progress < getStartDelayProgress()) {
      progress = getStartDelayProgress();
    } else if (progress > getEndProgress()) {
      progress = getEndProgress();
    }

    if (progress == this.progress) {
      return;
    }
    this.progress = progress;
    if (keyframesWrapper.isValueChanged(progress)) {
      notifyListeners();
    }
  }

  public void notifyListeners() {
    for (int i = 0; i < listeners.size(); i++) {
      listeners.get(i).onValueChanged();
    }
  }

  protected Keyframe<K> getCurrentKeyframe() {
    L.beginSection("BaseKeyframeAnimation#getCurrentKeyframe");
    final Keyframe<K> keyframe = keyframesWrapper.getCurrentKeyframe();
    L.endSection("BaseKeyframeAnimation#getCurrentKeyframe");
    return keyframe;
  }

  /**
   * Returns the progress into the current keyframe between 0 and 1. This does not take into account
   * any interpolation that the keyframe may have.
   */
  float getLinearCurrentKeyframeProgress() {
    if (isDiscrete) {
      return 0f;
    }

    Keyframe<K> keyframe = getCurrentKeyframe();
    if (keyframe.isStatic()) {
      return 0f;
    }
    float progressIntoFrame = progress - keyframe.getStartProgress();
    float keyframeProgress = keyframe.getEndProgress() - keyframe.getStartProgress();
    return progressIntoFrame / keyframeProgress;
  }

  /**
   * Takes the value of {@link #getLinearCurrentKeyframeProgress()} and interpolates it with
   * the current keyframe's interpolator.
   */
  protected float getInterpolatedCurrentKeyframeProgress() {
    Keyframe<K> keyframe = getCurrentKeyframe();
    // Keyframe should not be null here but there seems to be a Xiaomi Android 10 specific crash.
    // https://github.com/airbnb/lottie-android/issues/2050
    if (keyframe == null || keyframe.isStatic()) {
      return 0f;
    }
    //noinspection ConstantConditions
    return keyframe.interpolator.getInterpolation(getLinearCurrentKeyframeProgress());
  }

  @FloatRange(from = 0f, to = 1f)
  private float getStartDelayProgress() {
    if (cachedStartDelayProgress == -1f) {
      cachedStartDelayProgress = keyframesWrapper.getStartDelayProgress();
    }
    return cachedStartDelayProgress;
  }

  @FloatRange(from = 0f, to = 1f)
  float getEndProgress() {
    if (cachedEndProgress == -1f) {
      cachedEndProgress = keyframesWrapper.getEndProgress();
    }
    return cachedEndProgress;
  }

  public A getValue() {
    A value;

    float linearProgress = getLinearCurrentKeyframeProgress();
    if (valueCallback == null && keyframesWrapper.isCachedValueEnabled(linearProgress)) {
      return cachedGetValue;
    }
    final Keyframe<K> keyframe = getCurrentKeyframe();

    if (keyframe.xInterpolator != null && keyframe.yInterpolator != null) {
      float xProgress = keyframe.xInterpolator.getInterpolation(linearProgress);
      float yProgress = keyframe.yInterpolator.getInterpolation(linearProgress);
      value = getValue(keyframe, linearProgress, xProgress, yProgress);
    } else {
      float progress = getInterpolatedCurrentKeyframeProgress();
      value = getValue(keyframe, progress);
    }

    cachedGetValue = value;
    return value;
  }

  public float getProgress() {
    return progress;
  }

  public void setValueCallback(@Nullable LottieValueCallback<A> valueCallback) {
    if (this.valueCallback != null) {
      this.valueCallback.setAnimation(null);
    }
    this.valueCallback = valueCallback;
    if (valueCallback != null) {
      valueCallback.setAnimation(this);
    }
  }

  /**
   * keyframeProgress will be [0, 1] unless the interpolator has overshoot in which case, this
   * should be able to handle values outside of that range.
   */
  abstract A getValue(Keyframe<K> keyframe, float keyframeProgress);

  /**
   * Similar to {@link #getValue(Keyframe, float)} but used when an animation has separate interpolators for the X and Y axis.
   */
  protected A getValue(Keyframe<K> keyframe, float linearKeyframeProgress, float xKeyframeProgress, float yKeyframeProgress) {
    throw new UnsupportedOperationException("This animation does not support split dimensions!");
  }

  private static <T> KeyframesWrapper<T> wrap(List<? extends Keyframe<T>> keyframes) {
    if (keyframes.isEmpty()) {
      return new EmptyKeyframeWrapper<>();
    }
    if (keyframes.size() == 1) {
      return new SingleKeyframeWrapper<>(keyframes);
    }
    return new KeyframesWrapperImpl<>(keyframes);
  }

  private interface KeyframesWrapper<T> {
    boolean isEmpty();

    boolean isValueChanged(float progress);

    Keyframe<T> getCurrentKeyframe();

    @FloatRange(from = 0f, to = 1f)
    float getStartDelayProgress();

    @FloatRange(from = 0f, to = 1f)
    float getEndProgress();

    boolean isCachedValueEnabled(float progress);
  }

  private static final class EmptyKeyframeWrapper<T> implements KeyframesWrapper<T> {
    @Override
    public boolean isEmpty() {
      return true;
    }

    @Override
    public boolean isValueChanged(float progress) {
      return false;
    }

    @Override
    public Keyframe<T> getCurrentKeyframe() {
      throw new IllegalStateException("not implemented");
    }

    @Override
    public float getStartDelayProgress() {
      return 0f;
    }

    @Override
    public float getEndProgress() {
      return 1f;
    }

    @Override
    public boolean isCachedValueEnabled(float progress) {
      throw new IllegalStateException("not implemented");
    }
  }

  private static final class SingleKeyframeWrapper<T> implements KeyframesWrapper<T> {
    @NonNull
    private final Keyframe<T> keyframe;
    private float cachedInterpolatedProgress = -1f;

    SingleKeyframeWrapper(List<? extends Keyframe<T>> keyframes) {
      this.keyframe = keyframes.get(0);
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean isValueChanged(float progress) {
      return !keyframe.isStatic();
    }

    @Override
    public Keyframe<T> getCurrentKeyframe() {
      return keyframe;
    }

    @Override
    public float getStartDelayProgress() {
      return keyframe.getStartProgress();
    }

    @Override
    public float getEndProgress() {
      return keyframe.getEndProgress();
    }

    @Override
    public boolean isCachedValueEnabled(float progress) {
      if (cachedInterpolatedProgress == progress) {
        return true;
      }
      cachedInterpolatedProgress = progress;
      return false;
    }
  }

  private static final class KeyframesWrapperImpl<T> implements KeyframesWrapper<T> {
    private final List<? extends Keyframe<T>> keyframes;
    @NonNull
    private Keyframe<T> currentKeyframe;
    private Keyframe<T> cachedCurrentKeyframe = null;
    private float cachedInterpolatedProgress = -1f;

    KeyframesWrapperImpl(List<? extends Keyframe<T>> keyframes) {
      this.keyframes = keyframes;
      currentKeyframe = findKeyframe(0);
    }

    @Override
    public boolean isEmpty() {
      return false;
    }

    @Override
    public boolean isValueChanged(float progress) {
      if (currentKeyframe.containsProgress(progress)) {
        return !currentKeyframe.isStatic();
      }
      currentKeyframe = findKeyframe(progress);
      return true;
    }

    private Keyframe<T> findKeyframe(float progress) {
      Keyframe<T> keyframe = keyframes.get(keyframes.size() - 1);
      if (progress >= keyframe.getStartProgress()) {
        return keyframe;
      }
      for (int i = keyframes.size() - 2; i >= 1; i--) {
        keyframe = keyframes.get(i);
        if (currentKeyframe == keyframe) {
          continue;
        }
        if (keyframe.containsProgress(progress)) {
          return keyframe;
        }
      }
      return keyframes.get(0);
    }

    @Override
    @NonNull
    public Keyframe<T> getCurrentKeyframe() {
      return currentKeyframe;
    }

    @Override
    public float getStartDelayProgress() {
      return keyframes.get(0).getStartProgress();
    }

    @Override
    public float getEndProgress() {
      return keyframes.get(keyframes.size() - 1).getEndProgress();
    }

    @Override
    public boolean isCachedValueEnabled(float progress) {
      if (cachedCurrentKeyframe == currentKeyframe
          && cachedInterpolatedProgress == progress) {
        return true;
      }
      cachedCurrentKeyframe = currentKeyframe;
      cachedInterpolatedProgress = progress;
      return false;
    }
  }
}
