package com.knecon.fforesight.service.layoutparser.processor.utils;

import static com.knecon.fforesight.service.layoutparser.processor.utils.GeometricComparators.Y_FIRST_POINT_COMPARATOR;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.knecon.fforesight.service.layoutparser.processor.model.table.Ruling;

public class RectangularIntersectionFinder {

    public static List<Rectangle2D> find(List<Ruling> horizontalRulingLines, List<Ruling> verticalRulingLines) {

//        // Fix for 211.pdf
//        for (Ruling r : horizontalRulingLines) {
//            if (r.getX2() < r.getX1()) {
//                double a = r.getX2();
//                r.x2 = (float) r.getX1();
//                r.x1 = (float) a;
//            }
//        }

        List<Rectangle2D> foundRectangles = new ArrayList<>();
        Map<Point2D, RulingIntersectionFinder.IntersectingRulings> intersectionPoints = RulingIntersectionFinder.findNaive(horizontalRulingLines, verticalRulingLines);

        List<Point2D> intersectionPointsList = new ArrayList<>(intersectionPoints.keySet());
        intersectionPointsList.sort(Y_FIRST_POINT_COMPARATOR);

        for (int i = 0; i < intersectionPointsList.size(); i++) {
            Point2D topLeft = intersectionPointsList.get(i);
            RulingIntersectionFinder.IntersectingRulings intersectingRulingsFromTopLeft = intersectionPoints.get(topLeft);

            // CrossingPointsDirectlyBelow( topLeft );
            List<Point2D> xPoints = new ArrayList<>();
            // CrossingPointsDirectlyToTheRight( topLeft );
            List<Point2D> yPoints = new ArrayList<>();

            for (Point2D p : intersectionPointsList.subList(i, intersectionPointsList.size())) {
                if (p.getX() == topLeft.getX() && p.getY() > topLeft.getY()) {
                    xPoints.add(p);
                }
                if (p.getY() == topLeft.getY() && p.getX() > topLeft.getX()) {
                    yPoints.add(p);
                }
            }
            outer:
            for (Point2D xPoint : xPoints) {
                // is there a vertical edge b/w topLeft and xPoint?
                if (!intersectingRulingsFromTopLeft.vertical().equals(intersectionPoints.get(xPoint).vertical())) {
                    continue;
                }
                for (Point2D yPoint : yPoints) {
                    // is there a horizontal edge b/w topLeft and yPoint ?
                    if (!intersectingRulingsFromTopLeft.horizontal().equals(intersectionPoints.get(yPoint).horizontal())) {
                        continue;
                    }
                    Point2D btmRight = new Point2D.Float((float) yPoint.getX(), (float) xPoint.getY());
                    if (intersectionPoints.containsKey(btmRight)
                        && intersectionPoints.get(btmRight).horizontal().equals(intersectionPoints.get(xPoint).horizontal())
                        && intersectionPoints.get(btmRight).vertical().equals(intersectionPoints.get(yPoint).vertical())) {

                        foundRectangles.add(new Rectangle2D.Double(topLeft.getX(), topLeft.getY(), btmRight.getX() - topLeft.getX(), btmRight.getY() - topLeft.getY()));
                        intersectionPoints.get(topLeft).horizontal().setClassification(Ruling.Classification.TABLE_LINE);
                        intersectionPoints.get(topLeft).vertical().setClassification(Ruling.Classification.TABLE_LINE);
                        intersectionPoints.get(btmRight).horizontal().setClassification(Ruling.Classification.TABLE_LINE);
                        intersectionPoints.get(btmRight).vertical().setClassification(Ruling.Classification.TABLE_LINE);
                        break outer;
                    }
                }
            }
        }

        // TODO create cells for vertical ruling lines with aligned endpoints at the top/bottom of a grid
        // that aren't connected with an horizontal ruler?
        // see: https://github.com/jazzido/tabula-extractor/issues/78#issuecomment-41481207

        return foundRectangles;
    }

}
