/* BasicInternalFrameUI.java --
   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.plaf.basic;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.AbstractBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InternalFrameUI;
import javax.swing.plaf.UIResource;

/**
 * This is the UI delegate for the Basic look and feel for JInternalFrames.
 */
public class BasicInternalFrameUI extends InternalFrameUI
{
  /**
   * This is a helper class that listens to the JInternalFrame for
   * InternalFrameEvents.
   */
  protected class BasicInternalFrameListener implements InternalFrameListener
  {
    /**
     * This method is called when the JInternalFrame is activated.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameActivated(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is closed.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameClosed(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is closing.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameClosing(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is deactivated.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameDeactivated(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is  deiconified.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameDeiconified(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is  iconified.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameIconified(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the JInternalFrame is opened.
     *
     * @param e The InternalFrameEvent.
     */
    public void internalFrameOpened(InternalFrameEvent e)
    {
      // FIXME: Implement.
    }
  }

  /**
   * This helper class listens to the edges of the JInternalFrame and the
   * TitlePane for mouse events. It is responsible for dragging  and resizing
   * the JInternalFrame in response to the MouseEvents.
   */
  protected class BorderListener extends MouseInputAdapter
    implements SwingConstants
  {
    /** FIXME: Use for something. */
    protected int RESIZE_NONE;

    /** The x offset from the top left corner of the JInternalFrame. */
    private transient int xOffset = 0;

    /** The y offset from the top left corner of the JInternalFrame. */
    private transient int yOffset = 0;

    /** The direction that the resize is occuring in. */
    private transient int direction = -1;

    /** Cache rectangle that can be reused. */
    private transient Rectangle cacheRect = new Rectangle();

    /**
     * This method is called when the mouse is clicked.
     *
     * @param e The MouseEvent.
     */
    public void mouseClicked(MouseEvent e)
    {
      // There is nothing to do when the mouse is clicked
      // on the border.
    }

    /**
     * This method is called when the mouse is dragged. This method is
     * responsible for resizing or dragging the JInternalFrame.
     *
     * @param e The MouseEvent.
     */
    public void mouseDragged(MouseEvent e)
    {
      // If the frame is maximized, there is nothing that 
      // can be dragged around.
      if (frame.isMaximum())
	return;
      DesktopManager dm = getDesktopManager();
      Rectangle b = frame.getBounds();
      Dimension min = frame.getMinimumSize();
      if (min == null)
	min = new Dimension(0, 0);
      Insets insets = frame.getInsets();
      int x = e.getX();
      int y = e.getY();
      if (e.getSource() == frame && frame.isResizable())
        {
	  switch (direction)
	    {
	    case NORTH:
	      cacheRect.setBounds(b.x,
	                          Math.min(b.y + y, b.y + b.height
	                                   - min.height), b.width, b.height
	                          - y);
	      break;
	    case NORTH_EAST:
	      cacheRect.setBounds(b.x,
	                          Math.min(b.y + y, b.y + b.height
	                                   - min.height), x, b.height - y);
	      break;
	    case EAST:
	      cacheRect.setBounds(b.x, b.y, x, b.height);
	      break;
	    case SOUTH_EAST:
	      cacheRect.setBounds(b.x, b.y, x, y);
	      break;
	    case SOUTH:
	      cacheRect.setBounds(b.x, b.y, b.width, y);
	      break;
	    case SOUTH_WEST:
	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
	                          b.y, b.width - x, y);
	      break;
	    case WEST:
	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
	                          b.y, b.width - x, b.height);
	      break;
	    case NORTH_WEST:
	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
	                          Math.min(b.y + y, b.y + b.height
	                                   - min.height), b.width - x,
	                          b.height - y);
	      break;
	    }
	  dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
	                 Math.max(min.width, cacheRect.width),
	                 Math.max(min.height, cacheRect.height));
        }
      else if (e.getSource() == titlePane)
        {
	  Rectangle fBounds = frame.getBounds();

	  dm.dragFrame(frame, e.getX() - xOffset + b.x,
	               e.getY() - yOffset + b.y);
        }
    }

    /**
     * This method is called when the mouse exits the JInternalFrame.
     *
     * @param e The MouseEvent.
     */
    public void mouseExited(MouseEvent e)
    {
      // There is nothing to do when the mouse exits 
      // the border area.
    }

    /**
     * This method is called when the mouse is moved inside the
     * JInternalFrame.
     *
     * @param e The MouseEvent.
     */
    public void mouseMoved(MouseEvent e)
    {
      // There is nothing to do when the mouse moves
      // over the border area.
    }

    /**
     * This method is called when the mouse is pressed.
     *
     * @param e The MouseEvent.
     */
    public void mousePressed(MouseEvent e)
    {
      activateFrame(frame);
      DesktopManager dm = getDesktopManager();
      int x = e.getX();
      int y = e.getY();
      Insets insets = frame.getInsets();

      if (e.getSource() == frame && frame.isResizable())
        {
	  direction = sectionOfClick(x, y);
	  dm.beginResizingFrame(frame, direction);
        }
      else if (e.getSource() == titlePane)
        {
	  Rectangle tBounds = titlePane.getBounds();

	  xOffset = e.getX() - tBounds.x + insets.left;
	  yOffset = e.getY() - tBounds.y + insets.top;

	  dm.beginDraggingFrame(frame);
        }
    }

    /**
     * This method is called when the mouse is released.
     *
     * @param e The MouseEvent.
     */
    public void mouseReleased(MouseEvent e)
    {
      DesktopManager dm = getDesktopManager();
      xOffset = 0;
      yOffset = 0;
      if (e.getSource() == frame && frame.isResizable())
	dm.endResizingFrame(frame);
      else if (e.getSource() == titlePane)
	dm.endDraggingFrame(frame);
    }

    /**
     * This method determines the direction of the resize based on the
     * coordinates and the size of the JInternalFrame.
     *
     * @param x The x coordinate of the MouseEvent.
     * @param y The y coordinate of the MouseEvent.
     *
     * @return The direction of the resize (a SwingConstant direction).
     */
    private int sectionOfClick(int x, int y)
    {
      Insets insets = frame.getInsets();
      Rectangle b = frame.getBounds();
      if (x < insets.left && y < insets.top)
	return NORTH_WEST;
      else if (x > b.width - insets.right && y < insets.top)
	return NORTH_EAST;
      else if (x > b.width - insets.right && y > b.height - insets.bottom)
	return SOUTH_EAST;
      else if (x < insets.left && y > b.height - insets.bottom)
	return SOUTH_WEST;
      else if (y < insets.top)
	return NORTH;
      else if (x < insets.left)
	return WEST;
      else if (y > b.height - insets.bottom)
	return SOUTH;
      else if (x > b.width - insets.right)
	return EAST;

      return -1;
    }
  }

  /**
   * This helper class listens to the JDesktopPane that parents this
   * JInternalFrame and listens for resize events and resizes the
   * JInternalFrame appropriately.
   */
  protected class ComponentHandler implements ComponentListener
  {
    /**
     * This method is called when the JDesktopPane is hidden.
     *
     * @param e The ComponentEvent fired.
     */
    public void componentHidden(ComponentEvent e)
    {
      // Do nothing.
    }

    /**
     * This method is called when the JDesktopPane is moved.
     *
     * @param e The ComponentEvent fired.
     */
    public void componentMoved(ComponentEvent e)
    {
      // Do nothing.
    }

    /**
     * This method is called when the JDesktopPane is resized.
     *
     * @param e The ComponentEvent fired.
     */
    public void componentResized(ComponentEvent e)
    {
      if (frame.isMaximum())
        {
	  JDesktopPane pane = (JDesktopPane) e.getSource();
	  Insets insets = pane.getInsets();
	  Rectangle bounds = pane.getBounds();

	  frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
	                  bounds.width - insets.left - insets.right,
	                  bounds.height - insets.top - insets.bottom);
	  frame.revalidate();
	  frame.repaint();
        }

      // Sun also resizes the icons. but it doesn't seem to do anything.
    }

    /**
     * This method is called when the JDesktopPane is shown.
     *
     * @param e The ComponentEvent fired.
     */
    public void componentShown(ComponentEvent e)
    {
      // Do nothing.
    }
  }

  /**
   * This helper class acts as the LayoutManager for JInternalFrames.
   */
  public class InternalFrameLayout implements LayoutManager
  {
    /**
     * This method is called when the given Component is added  to the
     * JInternalFrame.
     *
     * @param name The name of the Component.
     * @param c The Component added.
     */
    public void addLayoutComponent(String name, Component c)
    {
    }

    /**
     * This method is used to set the bounds of the children of the
     * JInternalFrame.
     *
     * @param c The Container to lay out.
     */
    public void layoutContainer(Container c)
    {
      Dimension dims = frame.getSize();
      Insets insets = frame.getInsets();

      dims.width -= insets.left + insets.right;
      dims.height -= insets.top + insets.bottom;

      frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
                                                   dims.height);
      int nh = 0;
      int sh = 0;
      int ew = 0;
      int ww = 0;

      if (northPane != null)
        {
	  Dimension nDims = northPane.getPreferredSize();
	  nh = Math.min(nDims.height, dims.height);

	  northPane.setBounds(insets.left, insets.top, dims.width, nh);
        }

      if (southPane != null)
        {
	  Dimension sDims = southPane.getPreferredSize();
	  sh = Math.min(sDims.height, dims.height - nh);

	  southPane.setBounds(insets.left, insets.top + dims.height - sh,
	                      dims.width, sh);
        }

      int remHeight = dims.height - sh - nh;

      if (westPane != null)
        {
	  Dimension wDims = westPane.getPreferredSize();
	  ww = Math.min(dims.width, wDims.width);

	  westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
        }

      if (eastPane != null)
        {
	  Dimension eDims = eastPane.getPreferredSize();
	  ew = Math.min(eDims.width, dims.width - ww);

	  eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
	                     ew, remHeight);
        }

      int remWidth = dims.width - ww - ew;

      frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
                                    remWidth, remHeight);
    }

    /**
     * This method returns the minimum layout size.
     *
     * @param c The Container to find a minimum layout size for.
     *
     * @return The minimum dimensions for the JInternalFrame.
     */
    public Dimension minimumLayoutSize(Container c)
    {
      return getSize(c, true);
    }

    /**
     * This method returns the maximum layout size.
     *
     * @param c The Container to find a maximum layout size for.
     *
     * @return The maximum dimensions for the JInternalFrame.
     */
    public Dimension maximumLayoutSize(Container c)
    {
      return preferredLayoutSize(c);
    }

    /**
     * Th8is method returns the preferred layout size.
     *
     * @param c The Container to find a preferred layout size for.
     *
     * @return The preferred dimensions for the JInternalFrame.
     */
    public Dimension preferredLayoutSize(Container c)
    {
      return getSize(c, false);
    }

    /**
     * DOCUMENT ME!
     *
     * @param c DOCUMENT ME!
     * @param min DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    private Dimension getSize(Container c, boolean min)
    {
      Insets insets = frame.getInsets();

      Dimension contentDims = frame.getContentPane().getPreferredSize();
      if (min)
	contentDims.width = contentDims.height = 0;
      int nWidth = 0;
      int nHeight = 0;
      int sWidth = 0;
      int sHeight = 0;
      int eWidth = 0;
      int eHeight = 0;
      int wWidth = 0;
      int wHeight = 0;
      Dimension dims;

      if (northPane != null)
        {
	  dims = northPane.getPreferredSize();
	  if (dims != null)
	    {
	      nWidth = dims.width;
	      nHeight = dims.height;
	    }
        }

      if (southPane != null)
        {
	  dims = southPane.getPreferredSize();
	  if (dims != null)
	    {
	      sWidth = dims.width;
	      sHeight = dims.height;
	    }
        }

      if (eastPane != null)
        {
	  dims = eastPane.getPreferredSize();
	  if (dims != null)
	    {
	      sWidth = dims.width;
	      sHeight = dims.height;
	    }
        }

      if (westPane != null)
        {
	  dims = westPane.getPreferredSize();
	  if (dims != null)
	    {
	      wWidth = dims.width;
	      wHeight = dims.height;
	    }
        }

      int width = Math.max(sWidth, nWidth);
      width = Math.max(width, contentDims.width + eWidth + wWidth);

      int height = Math.max(eHeight, wHeight);
      height = Math.max(height, contentDims.height);
      height += nHeight + sHeight;

      width += insets.left + insets.right;
      height += insets.top + insets.bottom;

      return new Dimension(width, height);
    }

    /**
     * This method is called when a Component is removed from the
     * JInternalFrame.
     *
     * @param c The Component that was removed.
     */
    public void removeLayoutComponent(Component c)
    {
    }
  }

  /**
   * This helper class is used to listen to the JDesktopPane's glassPane for
   * MouseEvents. The JInternalFrame can then be selected if a click is
   * detected on its children.
   */
  protected class GlassPaneDispatcher implements MouseInputListener
  {
    /** The MouseEvent target. */
    private transient Component mouseEventTarget;

    /** The component pressed. */
    private transient Component pressedComponent;

    /** The last component entered. */
    private transient Component lastComponentEntered;

    /** The number of presses. */
    private transient int pressCount;

    /**
     * This method is called when the mouse enters the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseEntered(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method is called when the mouse is clicked on the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseClicked(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method is called when the mouse is dragged in the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseDragged(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method is called when the mouse exits the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseExited(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method is called when the mouse is moved in the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseMoved(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method is called when the mouse is  pressed in the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mousePressed(MouseEvent e)
    {
      activateFrame(frame);
      handleEvent(e);
    }

    /**
     * This method is called when the mouse is  released in the glass pane.
     *
     * @param e The MouseEvent.
     */
    public void mouseReleased(MouseEvent e)
    {
      handleEvent(e);
    }

    /**
     * This method acquires a candidate component to dispatch the  MouseEvent
     * to.
     *
     * @param me The MouseEvent to acquire a component for.
     */
    private void acquireComponentForMouseEvent(MouseEvent me)
    {
      int x = me.getX();
      int y = me.getY();

      // Find the candidate which should receive this event.
      Component parent = frame.getContentPane();
      if (parent == null)
	return;
      Component candidate = null;
      Point p = me.getPoint();
      while (candidate == null && parent != null)
        {
	  candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
	  if (candidate == null)
	    {
	      p = SwingUtilities.convertPoint(parent, p.x, p.y,
	                                      parent.getParent());
	      parent = parent.getParent();
	    }
        }

      // If the only candidate we found was the native container itself,
      // don't dispatch any event at all.  We only care about the lightweight
      // children here.
      if (candidate == frame.getContentPane())
	candidate = null;

      // If our candidate is new, inform the old target we're leaving.
      if (lastComponentEntered != null && lastComponentEntered.isShowing()
          && lastComponentEntered != candidate)
        {
	  Point tp = SwingUtilities.convertPoint(frame.getContentPane(), x, y,
	                                         lastComponentEntered);
	  MouseEvent exited = new MouseEvent(lastComponentEntered,
	                                     MouseEvent.MOUSE_EXITED,
	                                     me.getWhen(), me.getModifiersEx(),
	                                     tp.x, tp.y, me.getClickCount(),
	                                     me.isPopupTrigger(),
	                                     me.getButton());
	  lastComponentEntered.dispatchEvent(exited);
	  lastComponentEntered = null;
        }

      // If we have a candidate, maybe enter it.
      if (candidate != null)
        {
	  mouseEventTarget = candidate;
	  if (candidate.isLightweight() && candidate.isShowing()
	      && candidate != frame.getContentPane()
	      && candidate != lastComponentEntered)
	    {
	      lastComponentEntered = mouseEventTarget;
	      Point cp = SwingUtilities.convertPoint(frame.getContentPane(),
	                                             x, y, lastComponentEntered);
	      MouseEvent entered = new MouseEvent(lastComponentEntered,
	                                          MouseEvent.MOUSE_ENTERED,
	                                          me.getWhen(),
	                                          me.getModifiersEx(), cp.x,
	                                          cp.y, me.getClickCount(),
	                                          me.isPopupTrigger(),
	                                          me.getButton());
	      lastComponentEntered.dispatchEvent(entered);
	    }
        }

      if (me.getID() == MouseEvent.MOUSE_RELEASED
          || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
          || me.getID() == MouseEvent.MOUSE_DRAGGED)
	// If any of the following events occur while a button is held down,
	// they should be dispatched to the same component to which the
	// original MOUSE_PRESSED event was dispatched:
	//   - MOUSE_RELEASED
	//   - MOUSE_PRESSED: another button pressed while the first is held down
	//   - MOUSE_DRAGGED
	mouseEventTarget = pressedComponent;
      else if (me.getID() == MouseEvent.MOUSE_CLICKED)
        {
	  // Don't dispatch CLICKED events whose target is not the same as the
	  // target for the original PRESSED event.
	  if (candidate != pressedComponent)
	    mouseEventTarget = null;
	  else if (pressCount == 0)
	    pressedComponent = null;
        }
    }

    /**
     * This is a helper method that dispatches the GlassPane MouseEvents to
     * the proper component.
     *
     * @param e The AWTEvent to be dispatched. Usually an instance of
     *        MouseEvent.
     */
    private void handleEvent(AWTEvent e)
    {
      if (e instanceof MouseEvent)
        {
	  MouseEvent me = SwingUtilities.convertMouseEvent(frame.getRootPane()
	                                                        .getGlassPane(),
	                                                   (MouseEvent) e,
	                                                   frame.getRootPane()
	                                                        .getGlassPane());

	  acquireComponentForMouseEvent(me);

	  // Avoid dispatching ENTERED and EXITED events twice.
	  if (mouseEventTarget != null && mouseEventTarget.isShowing()
	      && e.getID() != MouseEvent.MOUSE_ENTERED
	      && e.getID() != MouseEvent.MOUSE_EXITED)
	    {
	      MouseEvent newEvt = SwingUtilities.convertMouseEvent(frame
	                                                           .getContentPane(),
	                                                           me,
	                                                           mouseEventTarget);
	      mouseEventTarget.dispatchEvent(newEvt);

	      switch (e.getID())
	        {
		case MouseEvent.MOUSE_PRESSED:
		  if (pressCount++ == 0)
		    pressedComponent = mouseEventTarget;
		  break;
		case MouseEvent.MOUSE_RELEASED:
		  // Clear our memory of the original PRESSED event, only if
		  // we're not expecting a CLICKED event after this. If
		  // there is a CLICKED event after this, it will do clean up.
		  if (--pressCount == 0
		      && mouseEventTarget != pressedComponent)
		    pressedComponent = null;
		  break;
	        }
	    }
        }
    }
  }

  /**
   * This helper class listens for PropertyChangeEvents from the
   * JInternalFrame.
   */
  public class InternalFramePropertyChangeListener
    implements PropertyChangeListener
  {
    /**
     * This method is called when one of the JInternalFrame's properties
     * change.
     *
     * @param evt The PropertyChangeEvent.
     */
    public void propertyChange(PropertyChangeEvent evt)
    {
      if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
        {
	  if (frame.isMaximum())
	    maximizeFrame(frame);
	  else
	    minimizeFrame(frame);
        }
      else if (evt.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
	closeFrame(frame);
      else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
        {
	  if (frame.isIcon())
	    iconifyFrame(frame);
	  else
	    deiconifyFrame(frame);
        }
      else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
        {
	  if (frame.isSelected())
	    activateFrame(frame);
	  else
	    getDesktopManager().deactivateFrame(frame);
        }
      else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
               || evt.getPropertyName().equals(JInternalFrame.GLASS_PANE_PROPERTY))
        {
	  Component old = (Component) evt.getOldValue();
	  old.removeMouseListener(glassPaneDispatcher);
	  old.removeMouseMotionListener(glassPaneDispatcher);

	  Component newPane = (Component) evt.getNewValue();
	  newPane.addMouseListener(glassPaneDispatcher);
	  newPane.addMouseMotionListener(glassPaneDispatcher);

	  frame.revalidate();
        }
      /* FIXME: need to add ancestor properties to JComponents.
      else if (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY))
      {
        if (desktopPane != null)
          desktopPane.removeComponentListener(componentListener);
        desktopPane = frame.getDesktopPane();
        if (desktopPane != null)
          desktopPane.addComponentListener(componentListener);
      }
      */
    }
  }

  /**
   * This helper class is the border for the JInternalFrame.
   */
  private class InternalFrameBorder extends AbstractBorder
    implements UIResource
  {
    /** The width of the border. */
    private static final int bSize = 5;

    /** The size of the corners. */
    private static final int offset = 10;

    /**
     * This method returns whether the border is opaque.
     *
     * @return Whether the border is opaque.
     */
    public boolean isBorderOpaque()
    {
      return true;
    }

    /**
     * This method returns the insets of the border.
     *
     * @param c The Component to find border insets for.
     *
     * @return The border insets.
     */
    public Insets getBorderInsets(Component c)
    {
      return new Insets(bSize, bSize, bSize, bSize);
    }

    /**
     * This method paints the border.
     *
     * @param c The Component that owns the border.
     * @param g The Graphics object to paint with.
     * @param x The x coordinate to paint at.
     * @param y The y coordinate to paint at.
     * @param width The width of the Component.
     * @param height The height of the Component.
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width,
                            int height)
    {
      g.translate(x, y);
      Color saved = g.getColor();
      Rectangle b = frame.getBounds();

      Color d = c.getBackground();
      g.setColor(d);
      g.fillRect(0, 0, bSize, b.height);
      g.fillRect(0, 0, b.width, bSize);
      g.fillRect(0, b.height - bSize, b.width, bSize);
      g.fillRect(b.width - bSize, 0, bSize, b.height);

      int x1 = 0;
      int x2 = bSize;
      int x3 = b.width - bSize;
      int x4 = b.width;

      int y1 = 0;
      int y2 = bSize;
      int y3 = b.height - bSize;
      int y4 = b.height;

      g.setColor(Color.GRAY);
      g.fillRect(0, 0, bSize, y4);
      g.fillRect(0, 0, x4, bSize);
      g.fillRect(0, y3, b.width, bSize);
      g.fillRect(x3, 0, bSize, b.height);

      g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
      g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
      g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
      g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);

      g.translate(-x, -y);
      g.setColor(saved);
    }
  }

  /**
   * The MouseListener that is responsible for dragging and resizing the
   * JInternalFrame in response to MouseEvents.
   */
  protected MouseInputAdapter borderListener;

  /**
   * The ComponentListener that is responsible for resizing the JInternalFrame
   * in response to ComponentEvents from the JDesktopPane.
   */
  protected ComponentListener componentListener;

  /**
   * The MouseListener that is responsible for activating the JInternalFrame
   * when the mouse press activates one of its descendents.
   */
  protected MouseInputListener glassPaneDispatcher;

  /**
   * The PropertyChangeListener that is responsible for listening to
   * PropertyChangeEvents from the JInternalFrame.
   */
  protected PropertyChangeListener propertyChangeListener;

  /** The InternalFrameListener that listens to the JInternalFrame. */
  private transient BasicInternalFrameListener internalFrameListener;

  /** The JComponent placed at the east region of the JInternalFrame. */
  protected JComponent eastPane;

  /** The JComponent placed at the north region of the JInternalFrame. */
  protected JComponent northPane;

  /** The JComponent placed at the south region of the JInternalFrame. */
  protected JComponent southPane;

  /** The JComponent placed at the west region of the JInternalFrame. */
  protected JComponent westPane;

  /**
   * The Keystroke bound to open the menu.
   * @deprecated
   */
  protected KeyStroke openMenuKey;

  /** The TitlePane displayed at the top of the JInternalFrame. */
  protected BasicInternalFrameTitlePane titlePane;

  /** The JInternalFrame this UI is responsible for. */
  protected JInternalFrame frame;

  /** The LayoutManager used in the JInternalFrame. */
  protected LayoutManager internalFrameLayout;

  /** The JDesktopPane that is the parent of the JInternalFrame. */
  private transient JDesktopPane desktopPane;

  /**
   * Creates a new BasicInternalFrameUI object.
   *
   * @param b The JInternalFrame this UI will represent.
   */
  public BasicInternalFrameUI(JInternalFrame b)
  {
  }

  /**
   * This method will create a new BasicInternalFrameUI for the given
   * JComponent.
   *
   * @param b The JComponent to create a BasicInternalFrameUI for.
   *
   * @return A new BasicInternalFrameUI.
   */
  public static ComponentUI createUI(JComponent b)
  {
    return new BasicInternalFrameUI((JInternalFrame) b);
  }

  /**
   * This method installs a UI for the JInternalFrame.
   *
   * @param c The JComponent to install this UI on.
   */
  public void installUI(JComponent c)
  {
    if (c instanceof JInternalFrame)
      {
	frame = (JInternalFrame) c;

	internalFrameLayout = createLayoutManager();
	frame.setLayout(internalFrameLayout);

	((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
	frame.getRootPane().getGlassPane().setVisible(true);

	installDefaults();
	installListeners();
	installComponents();
	installKeyboardActions();

	frame.setOpaque(true);
	titlePane.setOpaque(true);
	frame.invalidate();
      }
  }

  /**
   * This method reverses the work done by installUI.
   *
   * @param c The JComponent to uninstall this UI for.
   */
  public void uninstallUI(JComponent c)
  {
    uninstallKeyboardActions();
    uninstallComponents();
    uninstallListeners();
    uninstallDefaults();

    frame.setLayout(null);
    ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
    frame.getRootPane().getGlassPane().setVisible(false);

    frame = null;
  }

  /**
   * This method installs the defaults specified by the look and feel.
   */
  protected void installDefaults()
  {
    // FIXME: Move border to MetalBorders
    frame.setBorder(new InternalFrameBorder());
  }

  /**
   * This method installs the keyboard actions for the JInternalFrame.
   */
  protected void installKeyboardActions()
  {
    // FIXME: Implement.
  }

  /**
   * This method installs the Components for the JInternalFrame.
   */
  protected void installComponents()
  {
    setNorthPane(createNorthPane(frame));
    setSouthPane(createSouthPane(frame));
    setEastPane(createEastPane(frame));
    setWestPane(createWestPane(frame));
  }

  /**
   * This method installs the listeners for the JInternalFrame.
   */
  protected void installListeners()
  {
    glassPaneDispatcher = createGlassPaneDispatcher();
    createInternalFrameListener();
    borderListener = createBorderListener(frame);
    componentListener = createComponentListener();
    propertyChangeListener = createPropertyChangeListener();

    frame.addMouseListener(borderListener);
    frame.addMouseMotionListener(borderListener);
    frame.addInternalFrameListener(internalFrameListener);
    frame.addPropertyChangeListener(propertyChangeListener);

    frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
    frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
  }

  /**
   * This method uninstalls the defaults for the JInternalFrame.
   */
  protected void uninstallDefaults()
  {
    frame.setBorder(null);
  }

  /**
   * This method uninstalls the Components for the JInternalFrame.
   */
  protected void uninstallComponents()
  {
    setNorthPane(null);
    setSouthPane(null);
    setEastPane(null);
    setWestPane(null);
  }

  /**
   * This method uninstalls the listeners for the JInternalFrame.
   */
  protected void uninstallListeners()
  {
    if (desktopPane != null)
      desktopPane.removeComponentListener(componentListener);

    frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
    frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);

    frame.removePropertyChangeListener(propertyChangeListener);
    frame.removeInternalFrameListener(internalFrameListener);
    frame.removeMouseMotionListener(borderListener);
    frame.removeMouseListener(borderListener);

    propertyChangeListener = null;
    componentListener = null;
    borderListener = null;
    internalFrameListener = null;
    glassPaneDispatcher = null;
  }

  /**
   * This method uninstalls the keyboard actions for the JInternalFrame.
   */
  protected void uninstallKeyboardActions()
  {
    // FIXME: Implement.
  }

  /**
   * This method creates a new LayoutManager for the JInternalFrame.
   *
   * @return A new LayoutManager for the JInternalFrame.
   */
  protected LayoutManager createLayoutManager()
  {
    return new InternalFrameLayout();
  }

  /**
   * This method creates a new PropertyChangeListener for the JInternalFrame.
   *
   * @return A new PropertyChangeListener for the JInternalFrame.
   */
  protected PropertyChangeListener createPropertyChangeListener()
  {
    return new InternalFramePropertyChangeListener();
  }

  /**
   * This method returns the preferred size of the given JComponent.
   *
   * @param x The JComponent to find a preferred size for.
   *
   * @return The preferred size.
   */
  public Dimension getPreferredSize(JComponent x)
  {
    return internalFrameLayout.preferredLayoutSize(x);
  }

  /**
   * This method returns the minimum size of the given JComponent.
   *
   * @param x The JComponent to find a minimum size for.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumSize(JComponent x)
  {
    return internalFrameLayout.minimumLayoutSize(x);
  }

  /**
   * This method returns the maximum size of the given JComponent.
   *
   * @param x The JComponent to find a maximum size for.
   *
   * @return The maximum size.
   */
  public Dimension getMaximumSize(JComponent x)
  {
    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  }

  /**
   * This method replaces the currentPane with the newPane. When replacing it
   * also removes the MouseHandlers for the old pane and installs  them on
   * the new pane.
   *
   * @param currentPane The old pane to remove.
   * @param newPane The new pane to install.
   */
  protected void replacePane(JComponent currentPane, JComponent newPane)
  {
    if (currentPane != null)
      {
	deinstallMouseHandlers(currentPane);
	frame.remove(currentPane);
      }

    if (newPane != null)
      {
	installMouseHandlers(newPane);
	frame.add(newPane);
      }
  }

  /**
   * This method removes the necessary MouseListeners from the given
   * JComponent.
   *
   * @param c The JComponent to remove MouseListeners from.
   */
  protected void deinstallMouseHandlers(JComponent c)
  {
    c.removeMouseListener(borderListener);
    c.removeMouseMotionListener(borderListener);
  }

  /**
   * This method installs the necessary MouseListeners from the given
   * JComponent.
   *
   * @param c The JComponent to install MouseListeners on.
   */
  protected void installMouseHandlers(JComponent c)
  {
    c.addMouseListener(borderListener);
    c.addMouseMotionListener(borderListener);
  }

  /**
   * This method creates the north pane used in the JInternalFrame.
   *
   * @param w The JInternalFrame to create a north pane for.
   *
   * @return The north pane.
   */
  protected JComponent createNorthPane(JInternalFrame w)
  {
    titlePane = new BasicInternalFrameTitlePane(w);
    return titlePane;
  }

  /**
   * This method creates the west pane used in the JInternalFrame.
   *
   * @param w The JInternalFrame to create a west pane for.
   *
   * @return The west pane.
   */
  protected JComponent createWestPane(JInternalFrame w)
  {
    return null;
  }

  /**
   * This method creates the south pane used in the JInternalFrame.
   *
   * @param w The JInternalFrame to create a south pane for.
   *
   * @return The south pane.
   */
  protected JComponent createSouthPane(JInternalFrame w)
  {
    return null;
  }

  /**
   * This method creates the east pane used in the JInternalFrame.
   *
   * @param w The JInternalFrame to create an east pane for.
   *
   * @return The east pane.
   */
  protected JComponent createEastPane(JInternalFrame w)
  {
    return null;
  }

  /**
   * This method returns a new BorderListener for the given JInternalFrame.
   *
   * @param w The JIntenalFrame to create a BorderListener for.
   *
   * @return A new BorderListener.
   */
  protected MouseInputAdapter createBorderListener(JInternalFrame w)
  {
    return new BorderListener();
  }

  /**
   * This method creates a new InternalFrameListener for the JInternalFrame.
   */
  protected void createInternalFrameListener()
  {
    internalFrameListener = new BasicInternalFrameListener();
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  protected final boolean isKeyBindingRegistered()
  {
    // FIXME: Implement.
    return false;
  }

  /**
   * DOCUMENT ME!
   *
   * @param b DOCUMENT ME!
   */
  protected final void setKeyBindingRegistered(boolean b)
  {
    // FIXME: Implement.
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public final boolean isKeyBindingActive()
  {
    // FIXME: Implement.
    return false;
  }

  /**
   * DOCUMENT ME!
   *
   * @param b DOCUMENT ME!
   */
  protected final void setKeyBindingActive(boolean b)
  {
    // FIXME: Implement.
  }

  /**
   * DOCUMENT ME!
   */
  protected void setupMenuOpenKey()
  {
    // FIXME: Implement.
  }

  /**
   * DOCUMENT ME!
   */
  protected void setupMenuCloseKey()
  {
    // FIXME: Implement.
  }

  /**
   * This method returns the north pane.
   *
   * @return The north pane.
   */
  public JComponent getNorthPane()
  {
    return northPane;
  }

  /**
   * This method sets the north pane to be the given JComponent.
   *
   * @param c The new north pane.
   */
  public void setNorthPane(JComponent c)
  {
    replacePane(northPane, c);
    northPane = c;
  }

  /**
   * This method returns the south pane.
   *
   * @return The south pane.
   */
  public JComponent getSouthPane()
  {
    return southPane;
  }

  /**
   * This method sets the south pane to be the given JComponent.
   *
   * @param c The new south pane.
   */
  public void setSouthPane(JComponent c)
  {
    replacePane(southPane, c);
    southPane = c;
  }

  /**
   * This method sets the east pane to be the given JComponent.
   *
   * @param c The new east pane.
   */
  public void setEastPane(JComponent c)
  {
    replacePane(eastPane, c);
    eastPane = c;
  }

  /**
   * This method returns the east pane.
   *
   * @return The east pane.
   */
  public JComponent getEastPane()
  {
    return eastPane;
  }

  /**
   * This method sets the west pane to be the given JComponent.
   *
   * @param c The new west pane.
   */
  public void setWestPane(JComponent c)
  {
    replacePane(westPane, c);
    westPane = c;
  }

  /**
   * This method returns the west pane.
   *
   * @return The west pane.
   */
  public JComponent getWestPane()
  {
    return westPane;
  }

  /**
   * This method returns the DesktopManager to use with the JInternalFrame.
   *
   * @return The DesktopManager to use with the JInternalFrame.
   */
  protected DesktopManager getDesktopManager()
  {
    DesktopManager value = frame.getDesktopPane().getDesktopManager();
    if (value == null)
      value = createDesktopManager();
    return value;
  }

  /**
   * This method returns a default DesktopManager that can be used with this
   * JInternalFrame.
   *
   * @return A default DesktopManager that can be used with this
   *         JInternalFrame.
   */
  protected DesktopManager createDesktopManager()
  {
    return new DefaultDesktopManager();
  }

  /**
   * This is a convenience method that closes the JInternalFrame.
   *
   * @param f The JInternalFrame to close.
   */
  protected void closeFrame(JInternalFrame f)
  {
    getDesktopManager().closeFrame(f);
  }

  /**
   * This is a convenience method that maximizes the JInternalFrame.
   *
   * @param f The JInternalFrame to maximize.
   */
  protected void maximizeFrame(JInternalFrame f)
  {
    getDesktopManager().maximizeFrame(f);
  }

  /**
   * This is a convenience method that minimizes the JInternalFrame.
   *
   * @param f The JInternalFrame to minimize.
   */
  protected void minimizeFrame(JInternalFrame f)
  {
    getDesktopManager().minimizeFrame(f);
  }

  /**
   * This is a convenience method that iconifies the JInternalFrame.
   *
   * @param f The JInternalFrame to iconify.
   */
  protected void iconifyFrame(JInternalFrame f)
  {
    getDesktopManager().iconifyFrame(f);
  }

  /**
   * This is a convenience method that deiconifies the JInternalFrame.
   *
   * @param f The JInternalFrame to deiconify.
   */
  protected void deiconifyFrame(JInternalFrame f)
  {
    getDesktopManager().deiconifyFrame(f);
  }

  /**
   * This is a convenience method that activates the JInternalFrame.
   *
   * @param f The JInternalFrame to activate.
   */
  protected void activateFrame(JInternalFrame f)
  {
    getDesktopManager().activateFrame(f);
  }

  /**
   * This method returns a new ComponentListener for the JDesktopPane.
   *
   * @return A new ComponentListener.
   */
  protected ComponentListener createComponentListener()
  {
    return new ComponentHandler();
  }

  /**
   * This method returns a new GlassPaneDispatcher.
   *
   * @return A new GlassPaneDispatcher.
   */
  protected MouseInputListener createGlassPaneDispatcher()
  {
    return new GlassPaneDispatcher();
  }
}
