/*
 * Copyright 2006-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
  @test
  @bug 4737732
  @summary Tests that Toolkit.getScreenInsets() returns correct insets
  @author artem.ananiev: area=awt.toplevel
  @library ../../regtesthelpers
  @build Util
  @run main ScreenInsetsTest
*/

import java.awt.*;
import java.awt.event.*;

import test.java.awt.regtesthelpers.Util;

public class ScreenInsetsTest
{
    public static void main(String[] args)
    {
        if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH))
        {
            // this state is used in the test - sorry
            return;
        }

        boolean passed = true;

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gds = ge.getScreenDevices();
        for (GraphicsDevice gd : gds)
        {
            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            Rectangle gcBounds = gc.getBounds();
            Insets gcInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);

            Frame f = new Frame("Test", gc);
            f.setUndecorated(true);
            f.setBounds(gcBounds.x + 100, gcBounds.y + 100, 320, 240);
            f.setVisible(true);
            Util.waitForIdle(null);

            f.setExtendedState(Frame.MAXIMIZED_BOTH);
            Util.waitForIdle(null);

            Rectangle fBounds = f.getBounds();
            // workaround: on Windows maximized windows have negative coordinates
            if (fBounds.x < gcBounds.x)
            {
                fBounds.width -= (gcBounds.x - fBounds.x) * 2; // width is decreased
                fBounds.x = gcBounds.x;
            }
            if (fBounds.y < gcBounds.y)
            {
                fBounds.height -= (gcBounds.y - fBounds.y) * 2; // height is decreased
                fBounds.y = gcBounds.y;
            }
            Insets expected = new Insets(fBounds.y - gcBounds.y,
                                         fBounds.x - gcBounds.x,
                                         gcBounds.y + gcBounds.height - fBounds.y - fBounds.height,
                                         gcBounds.x + gcBounds.width - fBounds.x - fBounds.width);

            if (!expected.equals(gcInsets))
            {
                passed = false;
                System.err.println("Wrong insets for GraphicsConfig: " + gc);
                System.err.println("\tExpected: " + expected);
                System.err.println("\tActual: " + gcInsets);
            }

            f.dispose();
        }

        if (!passed)
        {
            throw new RuntimeException("TEST FAILED: Toolkit.getScreenInsets() returns wrong value for some screens");
        }
    }
}
