package com.airbnb.lottie.utils;

import android.graphics.Path;
import android.graphics.PointF;
import androidx.annotation.FloatRange;

import com.airbnb.lottie.animation.content.KeyPathElementContent;
import com.airbnb.lottie.model.CubicCurveData;
import com.airbnb.lottie.model.KeyPath;
import com.airbnb.lottie.model.content.ShapeData;

import java.util.List;

public class MiscUtils {
  private static PointF pathFromDataCurrentPoint = new PointF();

  public static PointF addPoints(PointF p1, PointF p2) {
    return new PointF(p1.x + p2.x, p1.y + p2.y);
  }

  public static void getPathFromData(ShapeData shapeData, Path outPath) {
    outPath.reset();
    PointF initialPoint = shapeData.getInitialPoint();
    outPath.moveTo(initialPoint.x, initialPoint.y);
    pathFromDataCurrentPoint.set(initialPoint.x, initialPoint.y);
    for (int i = 0; i < shapeData.getCurves().size(); i++) {
      CubicCurveData curveData = shapeData.getCurves().get(i);
      PointF cp1 = curveData.getControlPoint1();
      PointF cp2 = curveData.getControlPoint2();
      PointF vertex = curveData.getVertex();

      if (cp1.equals(pathFromDataCurrentPoint) && cp2.equals(vertex)) {
        // On some phones like Samsung phones, zero valued control points can cause artifacting.
        // https://github.com/airbnb/lottie-android/issues/275
        //
        // This does its best to add a tiny value to the vertex without affecting the final
        // animation as much as possible.
        // outPath.rMoveTo(0.01f, 0.01f);
        outPath.lineTo(vertex.x, vertex.y);
      } else {
        outPath.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, vertex.x, vertex.y);
      }
      pathFromDataCurrentPoint.set(vertex.x, vertex.y);
    }
    if (shapeData.isClosed()) {
      outPath.close();
    }
  }

  public static float lerp(float a, float b, @FloatRange(from = 0f, to = 1f) float percentage) {
    return a + percentage * (b - a);
  }

  public static double lerp(double a, double b, @FloatRange(from = 0f, to = 1f) double percentage) {
    return a + percentage * (b - a);
  }

  public static int lerp(int a, int b, @FloatRange(from = 0f, to = 1f) float percentage) {
    return (int) (a + percentage * (b - a));
  }

  static int floorMod(float x, float y) {
    return floorMod((int) x, (int) y);
  }

  private static int floorMod(int x, int y) {
    return x - y * floorDiv(x, y);
  }

  private static int floorDiv(int x, int y) {
    int r = x / y;
    boolean sameSign = (x ^ y) >= 0;
    int mod = x % y;
    if (!sameSign && mod != 0) {
      r--;
    }
    return r;
  }

  public static int clamp(int number, int min, int max) {
    return Math.max(min, Math.min(max, number));
  }

  public static float clamp(float number, float min, float max) {
    return Math.max(min, Math.min(max, number));
  }

  public static double clamp(double number, double min, double max) {
    return Math.max(min, Math.min(max, number));
  }

  public static boolean contains(float number, float rangeMin, float rangeMax) {
    return number >= rangeMin && number <= rangeMax;
  }

  /**
   * Helper method for any {@link KeyPathElementContent} that will check if the content
   * fully matches the keypath then will add itself as the final key, resolve it, and add
   * it to the accumulator list.
   *
   * Any {@link KeyPathElementContent} should call through to this as its implementation of
   * {@link KeyPathElementContent#resolveKeyPath(KeyPath, int, List, KeyPath)}.
   */
  public static void resolveKeyPath(KeyPath keyPath, int depth, List<KeyPath> accumulator,
      KeyPath currentPartialKeyPath, KeyPathElementContent content) {
    if (keyPath.fullyResolvesTo(content.getName(), depth)) {
      currentPartialKeyPath = currentPartialKeyPath.addKey(content.getName());
      accumulator.add(currentPartialKeyPath.resolve(content));
    }
  }
}
