package com.airbnb.lottie.animation.content;

import android.annotation.TargetApi;
import android.graphics.Path;
import android.os.Build;

import com.airbnb.lottie.model.content.MergePaths;

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

@TargetApi(Build.VERSION_CODES.KITKAT)
public class MergePathsContent implements PathContent, GreedyContent {
  private final Path firstPath = new Path();
  private final Path remainderPath = new Path();
  private final Path path = new Path();

  private final String name;
  private final List<PathContent> pathContents = new ArrayList<>();
  private final MergePaths mergePaths;

  public MergePathsContent(MergePaths mergePaths) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
      throw new IllegalStateException("Merge paths are not supported pre-KitKat.");
    }
    name = mergePaths.getName();
    this.mergePaths = mergePaths;
  }

  @Override public void absorbContent(ListIterator<Content> contents) {
    // Fast forward the iterator until after this content.
    //noinspection StatementWithEmptyBody
    while (contents.hasPrevious() && contents.previous() != this) {
    }
    while (contents.hasPrevious()) {
      Content content = contents.previous();
      if (content instanceof PathContent) {
        pathContents.add((PathContent) content);
        contents.remove();
      }
    }
  }

  @Override public void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {
    for (int i = 0; i < pathContents.size(); i++) {
      pathContents.get(i).setContents(contentsBefore, contentsAfter);
    }
  }

  @Override public Path getPath() {
    path.reset();

    if (mergePaths.isHidden()) {
      return path;
    }

    switch (mergePaths.getMode()) {
      case MERGE:
        addPaths();
        break;
      case ADD:
        opFirstPathWithRest(Path.Op.UNION);
        break;
      case SUBTRACT:
        opFirstPathWithRest(Path.Op.REVERSE_DIFFERENCE);
        break;
      case INTERSECT:
        opFirstPathWithRest(Path.Op.INTERSECT);
        break;
      case EXCLUDE_INTERSECTIONS:
        opFirstPathWithRest(Path.Op.XOR);
        break;
    }

    return path;
  }

  @Override public String getName() {
    return name;
  }

  private void addPaths() {
    for (int i = 0; i < pathContents.size(); i++) {
      path.addPath(pathContents.get(i).getPath());
    }
  }

  @TargetApi(Build.VERSION_CODES.KITKAT)
  private void opFirstPathWithRest(Path.Op op) {
    remainderPath.reset();
    firstPath.reset();

    for (int i = pathContents.size() - 1; i >= 1; i--) {
      PathContent content = pathContents.get(i);

      if (content instanceof ContentGroup) {
        List<PathContent> pathList = ((ContentGroup) content).getPathList();
        for (int j = pathList.size() - 1; j >= 0; j--) {
          Path path = pathList.get(j).getPath();
          path.transform(((ContentGroup) content).getTransformationMatrix());
          this.remainderPath.addPath(path);
        }
      } else {
        remainderPath.addPath(content.getPath());
      }
    }

    PathContent lastContent = pathContents.get(0);
    if (lastContent instanceof ContentGroup) {
      List<PathContent> pathList = ((ContentGroup) lastContent).getPathList();
      for (int j = 0; j < pathList.size(); j++) {
        Path path = pathList.get(j).getPath();
        path.transform(((ContentGroup) lastContent).getTransformationMatrix());
        this.firstPath.addPath(path);
      }
    } else {
      firstPath.set(lastContent.getPath());
    }

    path.op(firstPath, remainderPath, op);
  }
}
