/*
 * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;

/*
 * @test
 * @bug 4210936 4214524
 * @summary Tests the results of the hit test methods on 3 different
 *          Shape objects - Polygon, Area, and GeneralPath.  Both an
 *          automatic test for constraint compliance and a manual
 *          test for correctness are included in this one class.
 * @library /java/awt/regtesthelpers
 * @build PassFailJFrame
 * @run main PathHitTest
 */

/*
 * @test
 * @bug 4210936 4214524
 * @summary Tests the results of the hit test methods on 3 different
 *          Shape objects - Polygon, Area, and GeneralPath.  Both an
 *          automatic test for constraint compliance and a manual
 *          test for correctness are included in this one class.
 * @library /java/awt/regtesthelpers
 * @build PassFailJFrame
 * @run main/manual PathHitTest manual
 */

public class PathHitTest {

    public static final int BOXSIZE = 5;
    public static final int BOXCENTER = 2;
    public static final int TESTSIZE = 400;
    public static final int NUMTESTS = (TESTSIZE + BOXSIZE - 1) / BOXSIZE;

    public static Shape[] testShapes = new Shape[5];
    public static String[] testNames = {
            "Polygon",
            "EvenOdd GeneralPath",
            "NonZero GeneralPath",
            "Area from EO GeneralPath",
            "Area from NZ GeneralPath",
    };

    static {
        GeneralPath gpeo = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
        Ellipse2D ell = new Ellipse2D.Float();
        Point2D center = new Point2D.Float();
        AffineTransform at = new AffineTransform();
        for (int i = 0; i < 360; i += 30) {
            center.setLocation(100, 0);
            at.setToTranslation(200, 200);
            at.rotate(i * Math.PI / 180);
            at.transform(center, center);
            ell.setFrame(center.getX() - 50, center.getY() - 50, 100, 100);
            gpeo.append(ell, false);
        }
        GeneralPath side = new GeneralPath();
        side.moveTo(0, 0);
        side.lineTo(15, 10);
        side.lineTo(30, 0);
        side.lineTo(45, -10);
        side.lineTo(60, 0);
        append4sides(gpeo, side, 20, 20);
        side.reset();
        side.moveTo(0, 0);
        side.quadTo(15, 10, 30, 0);
        side.quadTo(45, -10, 60, 0);
        append4sides(gpeo, side, 320, 20);
        side.reset();
        side.moveTo(0, 0);
        side.curveTo(15, 10, 45, -10, 60, 0);
        append4sides(gpeo, side, 20, 320);

        GeneralPath gpnz = new GeneralPath(GeneralPath.WIND_NON_ZERO);
        gpnz.append(gpeo, false);
        Polygon p = new Polygon();
        p.addPoint( 50,  50);
        p.addPoint( 60, 350);
        p.addPoint(250, 340);
        p.addPoint(260, 150);
        p.addPoint(140, 140);
        p.addPoint(150, 260);
        p.addPoint(340, 250);
        p.addPoint(350,  60);
        testShapes[0] = p;
        testShapes[1] = gpeo;
        testShapes[2] = gpnz;
        testShapes[3] = new Area(gpeo);
        testShapes[3].getPathIterator(null);
        testShapes[4] = new Area(gpnz);
        testShapes[4].getPathIterator(null);
    }

    private static void append4sides(GeneralPath path, GeneralPath side,
                                     double xoff, double yoff) {
        AffineTransform at = new AffineTransform();
        at.setToTranslation(xoff, yoff);
        for (int i = 0; i < 4; i++) {
            path.append(side.getPathIterator(at), i != 0);
            at.rotate(Math.toRadians(90), 30, 30);
        }
    }

    public static void main(String[] argv) throws Exception {
        if (argv.length > 0 && argv[0].equals("manual")) {
            PathHitTestManual.doManual();
        } else {
            int totalerrs = 0;
            for (int i = 0; i < testShapes.length; i++) {
                totalerrs += testshape(testShapes[i], testNames[i]);
            }
            if (totalerrs != 0) {
                throw new RuntimeException(totalerrs +
                        " constraint conditions violated!");
            }
        }
    }

    public static int testshape(Shape s, String name) {
        int numerrs = 0;
        long start = System.currentTimeMillis();
        for (int y = 0; y < TESTSIZE; y += BOXSIZE) {
            for (int x = 0; x < TESTSIZE; x += BOXSIZE) {
                boolean rectintersects = s.intersects(x, y, BOXSIZE, BOXSIZE);
                boolean rectcontains = s.contains(x, y, BOXSIZE, BOXSIZE);
                boolean pointcontains = s.contains(x + BOXCENTER, y + BOXCENTER);
                if (rectcontains && !rectintersects) {
                    System.err.println("rect is contained " +
                            "but does not intersect!");
                    numerrs++;
                }
                if (rectcontains && !pointcontains) {
                    System.err.println("rect is contained " +
                            "but center is not contained!");
                    numerrs++;
                }
                if (pointcontains && !rectintersects) {
                    System.err.println("center is contained " +
                            "but rect does not intersect!");
                    numerrs++;
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(name + " completed in " +
                (end - start) + "ms with " +
                numerrs + " errors");
        return numerrs;
    }

    static class PathHitTestManual extends Panel {
        private static final String INSTRUCTIONS = """
            This test displays the results of hit testing 5 different Shape
            objects one at a time.

            You can switch between shapes using the Choice component located
            at the bottom of the window.

            Each square in the test represents the
            return values of the hit testing operators for that square region:

                yellow - not yet tested
                translucent blue overlay - the shape being tested

                black - all outside
                dark gray - rectangle intersects shape
                light gray - rectangle intersects and center point is inside shape
                white - rectangle is entirely contained in shape
                red - some constraint was violated, including:
                    rectangle is contained, but center point is not
                    rectangle is contained, but rectangle.intersects is false
                    centerpoint is contained, but rectangle.intersects is false

            Visually inspect the results to see if they match the above table.
            Note that it is not a violation for rectangles that are entirely
            inside the path to be light gray instead of white since sometimes
            the path is complex enough to make an exact determination expensive.
            You might see this on the GeneralPath NonZero example where the
            circles that make up the path cross over the interior of the shape
            and cause the hit testing methods to guess that the rectangle is
            not guaranteed to be contained within the shape.
            """;

        PathHitTestCanvas phtc;

        public void init() {
            setLayout(new BorderLayout());
            phtc = new PathHitTestCanvas();
            add("Center", phtc);
            final Choice ch = new Choice();
            for (int i = 0; i < PathHitTest.testNames.length; i++) {
                ch.add(PathHitTest.testNames[i]);
            }
            ch.addItemListener(e -> phtc.setShape(ch.getSelectedIndex()));
            ch.select(0);
            phtc.setShape(0);
            add("South", ch);
        }

        public void start() {
            phtc.start();
        }

        public void stop() {
            phtc.stop();
        }

        public static class PathHitTestCanvas extends Canvas implements Runnable {
            public static final Color[] colors = {
                                        /* contains?  point in?  intersects? */
                    Color.black,        /*    NO         NO          NO      */
                    Color.darkGray,     /*    NO         NO          YES     */
                    Color.red,          /*    NO         YES         NO      */
                    Color.lightGray,    /*    NO         YES         YES     */
                    Color.red,          /*    YES        NO          NO      */
                    Color.red,          /*    YES        NO          YES     */
                    Color.red,          /*    YES        YES         NO      */
                    Color.white,        /*    YES        YES         YES     */
                    Color.yellow,       /*     used for untested points      */
            };

            public Dimension getPreferredSize() {
                return new Dimension(TESTSIZE, TESTSIZE);
            }

            public synchronized void start() {
                if (!testdone) {
                    renderer = new Thread(this);
                    renderer.setPriority(Thread.MIN_PRIORITY);
                    renderer.start();
                }
            }

            public synchronized void stop() {
                renderer = null;
            }

            private Thread renderer;
            private int shapeIndex = 0;
            private byte[] indices = new byte[NUMTESTS * NUMTESTS];
            boolean testdone = false;

            private synchronized void setShape(int index) {
                shapeIndex = index;
                testdone = false;
                start();
            }

            public void run() {
                Thread me = Thread.currentThread();
                Graphics2D g2d = (Graphics2D) getGraphics();
                byte[] indices;
                Shape s = testShapes[shapeIndex];
                synchronized (this) {
                    if (renderer != me) {
                        return;
                    }
                    this.indices = new byte[NUMTESTS * NUMTESTS];
                    java.util.Arrays.fill(this.indices, (byte) 8);
                    indices = this.indices;
                }

                System.err.printf("%s %s\n", g2d, Color.yellow);
                g2d.setColor(Color.yellow);
                g2d.fillRect(0, 0, TESTSIZE, TESTSIZE);
                int numtests = 0;
                long start = System.currentTimeMillis();
                for (int y = 0; renderer == me && y < TESTSIZE; y += BOXSIZE) {
                    for (int x = 0; renderer == me && x < TESTSIZE; x += BOXSIZE) {
                        byte index = 0;
                        if (s.intersects(x, y, BOXSIZE, BOXSIZE)) {
                            index += 1;
                        }
                        if (s.contains(x + BOXCENTER, y + BOXCENTER)) {
                            index += 2;
                        }
                        if (s.contains(x, y, BOXSIZE, BOXSIZE)) {
                            index += 4;
                        }
                        numtests++;
                        int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE);
                        indices[i] = index;
                        g2d.setColor(colors[index]);
                        g2d.fillRect(x, y, BOXSIZE, BOXSIZE);
                    }
                }
                synchronized (this) {
                    if (renderer != me) {
                        return;
                    }
                    g2d.setColor(new Color(0, 0, 1, .2f));
                    g2d.fill(s);
                    testdone = true;
                    long end = System.currentTimeMillis();
                    System.out.println(numtests + " tests took " + (end - start) + "ms");
                }
            }

            public void paint(Graphics g) {
                g.setColor(Color.yellow);
                g.fillRect(0, 0, TESTSIZE, TESTSIZE);
                byte[] indices = this.indices;
                if (indices != null) {
                    for (int y = 0; y < TESTSIZE; y += BOXSIZE) {
                        for (int x = 0; x < TESTSIZE; x += BOXSIZE) {
                            int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE);
                            g.setColor(colors[indices[i]]);
                            g.fillRect(x, y, BOXSIZE, BOXSIZE);
                        }
                    }
                }
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(new Color(0, 0, 1, .2f));
                g2d.fill(testShapes[shapeIndex]);
            }
        }

        static volatile PathHitTestManual pathHitTestManual;

        private static void createAndShowGUI() {
            pathHitTestManual = new PathHitTestManual();
            Frame frame = new Frame("PathHitTestManual test window");

            frame.add(pathHitTestManual);
            frame.setSize(400, 450);

            PassFailJFrame.addTestWindow(frame);
            PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.HORIZONTAL);

            frame.setVisible(true);

            pathHitTestManual.init();
            pathHitTestManual.start();
        }

        public static void doManual() throws Exception {
            PassFailJFrame passFailJFrame = PassFailJFrame.builder()
                    .title("PathHitTestManual Instructions")
                    .instructions(INSTRUCTIONS)
                    .testTimeOut(5)
                    .rows(30)
                    .columns(70)
                    .screenCapture()
                    .build();

            EventQueue.invokeAndWait(PathHitTestManual::createAndShowGUI);
            try {
                passFailJFrame.awaitAndCheck();
            } finally {
                pathHitTestManual.stop();
            }
        }
    }
}
