/*
 * Copyright (c) 2021, 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.*;
import java.awt.event.*;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.security.SecureRandom;


/*
 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
 */
public abstract class Common {

    ExtendedRobot robot;
    Class<? extends Frame> windowClass;
    Frame background;
    BufferedImage foreground;
    Window window;
    Container componentsContainer;

    float opacity = 1.0f;
    static final int STATIC_STEP = 30;
    static final int STATIC_WIDTH = 25;
    static final int STATIC_BLOCKS = 30;
    static final Color BG_COLOR = Color.BLUE;
    static final Color FG_COLOR = Color.RED;
    static final int delay = 1000;
    static final SecureRandom random = new SecureRandom();
    static final int dl = 100;
    static final Class[] WINDOWS_TO_TEST = { Window.class, Frame.class, Dialog.class };

    public Common(Class windowClass, float opacity) throws Exception{
        this.opacity = opacity;
        robot = new ExtendedRobot();
        this.windowClass = windowClass;
        EventQueue.invokeAndWait(this::initBackgroundFrame);
        EventQueue.invokeAndWait(this::initGUI);
    }

    public Common(Class windowClass) throws Exception{
        this(windowClass, 1.0f);
    }

    public void doTest() throws Exception {
        robot.waitForIdle(delay);
    };

    public void dispose() {
        window.dispose();
        background.dispose();
    }

    public abstract void applyShape();

    public void applyDynamicShape() {
        final Area a = new Area();
        Dimension size = window.getSize();
        for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 3; y++) {
                a.add(new Area(new Rectangle2D.Double(
                        x * size.getWidth() / 17*6, y * size.getHeight() / 17*6,
                        size.getWidth() / 17*5, size.getHeight() / 17*5)));
            }
        }
        window.setShape(a);
    }

    public void applyStaticShape() {
        final Area a = new Area();
        for (int x = 0; x < STATIC_BLOCKS; x++) {
            for (int y = 0; y < STATIC_BLOCKS; y++) {
                a.add(new Area(new Rectangle2D.Float(
                        x*STATIC_STEP, y*STATIC_STEP,
                        STATIC_WIDTH, STATIC_WIDTH)));
            }
        }
        window.setShape(a);
    }

    public BufferedImage getForegroundWindow() throws Exception {
        final BufferedImage f[] = new BufferedImage[1];
        EventQueue.invokeAndWait( () -> {
            f[0] = new BufferedImage(window.getWidth(),
                    window.getHeight(), BufferedImage.TYPE_INT_RGB);
            window.printAll(f[0].createGraphics());
        });
        robot.waitForIdle(delay);
        return f[0];
    }

    public static boolean checkTranslucencyMode(GraphicsDevice.WindowTranslucency mode) {

        if (!GraphicsEnvironment
                .getLocalGraphicsEnvironment()
                .getDefaultScreenDevice()
                .isWindowTranslucencySupported(mode)){
            System.out.println(mode+" translucency mode isn't supported");
            return false;
        } else {
            return true;
        }

    }

    public void applyAppDragNResizeSupport() {
        MouseAdapter m = new MouseAdapter() {

            private Point dragOrigin = null;
            private Dimension origSize = null;
            private Point origLoc = null;
            private boolean left = false;
            private boolean top = false;
            private boolean bottom = false;
            private boolean right = false;

            public void mousePressed(MouseEvent e) {
                dragOrigin = e.getLocationOnScreen();
                origSize = window.getSize();
                origLoc = window.getLocationOnScreen();
                right = (origLoc.x + window.getWidth() - dragOrigin.x) < 5;
                left = !right && dragOrigin.x - origLoc.x < 5;
                bottom = (origLoc.y + window.getHeight() - dragOrigin.y) < 5;
                top = !bottom && dragOrigin.y - origLoc.y < 5;
            }

            public void mouseReleased(MouseEvent e) { resize(e); }
            public void mouseDragged(MouseEvent e) { resize(e); }

            void resize(MouseEvent e) {
                Point dragDelta = e.getLocationOnScreen();
                dragDelta.translate(-dragOrigin.x, -dragOrigin.y);
                Point newLoc = new Point(origLoc);
                newLoc.translate(dragDelta.x, dragDelta.y);
                Dimension newSize = new Dimension(origSize);
                if (left || right) {
                    newSize.width += right ? dragDelta.x : -dragDelta.x;
                }
                if (top || bottom) {
                    newSize.height += bottom ? dragDelta.y : -dragDelta.y;
                }
                if (right || (top || bottom) && !left) {
                    newLoc.x = origLoc.x;
                }
                if (bottom || (left || right) && !top) {
                    newLoc.y = origLoc.y;
                }
                window.setBounds(newLoc.x, newLoc.y, newSize.width, newSize.height);
            }
        };
        for (Component comp : window.getComponents()) {
            comp.addMouseListener(m);
            comp.addMouseMotionListener(m);
        }

        window.addMouseListener(m);
        window.addMouseMotionListener(m);
    }

    public void checkTranslucentShape() throws Exception {
        foreground = getForegroundWindow();
        Point[] points = new Point[4];

        Dimension size = window.getSize();
        Point location = window.getLocationOnScreen();

        points[0] = new Point(20, 20);
        points[1] = new Point(20, size.height-20);
        points[2] = new Point(size.width-20, 20);
        points[3] = new Point(size.width-20, size.height-20);

        for (Point p : points){
            p.translate(location.x, location.y);
            Color actual = robot.getPixelColor(p.x, p.y);
            if (actual.equals(BG_COLOR)|| actual.equals(FG_COLOR))
                throw new RuntimeException("Error in point "+p+": "+actual+" equals to foreground or background color");
            else
                System.out.println("OK with foreground point "+p);
        }
    }

    public void checkStaticShape() throws Exception {
        Point[] points = new Point[4];

        Dimension size = window.getSize();
        int xFactor = (int) Math.floor(size.getWidth()/STATIC_STEP)-1;
        int yFactor = (int) Math.floor(size.getHeight()/STATIC_STEP)-1;

        // background
        points[0] = new Point((STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2);
        points[1] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2);
        points[2] = new Point((STATIC_STEP+STATIC_WIDTH)/2, STATIC_STEP*yFactor+(STATIC_STEP+STATIC_WIDTH)/2);
        points[3] = new Point(STATIC_STEP*xFactor+(STATIC_STEP+STATIC_WIDTH)/2, (STATIC_STEP+STATIC_WIDTH)/2);
        checkShape(points, true);

        // foreground
        if (opacity < 1.0f){
            checkTranslucentShape();
        } else {
            points[0] = new Point((STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2);
            points[1] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2);
            points[2] = new Point((STATIC_WIDTH) / 2, STATIC_STEP * yFactor + (STATIC_WIDTH) / 2);
            points[3] = new Point(STATIC_STEP * xFactor + (STATIC_WIDTH) / 2, (STATIC_WIDTH) / 2);
            checkShape(points, false);
        }
    }

    public void checkDynamicShape() throws Exception {
        Point[] points = new Point[4];

        Dimension size = window.getSize();

        int blockSizeX = (int) (size.getWidth() / 17);
        int blockSizeY = (int) (size.getHeight() / 17);

        // background
        points[0] = new Point((int) (blockSizeX * 5.5), (int) (blockSizeY * 5.5));
        points[1] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5));
        points[2] = new Point((int) (blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5));
        points[3] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (blockSizeY * 5.5));
        checkShape(points, true);

        // foreground
        if (opacity < 1.0f){
            checkTranslucentShape();
        } else {
            points[0] = new Point(3 * blockSizeX, 3 * blockSizeY);
            points[1] = new Point(14 * blockSizeX, 14 * blockSizeY);
            points[2] = new Point(3 * blockSizeX, 14 * blockSizeY);
            points[3] = new Point(14 * blockSizeX, 3 * blockSizeY);
            checkShape(points, false);
        }
    }

    public void checkShape(Point[] points, boolean areBackgroundPoints) throws Exception {

        Point location = window.getLocationOnScreen();

        for (Point p : points) {
            p.translate(location.x, location.y);
            if (areBackgroundPoints) {
                if (!robot.getPixelColor(p.x, p.y).equals(BG_COLOR))
                    throw new RuntimeException("Background point " + p + " color " + robot.getPixelColor(p.x, p.y) +
                            " does not equal to background color " + BG_COLOR);
                else
                    System.out.println("OK with background point " + p);
            } else {
                if (robot.getPixelColor(p.x, p.y).equals(BG_COLOR))
                    throw new RuntimeException("Foreground point " + p +
                            " equals to background color " + BG_COLOR);
                else
                    System.out.println("OK with foreground point " + p);
            }
        }
    }

    public void initBackgroundFrame() {
        background = new Frame();
        background.setUndecorated(true);
        background.setBackground(BG_COLOR);
        background.setSize(500, 500);
        background.setLocation(dl, dl);
        background.setVisible(true);
    }

    public void initGUI() {
        if (windowClass.equals(Frame.class)) {
            window = new Frame();
            ((Frame) window).setUndecorated(true);
        } else  if (windowClass.equals(Dialog.class)) {
            window = new Dialog(background);
            ((Dialog) window).setUndecorated(true);
        } else {
            window = new Window(background);
        }

        window.setBackground(FG_COLOR);
        componentsContainer = new Panel();
        window.add(componentsContainer, BorderLayout.CENTER);
        window.setLocation(2 * dl, 2 * dl);
        window.setSize(255, 255);
        if (opacity < 1.0f)
            window.setOpacity(opacity);
        window.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                applyShape();
            }
        });
        applyShape();
        window.setVisible(true);
        applyAppDragNResizeSupport();
        window.toFront();
    }
}
