/*
 * Copyright (c) 2010, 2016, 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.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;

/*
 * @test
 * @key headful
 * @bug 8013450
 * @summary Check if the window events (Focus and Activation) are triggered correctly
 *          when clicked on visible and clipped areas.
 *
 * Test Description: Check if PERPIXEL_TRANSPARENT Translucency type is supported
 *      by the current platform. Proceed if it is supported. Apply different
 *      types of shapes on a Window. Make it appear with a known background.
 *      Check if mouse events which result in window-activated events are
 *      triggered only within the window's shape and not outside. Repeat this
 *      for Window, Dialog and Frame.
 * Expected Result: If PERPIXEL_TRANSPARENT Translucency type is supported, window should
 *      gain focus and should trigger activated events only when it is clicked on the
 *      visible areas. Events should be delivered to the background window if clicked
 *      on the clipped areas.
 *
 * @author mrkam
 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
 * @library ../../../../lib/testlibrary
 * @build Common ExtendedRobot
 * @run main FocusAWTTest
 */

public class FocusAWTTest extends Common {

    ExtendedRobot robot;
    int dx;
    int dy;
    static final int x = 20;
    static final int y = 400;

    static volatile HashMap<String, Boolean> flags = new HashMap<String, Boolean>();
    static {
        flags.put("backgroundWindowActivated", false);
        flags.put("backgroundWindowDeactivated", false);
        flags.put("backgroundWindowGotFocus", false);
        flags.put("backgroundWindowLostFocus", false);
        flags.put("foregroundWindowGotFocus", false);
        flags.put("foregroundWindowLostFocus", false);
        flags.put("foregroundWindowActivated", false);
        flags.put("foregroundWindowDeactivated", false);
    }

    public static void main(String[] ignored) throws Exception{
        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
            for (Class<Window> windowClass: WINDOWS_TO_TEST) {
                new FocusAWTTest(windowClass).doTest();
            }
    }

    public FocusAWTTest(Class windowClass) throws Exception {
        super(windowClass);
        this.robot = new ExtendedRobot();
        robot.waitForIdle();
        EventQueue.invokeAndWait(() -> {
            dx = background.getX() - x;
            dy = background.getY() - y;
        });
        robot.waitForIdle();
    }

    @Override
    public void initBackgroundFrame() {
        background = new Frame();
        background.setSize(300, 300);
        background.setLocation(x, y);
        background.setFocusable(true);
        background.setFocusableWindowState(true);

        background.addWindowFocusListener(new WindowFocusListener() {
            public void windowGainedFocus(WindowEvent e) { flags.put("backgroundWindowGotFocus", true); }
            public void windowLostFocus(WindowEvent e) { flags.put("backgroundWindowLostFocus", true); }
        });

        background.addWindowListener(new WindowAdapter() {
            public void windowActivated(WindowEvent e) { flags.put("backgroundWindowActivated", true); }
            public void windowDeactivated(WindowEvent e) { flags.put("backgroundWindowDeactivated", true); }
        });
        background.add(new TextArea());
        background.setVisible(true);
    }

    @Override
    public void initGUI() {
        if (windowClass.equals(Frame.class)) {
            window = new Frame() {
                public void paint(Graphics g) {
                    g.setColor(Color.BLUE);
                    g.fillRect(0, 0, 200, 200);
                }
            };
            ((Frame) window).setUndecorated(true);
        } else if (windowClass.equals(Dialog.class)) {
            window = new Dialog(background) {
                public void paint(Graphics g) {
                    g.setColor(Color.BLUE);
                    g.fillRect(0, 0, 200, 200);
                }
            };
            ((Dialog) window).setUndecorated(true);
        } else {
            window = new Window(background) {
                public void paint(Graphics g) {
                    g.setColor(Color.BLUE);
                    g.fillRect(0, 0, 200, 200);
                }
            };
            window.setFocusable(true);
            window.setFocusableWindowState(true);
        }

        window.setPreferredSize(new Dimension(200, 200));
        window.setLocation(70 + dx, 450 + dy);
        window.setLayout(new BorderLayout());

        window.addWindowFocusListener(new WindowFocusListener() {
            public void windowGainedFocus(WindowEvent e) { flags.put("foregroundWindowGotFocus", true); }
            public void windowLostFocus(WindowEvent e) { flags.put("foregroundWindowLostFocus", true); }
        });

        window.addWindowListener(new WindowAdapter() {
            public void windowActivated(WindowEvent e) { flags.put("foregroundWindowActivated", true); }
            public void windowDeactivated(WindowEvent e) { flags.put("foregroundWindowDeactivated", true); }
        });

        applyShape();
        window.pack();
        window.setAlwaysOnTop(true);
        window.setVisible(true);
    }

    @Override
    public void doTest() throws Exception {
        super.doTest();
        final Point wls = new Point();
        final Dimension size = new Dimension();
        EventQueue.invokeAndWait(() -> {
            window.requestFocus();
            wls.setLocation(window.getLocationOnScreen());
            window.getSize(size);
        });

        robot.waitForIdle();

        check(wls.x + size.width - 5, wls.y + 5, wls.x + size.width / 3, wls.y + size.height / 3);
        check(wls.x + size.width / 2, wls.y + size.height / 2, wls.x + size.width * 2 / 3, wls.y + size.height * 2 / 3);

        EventQueue.invokeAndWait(() -> {
            background.dispose();
            window.dispose();
        });

        robot.waitForIdle();
    }

    @Override
    public void applyShape() {
        Shape shape;
        Area a = new Area(new Rectangle2D.Float(0, 0, 200, 200));
        GeneralPath gp;
        gp = new GeneralPath();
        gp.moveTo(190, 0);
        gp.lineTo(200, 0);
        gp.lineTo(200, 10);
        gp.lineTo(10, 200);
        gp.lineTo(0, 200);
        gp.lineTo(0, 190);
        gp.closePath();
        a.subtract(new Area(gp));
        shape = a;

        window.setShape(shape);
    }

    private void check(int xb, int yb, int xw, int yw) throws Exception {
        checkClick(xb, yb, "backgroundWindowGotFocus");
        checkClick(xw, yw, "foregroundWindowGotFocus");
        checkClick(xb, yb, "foregroundWindowLostFocus");
        checkClick(xw, yw, "backgroundWindowLostFocus");

        if (window instanceof Dialog || window instanceof Frame) {
            checkClick(xb, yb, "backgroundWindowActivated");
            checkClick(xw, yw, "foregroundWindowActivated");
            checkClick(xb, yb, "foregroundWindowDeactivated");
            checkClick(xw, yw, "backgroundWindowDeactivated");
        }

    }

    private void checkClick(int x, int y, String flag) throws Exception {
        System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " to trigger.");

        flags.put(flag, false);

        robot.mouseMove(x, y);
        robot.click();
        int i = 0;
        while (i < 5000 && !flags.get(flag)) {
            robot.waitForIdle(50);
            i += 50;
        }

        if (!flags.get(flag))
            throw new RuntimeException(flag + " is not triggered for click on point " + x + ", " + y + " for " + windowClass + "!");
    }
}
