/*
 * Created on 22.07.2005
 *
 */
package org.jdesktop.swingx;

import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.util.logging.Logger;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRootPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

import org.jdesktop.swingx.JXRootPane.XRootLayout;
import org.jdesktop.test.AncientSwingTeam;
import org.jdesktop.test.PropertyChangeReport;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.Test;


    
/**
 * @author  Jeanette Winzenburg
 */
@RunWith(JUnit4.class)
public class JXRootPaneTest extends InteractiveTestCase {
 
    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(JXRootPaneTest.class
            .getName());
    
    
    /**
     * Issue #936-swingx: JXRootPane cannot cope with default laf decoration. 
     * 
     * testing implementation detail: layout's delegate is null by default
     */
    @Test
    public void testLayoutDelegateNull() {
        JXRootPane pane = new JXRootPane();
        assertTrue(pane.getLayout() instanceof XRootLayout);
        assertNull(((XRootLayout) pane.getLayout()).delegate);
    }
    
    /**
     * Issue #936-swingx: JXRootPane cannot cope with default laf decoration. 
     * 
     * testing implementation detail: layout's delegate is not null with laf decoration
     * 
     * How-to check if LAF supports laf decoration? Here we rely on default 
     * laf is metal which does support it
     */
    @Test
    public void testLayoutDelegateLAF() {
        // This test will not work in a headless configuration.
        if (GraphicsEnvironment.isHeadless()) {
            LOG.info("cannot run test - headless environment");
            return;
        }
        if (!UIManager.getLookAndFeel().getSupportsWindowDecorations()) {
            LOG.info("cannot run test - unsupported laf window decoration");
            return;
        }
        JFrame.setDefaultLookAndFeelDecorated(true);
        JXFrame frame = new JXFrame();
        JXRootPane pane = frame.getRootPaneExt();
        try {
            assertTrue(pane.getLayout() instanceof XRootLayout);
            assertNotNull(((XRootLayout) pane.getLayout()).delegate);
            pane.setWindowDecorationStyle(JRootPane.NONE);
            assertNull(((XRootLayout) pane.getLayout()).delegate);
        } finally {
            JFrame.setDefaultLookAndFeelDecorated(false);
        }
    }
    /**
     * Issue #936-swingx: JXRootPane cannot cope with default laf decoration. 
     * 
     * here the actual test: pref size with laf decoration 
     */
    @Test
    public void testLayoutWithLAFDecoration() {
        // This test will not work in a headless configuration.
        if (GraphicsEnvironment.isHeadless()) {
            LOG.info("cannot run testLAFDecorationLayout - headless environment");
            return;
        }
        if (!UIManager.getLookAndFeel().getSupportsWindowDecorations()) {
            LOG.info("cannot run test - unsupported laf window decoration");
            return;
        }
        
        JFrame.setDefaultLookAndFeelDecorated(true);
        JXFrame frame = new JXFrame();
        frame.add(new JXTable(new AncientSwingTeam()));
        frame.pack();
        Dimension dim = frame.getSize();
        assertEquals(dim, frame.getPreferredSize());
        JXStatusBar bar = new JXStatusBar();
        bar.add(new JLabel("need some content"));
        frame.setStatusBar(bar);
        frame.pack();
        try {
            assertEquals(dim.height + bar.getPreferredSize().height, frame.getPreferredSize().height);
        } finally {
            JFrame.setDefaultLookAndFeelDecorated(false);
        }
    }

    /**
     * Issue #936-swingx: JXRootPane cannot cope with default laf decoration. 
     * Compare: no laf decoration
     */
    @Test
    public void testLayoutWithOut() {
        // This test will not work in a headless configuration.
        if (GraphicsEnvironment.isHeadless()) {
            LOG.info("cannot run testLAFDecorationLayout - headless environment");
            return;
        }
        JXFrame frame = new JXFrame();
        frame.add(new JXTable(new AncientSwingTeam()));
        frame.pack();
        Dimension dim = frame.getSize();
        assertEquals(dim, frame.getPreferredSize());
        JXStatusBar bar = new JXStatusBar();
        bar.add(new JLabel("need some content"));
        frame.setStatusBar(bar);
        frame.pack();
        try {
            assertEquals(dim.height + bar.getPreferredSize().height, frame.getPreferredSize().height);
        } finally {
            JFrame.setDefaultLookAndFeelDecorated(false);
        }
    }

    /**
     * Issue #566: JXRootPane eats escape from popups (JXDatePicker).
     *
     */
    @Test
    public void testDefaultCancel() {
        JXRootPane rootPane = new JXRootPane();
        assertNull(rootPane.getCancelButton());
        Action action = rootPane.getActionMap().get("esc-action");
        assertFalse(action.isEnabled());
    }
    
    /**
     * Test setStatusBar analogous to setToolBar 
     * (triggered by 
     * Issue #499-swingx: old toolbar not removed on setting new).
     * 
     * had not been broken. 
     */
    @Test
    public void testStatusBarSet() {
        JXRootPane rootPane = new JXRootPane();
        JXStatusBar toolBar = new JXStatusBar();
        rootPane.setStatusBar(toolBar);
        assertTrue(SwingUtilities.isDescendingFrom(toolBar, rootPane));
        rootPane.setStatusBar(new JXStatusBar());
        assertFalse(SwingUtilities.isDescendingFrom(toolBar, rootPane));
    }
    
    /**
     * Test setStatusBar analogous to setToolBar 
     * (triggered by 
     * Issue #499-swingx: old toolbar not removed on setting new).
     *
     * Additional fix: rootPane must fire property change event on
     * setStatusBar. 
     * 
     */
    @Test
    public void testStatusBarFirePropertyChange() {
        JXRootPane rootPane = new JXRootPane();
        JXStatusBar toolBar = new JXStatusBar();
        rootPane.setStatusBar(toolBar);
        assertTrue(SwingUtilities.isDescendingFrom(toolBar, rootPane));
        PropertyChangeReport report = new PropertyChangeReport();
        rootPane.addPropertyChangeListener(report);
        rootPane.setStatusBar(new JXStatusBar());
        assertEquals("set statusBar must have fire exactly one property change", 1, report.getEventCount());
        assertTrue(report.hasEvents("statusBar"));
    }

    /**
     * Issue #499-swingx: old toolbar not removed on setting new.
     *
     */
    @Test
    public void testToolBarSet() {
        JXRootPane rootPane = new JXRootPane();
        JToolBar toolBar = new JToolBar();
        rootPane.setToolBar(toolBar);
        assertTrue(SwingUtilities.isDescendingFrom(toolBar, rootPane));
        rootPane.setToolBar(new JToolBar());
        assertFalse(SwingUtilities.isDescendingFrom(toolBar, rootPane));
    }
    
    /**
     * Issue #499-swingx: old toolbar not removed on setting new.
     *
     * Additional fix: rootPane must fire property change event on
     * setToolBar. 
     * 
     * PENDING: similar issue with statusbar?
     */
    @Test
    public void testToolBarFirePropertyChange() {
        JXRootPane rootPane = new JXRootPane();
        JToolBar toolBar = new JToolBar();
        rootPane.setToolBar(toolBar);
        assertTrue(SwingUtilities.isDescendingFrom(toolBar, rootPane));
        PropertyChangeReport report = new PropertyChangeReport();
        rootPane.addPropertyChangeListener(report);
        rootPane.setToolBar(new JToolBar());
        assertEquals(1, report.getEventCount());
        assertTrue(report.hasEvents("toolBar"));
    }
    /**
     * Issue #66-swingx: setStatusBar(null) throws NPE.
     *
     */
    @Test
    public void testStatusBarNPE() {
        JXRootPane rootPane = new JXRootPane();
        rootPane.setStatusBar(null);
    }
    
    public void interactiveTestStatusBar() {
        JXTable table = new JXTable(new DefaultTableModel(10, 3));
        final JXFrame frame = wrapWithScrollingInFrame(table, "Statusbar");
        Action action = new AbstractAction("toggle StatusBar") {

            public void actionPerformed(ActionEvent e) {
                JXStatusBar bar = frame.getRootPaneExt().getStatusBar();
                frame.getRootPaneExt().setStatusBar(bar != null ? null : new JXStatusBar());
                frame.getRootPaneExt().revalidate();
            }
            
        };
        addAction(frame, action);
        frame.setVisible(true);
    }
    
    public static void main(String args[]) {
        setSystemLF(true);
        JXRootPaneTest test = new JXRootPaneTest();
        try {
          test.runInteractiveTests();
//            test.runInteractiveTests("interactive.*ColumnControlColumnModel.*");
//            test.runInteractiveTests("interactive.*TableHeader.*");
       //     test.runInteractiveTests("interactive.*Sort.*");
//            test.runInteractiveTests("interactive.*ColumnControlAndF.*");
//            test.runInteractiveTests("interactive.*RowHeight.*");
        } catch (Exception e) {
            System.err.println("exception when executing interactive tests:");
            e.printStackTrace();
        }
    }

}
