/*
 * Copyright (c) 2008, 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 4452384
  @summary Tests that non-focusable windows doesn't generate any focus events when accessed.
  @author Denis.Mikhalkin: area=awt.focus
  @run main NoEventsTest
*/

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

public class NoEventsTest extends Frame {
    public static final int DEF_WIDTH = 400,
        DEF_HEIGHT = 300,
        DEF_TOP = 1,
        DEF_LEFT = 100,
        DEF_ROW = 0,
        DEF_COL = 0;
    static boolean automatic = true;
    static Window[] windows;
    static Frame main_frame, jumpingFrame;
    static Button focus_button;
    static Robot robot;
    static void pause(int timeout) {
        Toolkit.getDefaultToolkit().sync();
        robot.waitForIdle();
        robot.delay(100);
    }
    static GlobalListener listener;
    public static void main(String[] args) {

        listener = new GlobalListener();
        Toolkit.getDefaultToolkit().addAWTEventListener(listener,
                                                        AWTEvent.FOCUS_EVENT_MASK |
                                                        AWTEvent.WINDOW_EVENT_MASK);
        try{
            robot = new Robot();
        } catch(Exception e) {}
        // Create several pairs - focusable Frame with focusable component(button) and non-focusable:
        // window, resizable frame, non-resizable frame, dialog, non-resiable dialog
        main_frame = new Frame("focusable frame");
        focus_button = new Button("button to focus");
        main_frame.add(focus_button);
        main_frame.pack();
        main_frame.setVisible(true);
        main_frame.setLocation(10, 600);
        main_frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    listener.report();
                    System.exit(0);
                }
            });

        jumpingFrame = new Frame("Jumping frame");
        jumpingFrame.setBounds(DEF_LEFT, DEF_TOP, DEF_WIDTH, DEF_HEIGHT);

        windows = new Window[7];
        windows[0] = new TestWindow(0, 0, false, main_frame);
        //windows[1] = new TestWindow(2, 1, true, main_frame);
        windows[2] = new NoEventsTest(1, 0, false, true);
        windows[3] = new NoEventsTest(2, 0, false, false);
        //windows[4] = new Test(3, 0, true, true);
        windows[5] = new TestDialog(0, 1, false, true, main_frame);
        windows[6] = new TestDialog(1, 1, false, false, main_frame);
        if (!automatic) {
            int windowInd;
            for (windowInd = 0; windowInd < windows.length; windowInd++) {
                if (windows[windowInd] != null) {
                    windows[windowInd].setVisible(true);
                }
            }
        }
        // Run the test
        // 1. Click on all controls, check for no focus events for non-focusable, right focus events for focusable
        // 2. Perform some action with control, check if it works
        if (automatic) {
            int windowInd;
            for (windowInd = 0; windowInd < windows.length; windowInd++) {
                if (windows[windowInd] != null) {
                    windows[windowInd].setVisible(true);
                    focus_button.requestFocus();
                    pause(1000);

                    // Verify that click on non-focusable window causes no focus lost on active window
                    performFocusClick(windows[windowInd]);
                    focus_button.requestFocus();
                    pause(500);
                    performActionClick(windows[windowInd]);

                    // Verify that toFront, toBack doesn't cause non-focusable window to become active
                    jumpingFrame.setVisible(true);
                    pause(1000);
                      jumpingFrame.toBack();
                      pause(500);
                      jumpingFrame.toFront();
                      pause(500);
                      windows[windowInd].toBack();
                      pause(500);
                      windows[windowInd].toFront();
                      pause(500);

                    // Verify that iconifiyng/deiconfiying and
                    // zooming/unzooming doesn't cause non-focusable
                    // window to become active
                    if (windows[windowInd] instanceof Frame) {
                        Frame toTest = (Frame)windows[windowInd];
                        // Deiconification currently doesn't work!
//                        toTest.setExtendedState(Frame.ICONIFIED);
//                        pause(500);
//                        toTest.setExtendedState(Frame.NORMAL);
                        pause(500);
                        toTest.setExtendedState(Frame.MAXIMIZED_BOTH);
                        pause(500);
                        toTest.setExtendedState(Frame.NORMAL);
                    }

                    windows[windowInd].dispose();
                    jumpingFrame.dispose();
                }
            }
            pause(1000);
            System.err.println("Test finished.");
            if (!listener.report()) {
                throw new RuntimeException("Test Failed. See error stream output for details");
            }
        }
    }
    static void performFocusClick(Window parent) {
        if (parent == null) {
            return;
        }
        for (int compInd = 0; compInd < parent.getComponentCount(); compInd++) {
            Component child = parent.getComponent(compInd);
            if (child instanceof TestPanel) {
                TestPanel pan = (TestPanel)child;
                pan.performFocusClicks(robot);
                pause(100);
            }
        }
    }
    static void performActionClick(Window parent) {
        if (parent == null) {
            return;
        }
        for (int compInd = 0; compInd < parent.getComponentCount(); compInd++) {
            Component child = parent.getComponent(compInd);
            if (child instanceof TestPanel) {
                TestPanel pan = (TestPanel)child;
                pan.performActionClicks(robot);
                pause(100);
            }
        }
    }
    public NoEventsTest(int row, int col, boolean focusable, boolean resizable) {
        super("Frame" + row + "" + col);
        TestPanel panel = new TestPanel(row, col);
        if (NoEventsTest.automatic) {
            row = NoEventsTest.DEF_ROW;
            col = NoEventsTest.DEF_COL;
        }
        setName(getTitle());
        add("Center", panel);
        Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") +
                            ", " + (resizable?"resizable":"non-resizable"));
        l.setBackground(Color.green);
        add("North", l);
        setBounds(NoEventsTest.DEF_LEFT + DEF_WIDTH*col, DEF_TOP + DEF_HEIGHT*row, DEF_WIDTH, DEF_HEIGHT);
        if (!focusable) {
            setFocusableWindowState(false);
        }
        if (!resizable) {
            setResizable(false);
        }
//        setVisible(true);
    }
}
class TestWindow extends Window {
    public TestWindow(int row, int col, boolean focusable, Frame owner) {
        super(owner);
        setName("Window" + row + "" + col);
        TestPanel panel = new TestPanel(row, col);
        if (NoEventsTest.automatic) {
            row = NoEventsTest.DEF_ROW;
            col = NoEventsTest.DEF_COL;
        }

        add("Center", panel);
        Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") +
                            ", " + (false?"resizable":"non-resizable"));
        l.setBackground(Color.green);
        add("North", l);

        setBounds(NoEventsTest.DEF_LEFT + NoEventsTest.DEF_WIDTH*col, NoEventsTest.DEF_TOP + NoEventsTest.DEF_HEIGHT*row, NoEventsTest.DEF_WIDTH, NoEventsTest.DEF_HEIGHT);
        if (!focusable) {
            setFocusableWindowState(false);
        }
//        setVisible(true);
    }
}
class TestDialog extends Dialog {
    public TestDialog(int row, int col, boolean focusable, boolean resizable, Frame owner) {
        super(owner);
        setName("Dialog" + row + "" + col);
        TestPanel panel = new TestPanel(row, col);
        if (NoEventsTest.automatic) {
            row = NoEventsTest.DEF_ROW;
            col = NoEventsTest.DEF_COL;
        }

        add("Center", panel);
        Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") +
                            ", " + (resizable?"resizable":"non-resizable"));
        l.setBackground(Color.green);
        add("North", l);

        setBounds(NoEventsTest.DEF_LEFT + NoEventsTest.DEF_WIDTH*col, NoEventsTest.DEF_TOP + NoEventsTest.DEF_HEIGHT*row, NoEventsTest.DEF_WIDTH, NoEventsTest.DEF_HEIGHT);
        if (!focusable) {
            setFocusableWindowState(false);
        }
        if (!resizable) {
            setResizable(false);
        }
//        setVisible(true);
    }
}

class TestPanel extends Panel {

    void clickComponent(Component comp, Robot robot) {
        if (comp instanceof Choice) {
            return;
        }
        Point compLoc = comp.getLocationOnScreen();
        Dimension size = comp.getSize();
        robot.mouseMove(compLoc.x + size.width/2, compLoc.y + size.height/2);
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
    }
    void performFocusClicks(Robot robot) {
        for (int childInd = 0; childInd < getComponentCount(); childInd++) {
            performFocusClick(getComponent(childInd), robot);
        }
    }
    void performFocusClick(Component comp, Robot robot) {
        clickComponent(comp, robot);
    }

    void performActionClicks(Robot robot) {
        for (int childInd = 0; childInd < getComponentCount(); childInd++) {
            performActionClick(getComponent(childInd), robot);
        }
    }
    void performActionClick(Component comp, Robot robot) {
    }

    public TestPanel(int row, int col) {
        setLayout(new FlowLayout());
        Button b;
        add(b = new Button("press"+ row + "" + col));
        b.setName(b.getLabel());
//         b.addMouseListener(new MouseAdapter() {
//                 public void mousePressed(MouseEvent e) {
//                     System.err.println(e);
//                 }
//             });
        TextField t;
        add(t = new TextField("text" + row + "" + col));
        t.setName(t.getText());

        java.awt.List list = new java.awt.List();
        add(list);
        list.setName("list");
        list.add("one");
        list.add("two");
        list.add("three");
        list.setMultipleMode(true);
        list.setName("list" + row + "" + col);

        Checkbox check = new Checkbox("checker");
        add(check);
        check.setName("check" + row + "" + col);

        Choice choice = new Choice();
        choice.add("one");
        choice.add("two");
        choice.add("three");
        add(choice);
        choice.setName("choice" + row + "" + col);

        Canvas can = new Canvas() {
                public Dimension getPreferredSize() {
                    return new Dimension(10, 10);
                }
            };
        can.setBackground(Color.blue);
        add(can);
        can.setName("canvas" + row + "" + col);

        TextArea ta = new TextArea("text\ntttt\naaaa\nwwwww\nqqqqqq\neeeeee\nrrrrrr\nyyyyyy\nuuuuu", 3, 5);
        add(ta);
        ta.setName("textarea" + row + "" + col);

        Scrollbar bar = new Scrollbar(Scrollbar.HORIZONTAL);
        add(bar);
        bar.setName("scrollbar" + row + "" + col);

        CheckboxGroup group = new CheckboxGroup();
        Checkbox ch1 = new Checkbox("one", group, true);
        Checkbox ch2 = new Checkbox("two", group, false);
        add(ch1);
        add(ch2);
        ch1.setName("checkbox1 " + row + "" + col);
        ch2.setName("checkbox2 " + row + "" + col);


        ScrollPane pane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
        add(pane);
        Button bigButton = new Button("abc") {
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
            };
        pane.add(bigButton);
        bigButton.setName("bigbutton" + row + "" + col);
    }
}

class GlobalListener implements AWTEventListener {
    java.util.List errors = new java.util.LinkedList();
    public boolean report() {
        if (errors.size() != 0) {
            System.err.println("Test FAILED");
        } else {
            System.err.println("Test PASSED");
            return true;
        }
        ListIterator iter = errors.listIterator();
        while (iter.hasNext()) {
            System.err.println(iter.next());
        }
        return false;
    }
    public GlobalListener() {
    }
    Window getWindowParent(Component comp) {
        while (comp != null && !(comp instanceof Window)) {
            comp = comp.getParent();
        }
        return (Window)comp;
    }
    void reportError(AWTEvent e, String message) {
        String error = "ERROR: " + message + " : " + e;
        errors.add(error);
        System.err.println(error);
    }
    public void eventDispatched(AWTEvent e) {
        Component comp = (Component)e.getSource();
        Window parent = getWindowParent(comp);
        if (!(e instanceof WindowEvent || e instanceof FocusEvent)) {
            System.err.println("Strange event " + e);
        }

        // Skip WINDOW_OPENED
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            System.err.println(e);
        }
        switch (e.getID()) {
          case WindowEvent.WINDOW_OPENED:
          case WindowEvent.WINDOW_CLOSING:
          case WindowEvent.WINDOW_CLOSED:
          case WindowEvent.WINDOW_ICONIFIED:
          case WindowEvent.WINDOW_DEICONIFIED:
          case WindowEvent.WINDOW_STATE_CHANGED:
            return;
          case WindowEvent.WINDOW_LOST_FOCUS: {
              WindowEvent we = (WindowEvent)e;
              if (we.getOppositeWindow() != null && !we.getOppositeWindow().getFocusableWindowState()) {
                  reportError(e, "frame lost focus because of non-focusable window");
              }
              break;
          }
        }
        // Check that Window owner is focusable
        if (!parent.getFocusableWindowState()) {
            reportError(e, "focus event for component in non-focusable window " + parent.getName());
        }
        if (!comp.isFocusable()) {
            reportError(e, "focus event for non-focusable component");
        }
//         if (e instanceof WindowEvent || e instanceof FocusEvent) {
// //             System.err.println(e);
//         }
    }
}
