/*
 * Copyright (c) 2007, 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 6608456
 * @author Igor Kushnirskiy
 * @summary tests if delegate RepaintManager gets invoked.
 */

import java.awt.*;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

import javax.swing.JComponent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;



public class bug6608456 {
    private static final TestFuture testFuture = new TestFuture();
    public static void main(String[] args) throws Exception {
        final JComponent component = invokeAndWait(
            new Callable<JComponent>() {
                public JComponent call() throws Exception {
                    RepaintManager.setCurrentManager(new TestRepaintManager());
                    JFrame frame = new JFrame("test");
                    frame.setLayout(new FlowLayout());
                    JButton button = new JButton("default");

                    frame.add(button);
                    button = new JButton("delegate");
                    if ( ! registerDelegate(
                             button, new TestRepaintManager())) {
                        return null;
                    }
                    frame.add(button);
                    frame.pack();
                    frame.setVisible(true);
                    return button;
                }
            });
        if (component == null) {
            throw new RuntimeException("failed. can not register delegate");
        }
        blockTillDisplayed(component);
        // trigger repaint for delegate RepaintManager
        invokeAndWait(
            new Callable<Void>() {
                public Void call() {
                    component.repaint();
                    return null;
                }
        });
        try {
            if (testFuture.get(10, TimeUnit.SECONDS)) {
                // passed
            }
        } catch (Exception e) {
            throw new RuntimeException("failed", e);
        } finally {
            JFrame frame = (JFrame) SwingUtilities
                .getAncestorOfClass(JFrame.class, component);
            if (frame != null) {
                frame.dispose();
            }
        }
    }
    static class TestRepaintManager extends RepaintManager {
        @Override
        public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
            if (RepaintManager.currentManager(c) == this) {
                testFuture.defaultCalled();
            } else {
                testFuture.delegateCalled();
            }
            super.addDirtyRegion(c, x, y, w, h);
        }
    }
    static class TestFuture extends FutureTask<Boolean> {
        private volatile boolean defaultCalled = false;
        private volatile boolean delegateCalled = false;
        public TestFuture() {
            super(new Callable<Boolean>() {
                public Boolean call() {
                    return null;
                }
            });
        }
        public void defaultCalled() {
            defaultCalled = true;
            updateState();
        }
        public void delegateCalled() {
            delegateCalled = true;
            updateState();
        }
        private void updateState() {
            if (defaultCalled && delegateCalled) {
                set(Boolean.TRUE);
            }
        }
    }

    private static boolean registerDelegate(JComponent c,
            RepaintManager repaintManager) {
        boolean rv = false;
        try {
            Class<?> clazz = Class.forName("com.sun.java.swing.SwingUtilities3");
            Method method = clazz.getMethod("setDelegateRepaintManager",
                JComponent.class, RepaintManager.class);
            method.invoke(clazz, c, repaintManager);
            rv = true;
        } catch (Exception ignore) {
        }
        return rv;
    }
    static <T> T invokeAndWait(Callable<T> callable) throws Exception {
        FutureTask<T> future = new FutureTask<T>(callable);
        SwingUtilities.invokeLater(future);
        return future.get();
    }

    public static void blockTillDisplayed(Component comp) {
        Point p = null;
        while (p == null) {
            try {
                p = comp.getLocationOnScreen();
            } catch (IllegalStateException e) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ie) {
                }
            }
        }
    }
}
