package com.airbnb.lottie.parser;

import android.graphics.PointF;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;
import androidx.collection.SparseArrayCompat;
import androidx.core.view.animation.PathInterpolatorCompat;

import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.parser.moshi.JsonReader;
import com.airbnb.lottie.utils.MiscUtils;
import com.airbnb.lottie.utils.Utils;
import com.airbnb.lottie.value.Keyframe;

import java.io.IOException;
import java.lang.ref.WeakReference;

class KeyframeParser {
  /**
   * Some animations get exported with insane cp values in the tens of thousands.
   * PathInterpolator fails to create the interpolator in those cases and hangs.
   * Clamping the cp helps prevent that.
   */
  private static final float MAX_CP_VALUE = 100;
  private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
  private static SparseArrayCompat<WeakReference<Interpolator>> pathInterpolatorCache;

  static JsonReader.Options NAMES = JsonReader.Options.of(
      "t",  // 1
      "s",  // 2
      "e",  // 3
      "o",  // 4
      "i",  // 5
      "h",  // 6
      "to", // 7
      "ti"  // 8
  );
  static JsonReader.Options INTERPOLATOR_NAMES = JsonReader.Options.of(
      "x",  // 1
      "y"   // 2
  );

  // https://github.com/airbnb/lottie-android/issues/464
  private static SparseArrayCompat<WeakReference<Interpolator>> pathInterpolatorCache() {
    if (pathInterpolatorCache == null) {
      pathInterpolatorCache = new SparseArrayCompat<>();
    }
    return pathInterpolatorCache;
  }

  @Nullable
  private static WeakReference<Interpolator> getInterpolator(int hash) {
    // This must be synchronized because get and put isn't thread safe because
    // SparseArrayCompat has to create new sized arrays sometimes.
    synchronized (KeyframeParser.class) {
      return pathInterpolatorCache().get(hash);
    }
  }

  private static void putInterpolator(int hash, WeakReference<Interpolator> interpolator) {
    // This must be synchronized because get and put isn't thread safe because
    // SparseArrayCompat has to create new sized arrays sometimes.
    synchronized (KeyframeParser.class) {
      pathInterpolatorCache.put(hash, interpolator);
    }
  }

  /**
   * @param multiDimensional When true, the keyframe interpolators can be independent for the X and Y axis.
   */
  static <T> Keyframe<T> parse(JsonReader reader, LottieComposition composition,
      float scale, ValueParser<T> valueParser, boolean animated, boolean multiDimensional) throws IOException {

    if (animated && multiDimensional) {
      return parseMultiDimensionalKeyframe(composition, reader, scale, valueParser);
    } else if (animated) {
      return parseKeyframe(composition, reader, scale, valueParser);
    } else {
      return parseStaticValue(reader, scale, valueParser);
    }
  }

  /**
   * beginObject will already be called on the keyframe so it can be differentiated with
   * a non animated value.
   */
  private static <T> Keyframe<T> parseKeyframe(LottieComposition composition, JsonReader reader,
      float scale, ValueParser<T> valueParser) throws IOException {
    PointF cp1 = null;
    PointF cp2 = null;

    float startFrame = 0;
    T startValue = null;
    T endValue = null;
    boolean hold = false;
    Interpolator interpolator = null;

    // Only used by PathKeyframe
    PointF pathCp1 = null;
    PointF pathCp2 = null;

    reader.beginObject();
    while (reader.hasNext()) {
      switch (reader.selectName(NAMES)) {
        case 0: // t
          startFrame = reader.nextFloat();
          break;
        case 1: // s
          startValue = valueParser.parse(reader, scale);
          break;
        case 2: // e
          endValue = valueParser.parse(reader, scale);
          break;
        case 3: // o
          cp1 = JsonUtils.jsonToPoint(reader, 1f);
          break;
        case 4: // i
          cp2 = JsonUtils.jsonToPoint(reader, 1f);
          break;
        case 5: // h
          hold = reader.nextInt() == 1;
          break;
        case 6: // to
          pathCp1 = JsonUtils.jsonToPoint(reader, scale);
          break;
        case 7: // ti
          pathCp2 = JsonUtils.jsonToPoint(reader, scale);
          break;
        default:
          reader.skipValue();
      }
    }
    reader.endObject();

    if (hold) {
      endValue = startValue;
      // TODO: create a HoldInterpolator so progress changes don't invalidate.
      interpolator = LINEAR_INTERPOLATOR;
    } else if (cp1 != null && cp2 != null) {
      interpolator = interpolatorFor(cp1, cp2);
    } else {
      interpolator = LINEAR_INTERPOLATOR;
    }

    Keyframe<T> keyframe = new Keyframe<>(composition, startValue, endValue, interpolator, startFrame, null);

    keyframe.pathCp1 = pathCp1;
    keyframe.pathCp2 = pathCp2;
    return keyframe;
  }

  private static <T> Keyframe<T> parseMultiDimensionalKeyframe(LottieComposition composition, JsonReader reader,
      float scale, ValueParser<T> valueParser) throws IOException {
    PointF cp1 = null;
    PointF cp2 = null;

    PointF xCp1 = null;
    PointF xCp2 = null;
    PointF yCp1 = null;
    PointF yCp2 = null;

    float startFrame = 0;
    T startValue = null;
    T endValue = null;
    boolean hold = false;
    Interpolator interpolator = null;
    Interpolator xInterpolator = null;
    Interpolator yInterpolator = null;

    // Only used by PathKeyframe
    PointF pathCp1 = null;
    PointF pathCp2 = null;

    reader.beginObject();
    while (reader.hasNext()) {
      switch (reader.selectName(NAMES)) {
        case 0: // t
          startFrame = reader.nextFloat();
          break;
        case 1: // s
          startValue = valueParser.parse(reader, scale);
          break;
        case 2: // e
          endValue = valueParser.parse(reader, scale);
          break;
        case 3: // o
          if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) {
            reader.beginObject();
            float xCp1x = 0f;
            float xCp1y = 0f;
            float yCp1x = 0f;
            float yCp1y = 0f;
            while (reader.hasNext()) {
              switch (reader.selectName(INTERPOLATOR_NAMES)) {
                case 0: // x
                  if (reader.peek() == JsonReader.Token.NUMBER) {
                    xCp1x = reader.nextFloat();
                    yCp1x = xCp1x;
                  } else {
                    reader.beginArray();
                    xCp1x = reader.nextFloat();
                    if (reader.peek() == JsonReader.Token.NUMBER) {
                      yCp1x = reader.nextFloat();
                    } else {
                      yCp1x = xCp1x;
                    }
                    reader.endArray();
                  }
                  break;
                case 1: // y
                  if (reader.peek() == JsonReader.Token.NUMBER) {
                    xCp1y = reader.nextFloat();
                    yCp1y = xCp1y;
                  } else {
                    reader.beginArray();
                    xCp1y = reader.nextFloat();
                    if (reader.peek() == JsonReader.Token.NUMBER) {
                      yCp1y = reader.nextFloat();
                    } else {
                      yCp1y = xCp1y;
                    }
                    reader.endArray();
                  }
                  break;
                default:
                  reader.skipValue();
              }
            }
            xCp1 = new PointF(xCp1x, xCp1y);
            yCp1 = new PointF(yCp1x, yCp1y);
            reader.endObject();
          } else {
            cp1 = JsonUtils.jsonToPoint(reader, scale);
          }
          break;
        case 4: // i
          if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) {
            reader.beginObject();
            float xCp2x = 0f;
            float xCp2y = 0f;
            float yCp2x = 0f;
            float yCp2y = 0f;
            while (reader.hasNext()) {
              switch (reader.selectName(INTERPOLATOR_NAMES)) {
                case 0: // x
                  if (reader.peek() == JsonReader.Token.NUMBER) {
                    xCp2x = reader.nextFloat();
                    yCp2x = xCp2x;
                  } else {
                    reader.beginArray();
                    xCp2x = reader.nextFloat();
                    if (reader.peek() == JsonReader.Token.NUMBER) {
                      yCp2x = reader.nextFloat();
                    } else {
                      yCp2x = xCp2x;
                    }
                    reader.endArray();
                  }
                  break;
                case 1: // y
                  if (reader.peek() == JsonReader.Token.NUMBER) {
                    xCp2y = reader.nextFloat();
                    yCp2y = xCp2y;
                  } else {
                    reader.beginArray();
                    xCp2y = reader.nextFloat();
                    if (reader.peek() == JsonReader.Token.NUMBER) {
                      yCp2y = reader.nextFloat();
                    } else {
                      yCp2y = xCp2y;
                    }
                    reader.endArray();
                  }
                  break;
                default:
                  reader.skipValue();
              }
            }
            xCp2 = new PointF(xCp2x, xCp2y);
            yCp2 = new PointF(yCp2x, yCp2y);
            reader.endObject();
          } else {
            cp2 = JsonUtils.jsonToPoint(reader, scale);
          }
          break;
        case 5: // h
          hold = reader.nextInt() == 1;
          break;
        case 6: // to
          pathCp1 = JsonUtils.jsonToPoint(reader, scale);
          break;
        case 7: // ti
          pathCp2 = JsonUtils.jsonToPoint(reader, scale);
          break;
        default:
          reader.skipValue();
      }
    }
    reader.endObject();

    if (hold) {
      endValue = startValue;
      // TODO: create a HoldInterpolator so progress changes don't invalidate.
      interpolator = LINEAR_INTERPOLATOR;
    } else if (cp1 != null && cp2 != null) {
      interpolator = interpolatorFor(cp1, cp2);
    } else if (xCp1 != null && yCp1 != null && xCp2 != null && yCp2 != null) {
      xInterpolator = interpolatorFor(xCp1, xCp2);
      yInterpolator = interpolatorFor(yCp1, yCp2);
    } else {
      interpolator = LINEAR_INTERPOLATOR;
    }

    Keyframe<T> keyframe;
    if (xInterpolator != null && yInterpolator != null) {
      keyframe = new Keyframe<>(composition, startValue, endValue, xInterpolator, yInterpolator, startFrame, null);
    } else {
      keyframe = new Keyframe<>(composition, startValue, endValue, interpolator, startFrame, null);
    }

    keyframe.pathCp1 = pathCp1;
    keyframe.pathCp2 = pathCp2;
    return keyframe;
  }

  private static Interpolator interpolatorFor(PointF cp1, PointF cp2) {
    Interpolator interpolator = null;
    cp1.x = MiscUtils.clamp(cp1.x, -1f, 1f);
    cp1.y = MiscUtils.clamp(cp1.y, -MAX_CP_VALUE, MAX_CP_VALUE);
    cp2.x = MiscUtils.clamp(cp2.x, -1f, 1f);
    cp2.y = MiscUtils.clamp(cp2.y, -MAX_CP_VALUE, MAX_CP_VALUE);
    int hash = Utils.hashFor(cp1.x, cp1.y, cp2.x, cp2.y);
    WeakReference<Interpolator> interpolatorRef = getInterpolator(hash);
    if (interpolatorRef != null) {
      interpolator = interpolatorRef.get();
    }
    if (interpolatorRef == null || interpolator == null) {
      try {
        interpolator = PathInterpolatorCompat.create(cp1.x, cp1.y, cp2.x, cp2.y);
      } catch (IllegalArgumentException e) {
        if ("The Path cannot loop back on itself.".equals(e.getMessage())) {
          // If a control point extends beyond the previous/next point then it will cause the value of the interpolator to no
          // longer monotonously increase. This clips the control point bounds to prevent that from happening.
          // NOTE: this will make the rendered animation behave slightly differently than the original.
          interpolator = PathInterpolatorCompat.create(Math.min(cp1.x, 1f), cp1.y, Math.max(cp2.x, 0f), cp2.y);
        } else {
          // We failed to create the interpolator. Fall back to linear.
          interpolator = new LinearInterpolator();
        }
      }
      try {
        putInterpolator(hash, new WeakReference<>(interpolator));
      } catch (ArrayIndexOutOfBoundsException e) {
        // It is not clear why but SparseArrayCompat sometimes fails with this:
        //     https://github.com/airbnb/lottie-android/issues/452
        // Because this is not a critical operation, we can safely just ignore it.
        // I was unable to repro this to attempt a proper fix.
      }
    }
    return interpolator;
  }

  private static <T> Keyframe<T> parseStaticValue(JsonReader reader,
      float scale, ValueParser<T> valueParser) throws IOException {
    T value = valueParser.parse(reader, scale);
    return new Keyframe<>(value);
  }
}
