/* JWindow.java --
   Copyright (C) 2002, 2003, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.LayoutManager;
import java.awt.Window;
import java.awt.event.KeyEvent;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;

/**
 * Unlike JComponent derivatives, JWindow inherits from
 * java.awt.Window. But also lets a look-and-feel component to its work.
 *
 * @author Ronald Veldema (rveldema@cs.vu.nl)
 */
public class JWindow extends Window implements Accessible, RootPaneContainer
{
  /**
   * Provides accessibility support for <code>JWindow</code>.
   */
  protected class AccessibleJWindow extends Window.AccessibleAWTWindow
  {
    /**
     * Creates a new instance of <code>AccessibleJWindow</code>.
     */
    protected AccessibleJWindow()
    {
      super();
      // Nothing to do here.
    }
  }

  private static final long serialVersionUID = 5420698392125238833L;
  
  protected JRootPane rootPane;

  /**
   * @specnote rootPaneCheckingEnabled is false to comply with J2SE 5.0
   */
  protected boolean rootPaneCheckingEnabled = false;

  protected AccessibleContext accessibleContext;

  /**
   * Creates a new <code>JWindow</code> that has a shared invisible owner frame
   * as its parent.
   */
  public JWindow()
  {
    super(SwingUtilities.getOwnerFrame(null));
    windowInit();
  }

  /**
   * Creates a new <code>JWindow</code> that uses the specified graphics
   * environment. This can be used to open a window on a different screen for
   * example.
   *
   * @param gc the graphics environment to use
   */
  public JWindow(GraphicsConfiguration gc)
  {
    super(SwingUtilities.getOwnerFrame(null), gc);
    windowInit();
  }

  /**
   * Creates a new <code>JWindow</code> that has the specified
   * <code>owner</code> frame. If <code>owner</code> is <code>null</code>, then
   * an invisible shared owner frame is installed as owner frame.
   *
   * @param owner the owner frame of this window; if <code>null</code> a shared
   *        invisible owner frame is used
   */
  public JWindow(Frame owner)
  {
    super(SwingUtilities.getOwnerFrame(owner));
    windowInit();
  }

  /**
   * Creates a new <code>JWindow</code> that has the specified
   * <code>owner</code> window. If <code>owner</code> is <code>null</code>,
   * then an invisible shared owner frame is installed as owner frame.
   *
   * @param owner the owner window of this window; if <code>null</code> a
   *        shared invisible owner frame is used
   */
  public JWindow(Window owner)
  {
    super(SwingUtilities.getOwnerFrame(owner));
    windowInit();
  }

  /**
   * Creates a new <code>JWindow</code> for the given graphics configuration
   * and that has the specified <code>owner</code> window. If
   * <code>owner</code> is <code>null</code>, then an invisible shared owner
   * frame is installed as owner frame.
   *
   * The <code>gc</code> parameter can be used to open the window on a
   * different screen for example.
   *
   * @param owner the owner window of this window; if <code>null</code> a
   *        shared invisible owner frame is used
   * @param gc the graphics configuration to use
   */
  public JWindow(Window owner, GraphicsConfiguration gc)
  {
    super(SwingUtilities.getOwnerFrame(owner), gc);
    windowInit();
  }

  protected void windowInit()
  {
    // We need to explicitly enable events here so that our processKeyEvent()
    // and processWindowEvent() gets called.
    enableEvents(AWTEvent.KEY_EVENT_MASK);

    super.setLayout(new BorderLayout(1, 1));
    getRootPane(); // will do set/create
    // Now we're done init stage, adds and layouts go to content pane.
    setRootPaneCheckingEnabled(true);
  }

  public Dimension getPreferredSize()
  {
    return super.getPreferredSize();
  }

  public void setLayout(LayoutManager manager)
  {
    // Check if we're in initialization stage.  If so, call super.setLayout
    // otherwise, valid calls go to the content pane.
    if (isRootPaneCheckingEnabled())
      getContentPane().setLayout(manager);
    else
      super.setLayout(manager);
  }

  public void setLayeredPane(JLayeredPane layeredPane)
  {
    getRootPane().setLayeredPane(layeredPane);
  }

  public JLayeredPane getLayeredPane()
  {
    return getRootPane().getLayeredPane();
  }

  public JRootPane getRootPane()
  {
    if (rootPane == null)
      setRootPane(createRootPane());
    return rootPane;
  }

  protected void setRootPane(JRootPane root)
  {
    if (rootPane != null)
      remove(rootPane);

    rootPane = root;
    add(rootPane, BorderLayout.CENTER);
  }

  protected JRootPane createRootPane()
  {
    return new JRootPane();
  }

  public Container getContentPane()
  {
    return getRootPane().getContentPane();
  }

  public void setContentPane(Container contentPane)
  {
    getRootPane().setContentPane(contentPane);
  }

  public Component getGlassPane()
  {
    return getRootPane().getGlassPane();
  }

  public void setGlassPane(Component glassPane)
  {
    getRootPane().setGlassPane(glassPane);
  }


  protected void addImpl(Component comp, Object constraints, int index)
  {
    // If we're adding in the initialization stage use super.add.
    // otherwise pass the add onto the content pane.
    if (isRootPaneCheckingEnabled())
      getContentPane().add(comp, constraints, index);
    else
      super.addImpl(comp, constraints, index);
  }

  public void remove(Component comp)
  {
    // If we're removing the root pane, use super.remove.  Otherwise
    // pass it on to the content pane instead.
    if (comp == rootPane)
      super.remove(rootPane);
    else
      getContentPane().remove(comp);
  }

  protected boolean isRootPaneCheckingEnabled()
  {
    return rootPaneCheckingEnabled;
  }

  protected void setRootPaneCheckingEnabled(boolean enabled)
  {
    rootPaneCheckingEnabled = enabled;
  }

  public void update(Graphics g)
  {
    paint(g);
  }

  protected void processKeyEvent(KeyEvent e)
  {
    super.processKeyEvent(e);
  }

  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJWindow();
    return accessibleContext;
  }

  protected String paramString()
  {
    return "JWindow";
  }
}
