package com.stardust.autojs.core.image;

import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;

import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.concurrent.VolatileBox;
import com.stardust.util.ScreenMetrics;

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Stardust on 2017/5/18.
 */

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public class ColorFinder {

    public static Point findColorEquals(ImageWrapper imageWrapper, int color) {
        return findColorEquals(imageWrapper, color, null);
    }

    public static Point findColorEquals(ImageWrapper imageWrapper, int color, Rect region) {
        return findColor(imageWrapper, color, 0, region);
    }

    public static Point findColor(ImageWrapper imageWrapper, int color, int threshold) {
        return findColor(imageWrapper, color, threshold, null);
    }

    public static Point findColor(ImageWrapper imageWrapper, int color, int threshold, Rect region) {
        Point[] points = findAllColors(imageWrapper, color, threshold, region);
        if (points.length == 0) {
            return null;
        }
        return points[0];
    }

    public static Point[] findAllColors(ImageWrapper image, int color, int threshold, Rect rect) {
        Mat bi = new Mat();
        Scalar lowerBound = new Scalar(Color.red(color) - threshold, Color.green(color) - threshold,
                Color.blue(color) - threshold, 255);
        Scalar upperBound = new Scalar(Color.red(color) + threshold, Color.green(color) + threshold,
                Color.blue(color) + threshold, 255);
        if (rect != null) {
            Core.inRange(new Mat(image.getMat(), rect), lowerBound, upperBound, bi);
        } else {
            Core.inRange(image.getMat(), lowerBound, upperBound, bi);
        }
        Mat nonZeroPos = new Mat();
        Core.findNonZero(bi, nonZeroPos);
        if (nonZeroPos.rows() == 0 || nonZeroPos.cols() == 0) {
            return new Point[0];
        }
        Point[] points = new MatOfPoint(nonZeroPos).toArray();
        if (rect != null) {
            for (int i = 0; i < points.length; i++) {
                points[i].x += rect.x;
                points[i].y += rect.y;
            }
        }
        return points;
    }

}