/*
 * $Id: JXApplet.java 4175 2012-05-30 16:57:33Z kschaefe $
 *
 * Copyright 2010 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jdesktop.swingx;

import java.awt.HeadlessException;
import java.awt.IllegalComponentStateException;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.Callable;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

/**
 * An applet that uses {@link JXRootPane} as its root container.
 * 
 * @author kschaefer
 */
@SuppressWarnings("nls")
public class JXApplet extends JApplet {
    private static final long serialVersionUID = 2L;

    /**
     * Creates a the applet instance.
     * <p>
     * This constructor sets the component's locale property to the value returned by
     * <code>JComponent.getDefaultLocale</code>.
     * 
     * @throws HeadlessException
     *             if GraphicsEnvironment.isHeadless() returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     * @see JComponent#getDefaultLocale
     */
    public JXApplet() throws HeadlessException {
        super();
    }

    /**
     * Overridden to create a JXRootPane and to ensure that the root pane is always created on the
     * Event Dispatch Thread. Some applet containers do not start applets on the EDT; this method,
     * therefore, protects against that. Actual, root pane creation occurs in
     * {@link #createRootPaneSafely()}.
     * 
     * @return the root pane for this applet
     * @see #createRootPaneSafely()
     */
    @Override
    protected final JXRootPane createRootPane() {
        if (SwingUtilities.isEventDispatchThread()) {
            return createRootPaneSafely();
        }
        
        try {
            return SwingXUtilities.invokeAndWait(new Callable<JXRootPane>() {
                @Override
                public JXRootPane call() throws Exception {
                    return createRootPaneSafely();
                }
            });
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (InvocationTargetException e) {
            IllegalComponentStateException thrown = new IllegalComponentStateException("cannot construct root pane");
            thrown.initCause(e);
            
            throw thrown;
        }
        
        return null;
    }
    
    /**
     * This method performs the actual creation of the root pane and is guaranteed to be performed on the Event Dispatch Thread.
     * <p>
     * Subclasses that need to configure the root pane or create a custom root pane should override this method.
     * 
     * @return the root pane for this applet
     */
    protected JXRootPane createRootPaneSafely() {
        JXRootPane rp = new JXRootPane();
        rp.setOpaque(true);
        
        return rp;
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JXRootPane getRootPane() {
        return (JXRootPane) super.getRootPane();
    }
    
    /**
     * Returns the value of the status bar property from the underlying
     * {@code JXRootPane}.
     * 
     * @return the {@code JXStatusBar} which is the current status bar
     * @see #setStatusBar(JXStatusBar)
     * @see JXRootPane#getStatusBar()
     */
    public JXStatusBar getStatusBar() {
        return getRootPane().getStatusBar();
    }
    
    /**
     * Sets the status bar property on the underlying {@code JXRootPane}.
     * 
     * @param statusBar
     *            the {@code JXStatusBar} which is to be the status bar
     * @see #getStatusBar()
     * @see JXRootPane#setStatusBar(JXStatusBar)
     */
    public void setStatusBar(JXStatusBar statusBar) {
        getRootPane().setStatusBar(statusBar);
    }
    
    /**
     * Returns the value of the tool bar property from the underlying
     * {@code JXRootPane}.
     * 
     * @return the {@code JToolBar} which is the current tool bar
     * @see #setToolBar(JToolBar)
     * @see JXRootPane#getToolBar()
     */
    public JToolBar getToolBar() {
        return getRootPane().getToolBar();
    }
    
    /**
     * Sets the tool bar property on the underlying {@code JXRootPane}.
     * 
     * @param toolBar
     *            the {@code JToolBar} which is to be the tool bar
     * @see #getToolBar()
     * @see JXRootPane#setToolBar(JToolBar)
     */
    public void setToolBar(JToolBar toolBar) {
        getRootPane().setToolBar(toolBar);
    }
    
    /**
     * Returns the value of the default button property from the underlying
     * {@code JRootPane}.
     * 
     * @return the {@code JButton} which is the default button
     * @see #setDefaultButton(JButton)
     * @see JRootPane#getDefaultButton()
     */
    public JButton getDefaultButton() {
        return getRootPane().getDefaultButton();
    }
    
    /**
     * Sets the default button property on the underlying {@code JRootPane}.
     * 
     * @param button
     *            the {@code JButton} which is to be the default button
     * @see #getDefaultButton()
     * @see JRootPane#setDefaultButton(JButton)
     */
    public void setDefaultButton(JButton button) {
        getRootPane().setDefaultButton(button);
    }
    
    /**
     * Returns the value of the cancel button property from the underlying
     * {@code JXRootPane}.
     * 
     * @return the {@code JButton} which is the cancel button
     * @see #setCancelButton(JButton)
     * @see JXRootPane#getCancelButton()
     */
    public JButton getCancelButton() {
        return getRootPane().getCancelButton();
    }

    /**
     * Sets the cancel button property on the underlying {@code JXRootPane}.
     * 
     * @param button
     *            the {@code JButton} which is to be the cancel button
     * @see #getCancelButton()
     * @see JXRootPane#setCancelButton(JButton)
     */
    public void setCancelButton(JButton button) {
        getRootPane().setCancelButton(button);
    }
}
