/*
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */


import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.LayerUI;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * @author Sergey Bylokhov
 */
public abstract class JLayerFunctionalPaintTest {
    private static final String WORK_DIR = System.getProperty("resultsDir");
    private static JFrame frame;
    private static volatile int step = 0;
    private volatile JComponent comp;
    //Component coordinate
    private volatile int x;
    private volatile int y;

    static {
        if (null == WORK_DIR || WORK_DIR.trim().isEmpty()) {
            System.err.println("ERROR: resultsDir not set!");
            System.exit(1);
        }
    }

    /**
     * @throws Exception if some errors occurred.
     */
    public void runTest() throws Exception {
        //avoid accidental mouse events before test start.
        final Robot robot = new Robot();
        robot.mouseMove(0, 0);
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                comp = getNewComponent();
                comp.setBackground(new Color(128, 0, 0));
                createGUI(comp);
            }
        });
        Thread.sleep(1000);
        execute(comp, true);
        execute(comp, false);
    }

    public abstract JComponent getNewComponent();

    private void createGUI(final JComponent component) {
        final JPanel panel = new JPanel();
        panel.add(component);
        final JLayer jlayer = createLayer(panel);
        frame = new JFrame();
        frame.add(jlayer);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JLayer createLayer(final JComponent panel) {
        final LayerUI layerUI = new LayerUI() {
            @Override
            public void paint(final Graphics g, final JComponent c) {
                // paint the layer as is
                super.paint(g, c);
                // fill it with the translucent green
                g.setColor(new Color(0, 128, 0, 128));
                g.fillRect(0, 0, c.getWidth(), c.getHeight());
            }
        };
        return new JLayer(panel, layerUI);
    }

    private void execute(final JComponent comp,
            final boolean state) throws Exception {
        final Robot robot = new Robot();
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                comp.setEnabled(state);
                x = comp.getLocationOnScreen().x + comp.getWidth() / 2;
                y = comp.getLocationOnScreen().y + comp.getHeight() / 2;
            }
        });
        robot.waitForIdle();
        robot.mouseMove(x, y);
        robot.waitForIdle();
	Thread.sleep(1000);
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                captureFrame();
            }
        });
    }

    /**
     * Do screen capture and save it as image
     */
    private static void captureFrame() {
        try {
            final Robot robot = new Robot();
            final BufferedImage image =
                    robot.createScreenCapture(frame.getBounds());
            ImageIO.write(image, "png",
                    new File(WORK_DIR, "Frame" + step + ".png"));
            ++step;
        } catch (Throwable t) {
            System.out.println(
                    "WARNING: Exception thrown while screen capture!");
            t.printStackTrace();
        }
    }
}
