package com.epson.cameracopy.device;

import android.util.Pair;

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

import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

public class PaperContourDetector {
    private static final double DETECT_AREA_RATIO = 0.8d;

    public static Pair<Point[], Boolean> detectPaperContour(Mat mat) {
        List<MatOfPoint> findPaperContourCandidate = findPaperContourCandidate(mat);
        if (findPaperContourCandidate.size() <= 0) {
            return null;
        }
        return findPaperRect(mat, findMax(findPaperContourCandidate));
    }

    public static List<MatOfPoint> findPaperContourCandidate(Mat mat) {
        Mat mat2 = new Mat();
        Imgproc.Canny(mat, mat2, 1.0d, 120.0d);
        Mat mat3 = new Mat();
        Imgproc.morphologyEx(mat2, mat2, 4, mat3, new Point(-1.0d, -1.0d), 1);
        mat3.release();
        ArrayList arrayList = new ArrayList();
        Mat mat4 = new Mat();
        Imgproc.findContours(mat2, arrayList, mat4, 1, 4);
        mat4.release();
        mat2.release();
        return arrayList;
    }

    private static MatOfPoint findMax(List<MatOfPoint> list) {
        double d = 0.0d;
        MatOfPoint matOfPoint = null;
        for (MatOfPoint next : list) {
            if (next.cols() * next.rows() >= 4) {
                double contourArea = Imgproc.contourArea(next);
                if (contourArea > d) {
                    matOfPoint = next;
                    d = contourArea;
                }
            }
        }
        return matOfPoint;
    }

    private static Pair<Point[], Boolean> findPaperRect(Mat mat, MatOfPoint matOfPoint) {
        boolean z;
        if (matOfPoint == null || matOfPoint.rows() < 1 || matOfPoint.cols() < 1) {
            return null;
        }
        MatOfPoint2f matOfPoint2f = new MatOfPoint2f(matOfPoint.toArray());
        MatOfPoint2f matOfPoint2f2 = new MatOfPoint2f();
        for (int i = 300; i >= 100; i -= 100) {
            Imgproc.approxPolyDP(matOfPoint2f, matOfPoint2f2, i, true);
            if (matOfPoint2f2.rows() * matOfPoint2f2.cols() >= 4) {
                break;
            }
        }
        matOfPoint2f.release();
        Point[] array = matOfPoint2f2.toArray();
        MatOfPoint matOfPoint2 = new MatOfPoint(array);
        if (array.length == 4) {
            matOfPoint2f2.release();
            boolean isContourConvex = Imgproc.isContourConvex(matOfPoint2);
            matOfPoint2.release();
            if (!isContourConvex) {
                return null;
            }
            Size size = mat.size();
            double d = size.width;
            double d2 = size.height;
            int length = array.length;
            double d3 = 0.0d;
            double d4 = d2;
            double d5 = 0.0d;
            double d6 = d;
            int i2 = 0;
            while (true) {
                if (i2 >= length) {
                    z = true;
                    break;
                }
                Point point = array[i2];
                int i3 = i2;
                if (size.width <= 1.0d && size.height <= 1.0d) {
                    z = false;
                    break;
                }
                if (d6 > point.f432x) {
                    d6 = point.f432x;
                }
                if (d3 < point.f432x) {
                    d3 = point.f432x;
                }
                if (d4 > point.f433y) {
                    d4 = point.f433y;
                }
                if (d5 < point.f433y) {
                    d5 = point.f433y;
                }
                i2 = i3 + 1;
            }
            if (z) {
                z = (d3 - d6) / size.width >= DETECT_AREA_RATIO || (d5 - d4) / size.height >= DETECT_AREA_RATIO;
            }
            return new Pair<>(array, Boolean.valueOf(z));
        }
        int length2 = array.length;
        return null;
    }
}
