package com.airbnb.lottie.model.content;

import android.graphics.PointF;
import android.support.annotation.FloatRange;
import android.util.JsonReader;
import android.util.JsonToken;

import com.airbnb.lottie.model.CubicCurveData;
import com.airbnb.lottie.model.animatable.AnimatableValue;
import com.airbnb.lottie.utils.JsonUtils;
import com.airbnb.lottie.utils.MiscUtils;

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

public class ShapeData {
  private final List<CubicCurveData> curves = new ArrayList<>();
  private PointF initialPoint;
  private boolean closed;

  private ShapeData(PointF initialPoint, boolean closed, List<CubicCurveData> curves) {
    this.initialPoint = initialPoint;
    this.closed = closed;
    this.curves.addAll(curves);
  }

  public ShapeData() {
  }

  private void setInitialPoint(float x, float y) {
    if (initialPoint == null) {
      initialPoint = new PointF();
    }
    initialPoint.set(x, y);
  }

  public PointF getInitialPoint() {
    return initialPoint;
  }

  public boolean isClosed() {
    return closed;
  }

  public List<CubicCurveData> getCurves() {
    return curves;
  }

  public void interpolateBetween(ShapeData shapeData1, ShapeData shapeData2,
      @FloatRange(from = 0f, to = 1f) float percentage) {
    if (initialPoint == null) {
      initialPoint = new PointF();
    }
    closed = shapeData1.isClosed() || shapeData2.isClosed();

    if (!curves.isEmpty() && curves.size() != shapeData1.getCurves().size()
        && curves.size() != shapeData2.getCurves().size()) {
      throw new IllegalStateException("Curves must have the same number of control points. This: "
          + getCurves().size()
          + "\tShape 1: " + shapeData1.getCurves().size() + "\tShape 2: "
          + shapeData2.getCurves().size());
    } else if (curves.isEmpty()) {
      for (int i = shapeData1.getCurves().size() - 1; i >= 0; i--) {
        curves.add(new CubicCurveData());
      }
    }

    PointF initialPoint1 = shapeData1.getInitialPoint();
    PointF initialPoint2 = shapeData2.getInitialPoint();

    setInitialPoint(MiscUtils.lerp(initialPoint1.x, initialPoint2.x, percentage),
        MiscUtils.lerp(initialPoint1.y, initialPoint2.y, percentage));

    for (int i = curves.size() - 1; i >= 0; i--) {
      CubicCurveData curve1 = shapeData1.getCurves().get(i);
      CubicCurveData curve2 = shapeData2.getCurves().get(i);

      PointF cp11 = curve1.getControlPoint1();
      PointF cp21 = curve1.getControlPoint2();
      PointF vertex1 = curve1.getVertex();

      PointF cp12 = curve2.getControlPoint1();
      PointF cp22 = curve2.getControlPoint2();
      PointF vertex2 = curve2.getVertex();

      curves.get(i).setControlPoint1(
          MiscUtils.lerp(cp11.x, cp12.x, percentage), MiscUtils.lerp(cp11.y, cp12.y,
              percentage));
      curves.get(i).setControlPoint2(
          MiscUtils.lerp(cp21.x, cp22.x, percentage), MiscUtils.lerp(cp21.y, cp22.y,
              percentage));
      curves.get(i).setVertex(
          MiscUtils.lerp(vertex1.x, vertex2.x, percentage), MiscUtils.lerp(vertex1.y, vertex2.y,
              percentage));
    }
  }

  @Override public String toString() {
    return "ShapeData{" + "numCurves=" + curves.size() +
        "closed=" + closed +
        '}';
  }

  public static class Factory implements AnimatableValue.Factory<ShapeData> {
    public static final ShapeData.Factory INSTANCE = new Factory();

    private Factory() {
    }

    @Override public ShapeData valueFromObject(JsonReader reader, float scale) throws IOException {
      // Sometimes the points data is in a array of length 1. Sometimes the data is at the top
      // level.
      if (reader.peek() == JsonToken.BEGIN_ARRAY) {
        reader.beginArray();
      }

      boolean closed = false;
      List<PointF> pointsArray = null;
      List<PointF> inTangents = null;
      List<PointF> outTangents = null;
      reader.beginObject();

      while (reader.hasNext()) {
        switch (reader.nextName()) {
          case "c":
            closed = reader.nextBoolean();
            break;
          case "v":
            pointsArray =  JsonUtils.jsonToPoints(reader, scale);
            break;
          case "i":
            inTangents =  JsonUtils.jsonToPoints(reader, scale);
            break;
          case "o":
            outTangents =  JsonUtils.jsonToPoints(reader, scale);
            break;
        }
      }

      reader.endObject();

      if (reader.peek() == JsonToken.END_ARRAY) {
        reader.endArray();
      }

      if (pointsArray == null || inTangents == null || outTangents == null) {
        throw new IllegalArgumentException("Shape data was missing information.");
      }

      if (pointsArray.isEmpty()) {
        return new ShapeData(new PointF(), false, Collections.<CubicCurveData>emptyList());
      }

      int length = pointsArray.size();
      PointF vertex = pointsArray.get(0);
      PointF initialPoint = vertex;
      List<CubicCurveData> curves = new ArrayList<>(length);

      for (int i = 1; i < length; i++) {
        vertex = pointsArray.get(i);
        PointF previousVertex = pointsArray.get(i - 1);
        PointF cp1 = outTangents.get(i - 1);
        PointF cp2 = inTangents.get(i);
        PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
        PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);
        curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
      }

      if (closed) {
        vertex = pointsArray.get(0);
        PointF previousVertex = pointsArray.get(length - 1);
        PointF cp1 = outTangents.get(length - 1);
        PointF cp2 = inTangents.get(0);

        PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
        PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);

        curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
      }
      return new ShapeData(initialPoint, closed, curves);
    }
  }
}
