package com.airbnb.lottie.parser;

import android.graphics.Color;

import com.airbnb.lottie.model.content.GradientColor;
import com.airbnb.lottie.parser.moshi.JsonReader;
import com.airbnb.lottie.utils.MiscUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GradientColorParser implements com.airbnb.lottie.parser.ValueParser<GradientColor> {
  /**
   * The number of colors if it exists in the json or -1 if it doesn't (legacy bodymovin)
   */
  private int colorPoints;

  public GradientColorParser(int colorPoints) {
    this.colorPoints = colorPoints;
  }

  /**
   * Both the color stops and opacity stops are in the same array.
   * There are {@link #colorPoints} colors sequentially as:
   * [
   * ...,
   * position,
   * red,
   * green,
   * blue,
   * ...
   * ]
   * <p>
   * The remainder of the array is the opacity stops sequentially as:
   * [
   * ...,
   * position,
   * opacity,
   * ...
   * ]
   */
  @Override
  public GradientColor parse(JsonReader reader, float scale)
      throws IOException {
    List<Float> array = new ArrayList<>();
    // The array was started by Keyframe because it thought that this may be an array of keyframes
    // but peek returned a number so it considered it a static array of numbers.
    boolean isArray = reader.peek() == JsonReader.Token.BEGIN_ARRAY;
    if (isArray) {
      reader.beginArray();
    }
    while (reader.hasNext()) {
      array.add((float) reader.nextDouble());
    }
    if (array.size() == 4 && array.get(0) == 1f) {
      // If a gradient color only contains one color at position 1, add a second stop with the same
      // color at position 0. Android's LinearGradient shader requires at least two colors.
      // https://github.com/airbnb/lottie-android/issues/1967
      array.set(0, 0f);
      array.add(1f);
      array.add(array.get(1));
      array.add(array.get(2));
      array.add(array.get(3));
      colorPoints = 2;
    }
    if (isArray) {
      reader.endArray();
    }
    if (colorPoints == -1) {
      colorPoints = array.size() / 4;
    }

    float[] positions = new float[colorPoints];
    int[] colors = new int[colorPoints];

    int r = 0;
    int g = 0;
    for (int i = 0; i < colorPoints * 4; i++) {
      int colorIndex = i / 4;
      double value = array.get(i);
      switch (i % 4) {
        case 0:
          // Positions should monotonically increase. If they don't, it can cause rendering problems on some phones.
          // https://github.com/airbnb/lottie-android/issues/1675
          if (colorIndex > 0 && positions[colorIndex - 1] >= (float) value) {
            positions[colorIndex] = (float) value + 0.01f;
          } else {
            positions[colorIndex] = (float) value;
          }
          break;
        case 1:
          r = (int) (value * 255);
          break;
        case 2:
          g = (int) (value * 255);
          break;
        case 3:
          int b = (int) (value * 255);
          colors[colorIndex] = Color.argb(255, r, g, b);
          break;
      }
    }

    GradientColor gradientColor = new GradientColor(positions, colors);
    gradientColor = addOpacityStopsToGradientIfNeeded(gradientColor, array);
    return gradientColor;
  }

  /**
   * This cheats a little bit.
   * Opacity stops can be at arbitrary intervals independent of color stops.
   * This uses the existing color stops and modifies the opacity at each existing color stop
   * based on what the opacity would be.
   * <p>
   * This should be a good approximation is nearly all cases. However, if there are many more
   * opacity stops than color stops, information will be lost.
   */
  private GradientColor addOpacityStopsToGradientIfNeeded(GradientColor gradientColor, List<Float> array) {
    int startIndex = colorPoints * 4;
    if (array.size() <= startIndex) {
      return gradientColor;
    }

    // When there are opacity stops, we create a merged list of color stops and opacity stops.
    // For a given color stop, we linearly interpolate the opacity for the two opacity stops around it.
    // For a given opacity stop, we linearly interpolate the color for the two color stops around it.
    float[] colorStopPositions = gradientColor.getPositions();
    int[] colorStopColors = gradientColor.getColors();

    int opacityStops = (array.size() - startIndex) / 2;
    float[] opacityStopPositions = new float[opacityStops];
    float[] opacityStopOpacities = new float[opacityStops];

    for (int i = startIndex, j = 0; i < array.size(); i++) {
      if (i % 2 == 0) {
        opacityStopPositions[j] = array.get(i);
      } else {
        opacityStopOpacities[j] = array.get(i);
        j++;
      }
    }

    // Pre-SKIA (Oreo) devices render artifacts when there is two stops in the same position.
    // As a result, we have to de-dupe the merge color and opacity stop positions.
    float[] newPositions = mergeUniqueElements(gradientColor.getPositions(), opacityStopPositions);
    int newColorPoints = newPositions.length;
    int[] newColors = new int[newColorPoints];

    for (int i = 0; i < newColorPoints; i++) {
      float position = newPositions[i];
      int colorStopIndex = Arrays.binarySearch(colorStopPositions, position);
      int opacityIndex = Arrays.binarySearch(opacityStopPositions, position);
      if (colorStopIndex < 0 || opacityIndex > 0) {
        // This is a stop derived from an opacity stop.
        if (opacityIndex < 0) {
          // The formula here is derived from the return value for binarySearch. When an item isn't found, it returns -insertionPoint - 1.
          opacityIndex = -(opacityIndex + 1);
        }
        newColors[i] = getColorInBetweenColorStops(position, opacityStopOpacities[opacityIndex], colorStopPositions, colorStopColors);
      } else {
        // This os a step derived from a color stop.
        newColors[i] = getColorInBetweenOpacityStops(position, colorStopColors[colorStopIndex], opacityStopPositions, opacityStopOpacities);
      }
    }
    return new GradientColor(newPositions, newColors);
  }

  private int getColorInBetweenColorStops(float position, float opacity, float[] colorStopPositions, int[] colorStopColors) {
    if (colorStopColors.length < 2 || position == colorStopPositions[0]) {
      return colorStopColors[0];
    }
    for (int i = 1; i < colorStopPositions.length; i++) {
      float colorStopPosition = colorStopPositions[i];
      if (colorStopPosition < position && i != colorStopPositions.length - 1) {
        continue;
      }
      // We found the position in which position is between i - 1 and i.
      float distanceBetweenColors = colorStopPositions[i] - colorStopPositions[i - 1];
      float distanceToLowerColor = position - colorStopPositions[i - 1];
      float percentage = distanceToLowerColor / distanceBetweenColors;
      int upperColor = colorStopColors[i];
      int lowerColor = colorStopColors[i - 1];
      int a = (int) (opacity * 255);
      int r = MiscUtils.lerp(Color.red(lowerColor), Color.red(upperColor), percentage);
      int g = MiscUtils.lerp(Color.green(lowerColor), Color.green(upperColor), percentage);
      int b = MiscUtils.lerp(Color.blue(lowerColor), Color.blue(upperColor), percentage);
      return Color.argb(a, r, g, b);
    }
    throw new IllegalArgumentException("Unreachable code.");
  }

  private int getColorInBetweenOpacityStops(float position, int color, float[] opacityStopPositions, float[] opacityStopOpacities) {
    if (opacityStopOpacities.length < 2 || position <= opacityStopPositions[0]) {
      int a = (int) (opacityStopOpacities[0] * 255);
      int r = Color.red(color);
      int g = Color.green(color);
      int b = Color.blue(color);
      return Color.argb(a, r, g, b);
    }
    for (int i = 1; i < opacityStopPositions.length; i++) {
      float opacityStopPosition = opacityStopPositions[i];
      if (opacityStopPosition < position && i != opacityStopPositions.length - 1) {
        continue;
      }
      final int a;
      if (opacityStopPosition <= position) {
        a = (int) (opacityStopOpacities[i] * 255);
      } else {
        // We found the position in which position in between i - 1 and i.
        float distanceBetweenOpacities = opacityStopPositions[i] - opacityStopPositions[i - 1];
        float distanceToLowerOpacity = position - opacityStopPositions[i - 1];
        float percentage = distanceToLowerOpacity / distanceBetweenOpacities;
        a = (int) (MiscUtils.lerp(opacityStopOpacities[i - 1], opacityStopOpacities[i], percentage) * 255);
      }
      int r = Color.red(color);
      int g = Color.green(color);
      int b = Color.blue(color);
      return Color.argb(a, r, g, b);
    }
    throw new IllegalArgumentException("Unreachable code.");
  }

  /**
   * Takes two sorted float arrays and merges their elements while removing duplicates.
   */
  protected static float[] mergeUniqueElements(float[] arrayA, float[] arrayB) {
    if (arrayA.length == 0) {
      return arrayB;
    } else if (arrayB.length == 0) {
      return arrayA;
    }

    int aIndex = 0;
    int bIndex = 0;
    int mergedIndex = 0;
    int numDuplicates = 0;
    // This will be the merged list but may be longer than what is needed if there are duplicates.
    // If there are, the 0 elements at the end need to be truncated.
    float[] mergedNotTruncated = new float[arrayA.length + arrayB.length];
    for (int i = 0; i < mergedNotTruncated.length; i++) {
      final float a;
      if (aIndex < arrayA.length) {
        a = arrayA[aIndex];
      } else {
        a = Float.NaN;
      }

      final float b;
      if (bIndex < arrayB.length) {
        b = arrayB[bIndex];
      } else {
        b = Float.NaN;
      }

      if (Float.isNaN(b) || a < b) {
        mergedNotTruncated[mergedIndex++] = a;
        aIndex++;
      } else if (Float.isNaN(a) || b < a) {
        mergedNotTruncated[mergedIndex++] = b;
        bIndex++;
      } else {
        mergedNotTruncated[mergedIndex++] = a;
        aIndex++;
        bIndex++;
        numDuplicates++;
      }
    }

    if (numDuplicates == 0) {
      return mergedNotTruncated;
    }


    float[] merged = new float[mergedNotTruncated.length - numDuplicates];
    System.arraycopy(mergedNotTruncated, 0, merged, 0, merged.length);
    return merged;
  }
}