/*
 * Copyright (c) 2016, 2022, 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
 * @key headful
 * @bug 8150724 8151303
 * @author a.stepanov
 * @summary Check that correct resolution variants are chosen for icons
 *          when multiresolution image is used for their construction.
 *
 * @library /lib/client/
 * @build ExtendedRobot
 * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=1 MultiresolutionIconTest
 * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=2 MultiresolutionIconTest
 */


// TODO: please remove the "@requires" tag after 8151303 fix


import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.image.BaseMultiResolutionImage;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class MultiresolutionIconTest extends JFrame {

    private final static int SZ = 100;
    private final static int N = 5; // number of components

    private final static String SCALE = "sun.java2d.uiScale";
    private final static Color C1X = Color.RED;
    private final static Color C2X = Color.BLUE;

    private JLabel lbl;
    private JTabbedPane tabbedPane;

    private final ExtendedRobot r;

    private static BufferedImage generateImage(int sz, Color c) {

        BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB);
        Graphics g = img.getGraphics();
        g.setColor(c);
        g.fillRect(0, 0, sz, sz);
        return img;
    }

    public MultiresolutionIconTest(UIManager.LookAndFeelInfo lf) throws Exception {

        UIManager.setLookAndFeel(lf.getClassName());
        r = new ExtendedRobot();
        SwingUtilities.invokeAndWait(this::UI);
    }

    private void UI() {

        setUndecorated(true);

        BufferedImage img1x = generateImage(SZ / 2, C1X);
        BufferedImage img2x = generateImage(SZ, C2X);
        BaseMultiResolutionImage mri = new BaseMultiResolutionImage(
            new BufferedImage[]{img1x, img2x});
        Icon icon = new ImageIcon(mri);

        // hardcoded icon size for OS X (Mac OS X L&F) - see JDK-8151060
        BufferedImage tab1x = generateImage(16, C1X);
        BufferedImage tab2x = generateImage(32, C2X);
        BaseMultiResolutionImage tabMRI = new BaseMultiResolutionImage(
            new BufferedImage[]{tab1x, tab2x});
        Icon tabIcon = new ImageIcon(tabMRI);

        setSize((N + 1) * SZ, SZ);
        setLocation(50, 50);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridLayout(1, 1));

        JPanel p = new JPanel();
        p.setLayout(new GridLayout(1, N));

        JButton btn = new JButton(icon);
        p.add(btn);

        JToggleButton tbn = new JToggleButton(icon);
        p.add(tbn);

        JRadioButton rbn = new JRadioButton(icon);
        rbn.setHorizontalAlignment(SwingConstants.CENTER);
        p.add(rbn);

        JCheckBox cbx = new JCheckBox(icon);
        cbx.setHorizontalAlignment(SwingConstants.CENTER);
        p.add(cbx);

        lbl = new JLabel(icon);
        p.add(lbl);

        tabbedPane = new JTabbedPane(JTabbedPane.LEFT);
        tabbedPane.addTab("", tabIcon, p);
        getContentPane().add(tabbedPane);

        setResizable(false);
        setVisible(true);
    }

    private boolean checkPressedColor(int x, int y, Color ok) {

        r.mouseMove(x+5, y+5);
        r.waitForIdle();
        r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        r.waitForIdle(100);
        Color c = r.getPixelColor(x, y);
        r.waitForIdle(100);
        r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
        r.waitForIdle(100);
        if (!c.equals(ok)) { return false; }
        // check the icon's color hasn't changed
        // after the mouse was released
        c = r.getPixelColor(x, y);
        return c.equals(ok);
    }

    private boolean checkTabIcon(
        int xStart, int xEnd, int yStart, int yEnd, Color ok, Color nok) {

        for (int y = yStart; y < yEnd; y += 2) {
            for (int x = xStart; x < xEnd; x += 2) {
                Color c = r.getPixelColor(x, y);
                if (c.equals(nok)) { return false; }
                else if (c.equals(ok)) {
                    // shift a bit to avoid the selection effects
                    return checkPressedColor(x + 5, y + 5, ok);
                }
            }
        }

        return false; // didn't find the icon
    }


    private void doTest() {

        r.waitForIdle(2000);
        String scale = System.getProperty(SCALE);
        boolean is2x = "2".equals(scale);
        Color expected = is2x ? C2X : C1X;
        Color unexpected = is2x ? C1X : C2X;

        Point p = lbl.getLocationOnScreen();
        int x = p.x + lbl.getWidth() / 2;
        int y = p.y + lbl.getHeight() / 2;
        int w = lbl.getWidth();

        boolean ok = true, curr;
        Color c;
        String components[] = new String[]{
            "JLabel", "JCheckBox", "JRadioButton", "JToggleButton", "JButton"};
        for (int i = 0; i < N; i++) {

            curr = true;
            int t = x - i * w;

            // check icon color
            c = r.getPixelColor(t, y);
            System.out.print(components[i] + " icon: ");
            if (!c.equals(expected)) {
                curr = false;
            } else {
                // check icon color when mouse button pressed - see JDK-8151303
                curr = checkPressedColor(t, y, expected);
            }

            System.out.println(curr ? "ok" : "nok");
            ok = ok && curr;

            r.waitForIdle();
        }

        int x0 = tabbedPane.getLocationOnScreen().x;
        int x1 = x - ((N - 1) * w + w / 2);
        int y0 = getLocationOnScreen().y;
        int y1 = y0 + getHeight();
        curr = checkTabIcon(x0, x1, y0, y1, expected, unexpected);

        System.out.println("JTabbedPane icon: " + (curr ? "ok" : "nok"));
        ok = ok && curr;

        if (!ok) { throw new RuntimeException("test failed"); }

        r.waitForIdle();
        dispose();
    }

    public static void main(String[] args) throws Exception {

        for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) {
            // skip AquaL&F because Aqua icon darkening fails the test
            if (LF.getName().equalsIgnoreCase("Mac OS X")) {
                continue;
            }
            System.out.println("\nL&F: " + LF.getName());
            (new MultiresolutionIconTest(LF)).doTest();
        }
    }
}
