/*
test SetLocDlgTest 1.0 2001/04/05
@summary To test a method setLocationRelativeTo() which is moved up in
the hierarchy from javax.swing.JDialog to java.awt.Window
@author Aruna S. (aruna.samji@india) area=AWTCCC
@run applet SetLocDlgTest.html
*/

/**
 * SetLocDlgTest.java
 *
 * summary: This class tests for the setLocationRelativeTo(Component c) method
 *      by invoking the method from Dialog class.
 *      The parameters passed to this method includes the set of AWT and swing Components.
 *      The Dialog should be moved relative to the components passed as parameter to the
 *      method.
 */

import java.io.*;
import java.util.Vector;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

public class SetLocSwingDlgTest implements ActionListener {

    JDialog dialog, testDlg;
    JFrame frame;
    JButton jbutton;
    JCheckBox jchkBox;
    JLabel jlabel;
    JList jlist;
    JScrollBar jscrollbar;
    JTextArea jtextArea;
    JTextField jtextField;
    JComponent c;
    Point comp_pt, dlg_pt;
    Vector vector;

    private Button showComponent;
    private Button showDialog;
    private Object lock = new Object();

    private int delay = 500;
    private static int count = 0;
    private int componentCount = 0;
    private boolean actionPerformed = false;

    private boolean passed = true;
    private static String WORK_DIR=".";

    public SetLocSwingDlgTest() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    initializeGUI();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    private void initializeGUI() {
		
        final int CONTROLLER_SIZE = 200;
        final int CONTROLLER_X = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width - CONTROLLER_SIZE;
        final int DLG_SIZE = 400;
		
        frame = new JFrame("SetLocDlg Test Frame");
        dialog = new JDialog(frame, "SetLocDlg Test Dialog");
        dialog.setBackground(Color.red);
        dialog.setSize(DLG_SIZE, DLG_SIZE);
        dialog.setLocation(CONTROLLER_X - DLG_SIZE, 200);
        dialog.getContentPane().setLayout(null);

        jbutton = new JButton("SetLocDlgJButton");
        jbutton.setBounds(40, 50, 300, 200);
        jbutton.setName("JButton");

        jchkBox = new JCheckBox("SetLocDlgJCheckBox");
        jchkBox.setBounds(40, 50,300,200);
        jchkBox.setName("JCheckBox");

        jlabel = new JLabel("SetLocDlgJLabel");
        jlabel.setName("JLabel");
        jlabel.setBounds(40, 50, 200, 200);

        String[] jdata = {"JItem 1", "JItem 2", "JItem 3", "JItem 4"};
        jlist = new JList(jdata);
        jlist.setBounds(40, 50, 200, 200);
        jlist.setName("JList");

        jscrollbar = new JScrollBar();
        jscrollbar.setBounds(40, 50, 200, 200);
        jscrollbar.setName("JScrollBar");

        jtextArea = new JTextArea("SetLocDlgJTextArea", 4, 5);
        jtextArea.setBounds(40, 50, 200, 200);
        jtextArea.setName("JTextArea");

        jtextField = new JTextField("SetLocDlgJTextField", 1);
        jtextField.setBounds(40, 50, 200, 200);
        jtextField.setName("JTextField");

        comp_pt = new Point();
        dlg_pt = new Point();

        testDlg = new JDialog(frame, "Test Dialog");
        testDlg.setSize(200, 100);
        testDlg.setBackground(Color.yellow);

        // a vector is created to have set of components
        vector = new Vector(16);

        vector.add(jbutton);
        vector.add(jchkBox);
        vector.add(jlabel);
        vector.add(jscrollbar);
        vector.add(jlist);
        vector.add(jtextArea);
        vector.add(jtextField);

        dialog.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent event) {
                /*testDlg.setVisible(false);
                dialog.getContentPane().removeAll();
                dialog.setVisible(false);*/
            }
        });


        Frame f = new Frame("ControllerFrame");
        f.setLayout(new FlowLayout());
        f.setSize(CONTROLLER_SIZE, CONTROLLER_SIZE);
        showComponent = new Button("Show Component");
        showComponent.addActionListener(this);
        showDialog = new Button("Show Dialog");
        showDialog.addActionListener(this);
        f.add(showComponent);
        f.add(showDialog);
        f.setLocation(CONTROLLER_X, 0);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            WORK_DIR = System.getProperty("resultsDir");
            if (WORK_DIR == null || WORK_DIR.equals("")) {
                System.err.println("ERROR: resultsDir not set!");
                System.exit(1);
            }
            SetLocSwingDlgTest test = new SetLocSwingDlgTest();
            test.doTest();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (event.getSource().equals(showComponent)) {
            dialog.getContentPane().add((JComponent) vector.get(componentCount));
            dialog.setVisible(true);
        } else {
            testDlg.setLocationRelativeTo((JComponent) vector.get(componentCount));
            testDlg.setVisible(true);
            /*componentCount++;
            if (componentCount == vector.size()) {
                System.exit(0);
            }*/
        }
        actionPerformed = true;
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    private void doTest() throws Exception {

        Robot robot = new Robot();
        robot.delay(5000);

        for (componentCount = 0; componentCount < vector.size(); componentCount++) {
            c = (JComponent) vector.get(componentCount);

            actionPerformed = false;
            robot.mouseMove(showComponent.getLocationOnScreen().x + showComponent.getSize().width / 2,
                            showComponent.getLocationOnScreen().y + showComponent.getSize().height / 2);
            robot.delay(500);
            robot.mousePress(MouseEvent.BUTTON1_MASK);
            robot.delay(500);
            robot.mouseRelease(MouseEvent.BUTTON1_MASK);

            if (! actionPerformed) {
                synchronized (lock) {
                    lock.wait(5000);
                }
            }
            if (! actionPerformed) {
                System.err.println("FAIL: ActionEvent not generated after pressing Show Component " +
                                   "button when testing for component " + componentCount);
                captureScreenAndSave();
                passed = false;
            }
            robot.delay(5000);

            actionPerformed = false;
            robot.mouseMove(showDialog.getLocationOnScreen().x + showDialog.getSize().width / 2,
                            showDialog.getLocationOnScreen().y + showDialog.getSize().height / 2);
            robot.delay(500);
            robot.mousePress(MouseEvent.BUTTON1_MASK);
            robot.delay(500);
            robot.mouseRelease(MouseEvent.BUTTON1_MASK);

            if (! actionPerformed) {
                synchronized (lock) {
                    lock.wait(5000);
                }
            }
            if (! actionPerformed) {
                System.err.println("FAIL: ActionEvent not generated after pressing Show Dialog " +
                                   "button when testing for component " + componentCount);
                captureScreenAndSave();
                passed = false;
            }
            robot.delay(3000);

            Point comp_pt = c.getLocationOnScreen();

            Point dlg_pt = testDlg.getLocationOnScreen();

            //gets the center of the Dialog and component and compares both
            int comp_x = c.getWidth()/2;
            int comp_y = c.getHeight()/2;

            int dlgx = testDlg.getWidth()/2;
            int dlgy = testDlg.getHeight()/2;

            int c_location_x = comp_pt.x;
            int c_location_y = comp_pt.y;

            int dlg_location_x = dlg_pt.x;
            int dlg_location_y = dlg_pt.y;

            int c_center_x = comp_x + c_location_x;
            int c_center_y = comp_y + c_location_y;

            int dlg_center_x = dlgx + dlg_location_x;
            int dlg_center_y = dlgy + dlg_location_y;

            System.out.println("The center of the component " + c.getName() +
                               " is (" + c_center_x + "," + c_center_y + ")");
            System.out.println("The center of the Dialog is (" + dlg_center_x +
                               "," + dlg_center_y + ")");

            //The getLocationOnScreen() returns with decoration on windows and not on X-Windows
            //Hence the Frame Insets are added for X and Y
            if ((c_center_x == dlg_center_x ||
                 c_center_x < dlg_center_x + testDlg.getInsets().left) &&
                (c_center_y == dlg_center_y ||
                 c_center_y < dlg_center_y + testDlg.getInsets().top)) {
                System.out.println("PASS: The Dialog is moved relative to the component " + c.getName());
            } else {
                passed = false;
                captureScreenAndSave();
                System.err.println("FAIL: The Dialog is not moved relative to the component " + c.getName());
            }

            try {
                Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
                    public void run() {
                        testDlg.setVisible(false);
                        dialog.remove(c);
                        dialog.dispose();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
            robot.delay(delay * 6);
        }

        if (! passed) {
            System.err.println("Test failed!");
            System.exit(1);
        } else {
            System.out.println("Test passed!");
            System.exit(0);
        }
    }

    /**
     * Do screen capture and save it as image
     */
    private static void captureScreenAndSave() {

        try {
            Robot robot = new Robot();
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Rectangle rectangle = new Rectangle(0, 0, screenSize.width, screenSize.height);
            java.awt.image.BufferedImage image = robot.createScreenCapture(rectangle);
            count++;
            System.err.println("About to screen capture - ScreenImage" + count + ".jpg");
            javax.imageio.ImageIO.write(image, "jpg", new File(WORK_DIR,
                                                               "ScreenImage" +
                                                               count + ".jpg"));
            robot.delay(3000);
        } catch (Throwable t) {
            System.out.println("WARNING: Exception thrown while screen capture!");
            t.printStackTrace();
        }
    }
}
