/*
 * Copyright (c) 2013, 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.
 */

/**
 * @test
 * @bug 8027628
 * @author Oleg Pekhovskiy
 * @summary JWindow jumps to (0, 0) after mouse clicked
 * @run main TopLevelLocation
 */

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JWindow;

public class TopLevelLocation {

    private static JFrame frame;
    private static JWindow window;
    private static boolean passed = true;

    public static void main(String[] args) throws Exception {
        EventQueue.invokeAndWait(() -> {
            frame = new JFrame();
            frame.getContentPane().setBackground(Color.PINK);
            frame.setBounds(100, 100, 500, 400);
            frame.setUndecorated(true);
            frame.setVisible(true);
            window = new JWindow(frame);
            window.setBackground(Color.BLUE);
            window.setAlwaysOnTop(true);
            window.setBounds(200, 200, 200, 200);
            window.addMouseListener(new MouseAdapter() {
                private Point dragOrigin = null;
                private Dimension origSize = null;
                private Point origLoc = null;
                private Point lastLoc = null;
                private boolean left = false;
                private boolean top = false;
                private boolean bottom = false;
                private boolean right = false;

                @Override
                public void mousePressed(MouseEvent e) {
                    System.out.println("mousePressed");
                    dragOrigin = e.getLocationOnScreen();
                    origSize = window.getSize();
                    origLoc = window.getLocationOnScreen();
                    if (lastLoc != null) {
                        System.out.println("SET LOCATION: " + lastLoc);
                        System.out.println("CURRENT LOCATION: " + origLoc);
                        if (lastLoc.x != origLoc.x || lastLoc.y != origLoc.y) {
                            passed = false;
                        }
                    }
                    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;
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    System.out.println("mouseDragged");
                    resize(e);
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    System.out.println("mouseReleased");
                    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);
                    lastLoc = newLoc;
                }
            });
            window.setVisible(true);
        });
        Thread.sleep(500);
        Dimension size = window.getSize();
        Point location = window.getLocation();
        Robot robot = new Robot();
        robot.setAutoDelay(200);
        robot.setAutoWaitForIdle(true);
        robot.waitForIdle();
        robot.mouseMove(location.x + size.height - 2, location.y + size.width - 2);
        robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
        robot.mouseMove(location.x + size.height, location.y + size.width);
        robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
        robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
        robot.mouseMove(location.x + size.height + 2, location.y + size.width + 2);
        robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
        Thread.sleep(500);
        frame.dispose();
        if (!passed) {
            throw new RuntimeException("TEST FAILED: Location doesn't match!");
        }
        System.out.println("TEST PASSED!");
    }
}