/* BasicInternalFrameUI.java --
   Copyright (C) 2004, 2005, 2006 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.plaf.basic;

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

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
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.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
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.ActionMapUIResource;
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)
    {
      frame.getGlassPane().setVisible(false);
    }

    /**
     * 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)
    {
      frame.getGlassPane().setVisible(true);
    }

    /**
     * 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
  {
    /**
     * The current shape of the cursor. 
     */
    transient int showingCursor;
    
    /** FIXME: Use for something. */
    protected final int RESIZE_NONE = 0;

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

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

    /** 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)
    {
      // Do minimization/maximization when double-clicking in the title pane.
      if (e.getSource() == titlePane && e.getClickCount() == 2)
        try
          {
            if (frame.isMaximizable() && ! frame.isMaximum())
              frame.setMaximum(true);
            else if (frame.isMaximum())
              frame.setMaximum(false);
          }
        catch (PropertyVetoException pve)
          {
            // We do nothing if the attempt has been vetoed.
          }
        
      // 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 Cursor.N_RESIZE_CURSOR:
              cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
                                                         - min.height),
                                  b.width, b.height - y);
              break;
            case Cursor.NE_RESIZE_CURSOR:
              cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
                                                         - min.height), x + 1,
                                  b.height - y);
              break;
            case Cursor.E_RESIZE_CURSOR:
              cacheRect.setBounds(b.x, b.y, x + 1, b.height);
              break;
            case Cursor.SE_RESIZE_CURSOR:
              cacheRect.setBounds(b.x, b.y, x + 1, y + 1);
              break;
            case Cursor.S_RESIZE_CURSOR:
              cacheRect.setBounds(b.x, b.y, b.width, y + 1);
              break;
            case Cursor.SW_RESIZE_CURSOR:
              cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
                                  b.y, b.width - x, y + 1);
              break;
            case Cursor.W_RESIZE_CURSOR:
              cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
                                  b.y, b.width - x, b.height);
              break;
            case Cursor.NW_RESIZE_CURSOR:
              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));
          setCursor(e);
        }
      else if (e.getSource() == titlePane)
        {
          Rectangle fBounds = frame.getBounds();
          frame.putClientProperty("bufferedDragging", Boolean.TRUE);
          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)
    {
      if (showingCursor != Cursor.DEFAULT_CURSOR)
        {
          frame.setCursor(Cursor.getDefaultCursor());
          showingCursor = Cursor.DEFAULT_CURSOR;
        }
    }

    /**
     * This method is called when the mouse is moved inside the JInternalFrame.
     * 
     * @param e The MouseEvent.
     */
    public void mouseMoved(MouseEvent e)
    {
      // Turn off the resize cursor if we are in the frame header.
      if (showingCursor != Cursor.DEFAULT_CURSOR && e.getSource() != frame)
        {
          frame.setCursor(Cursor.getDefaultCursor());
          showingCursor = Cursor.DEFAULT_CURSOR;
        }
      else if (e.getSource() == frame && frame.isResizable())
        {
          setCursor(e);
        }
    }
    
    /**
     * Set the mouse cursor, how applicable.
     * 
     * @param e the current mouse event.
     */
    void setCursor(MouseEvent e)
    {
      int cursor = sectionOfClick(e.getX(), e.getY());
      if (cursor != showingCursor)
        {
          Cursor resize = Cursor.getPredefinedCursor(cursor);
          frame.setCursor(resize);
          showingCursor = cursor;
        }
    }

    /**
     * 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);
          frame.putClientProperty("bufferedDragging", null);
        }
      
      setCursor(e);
    }

    /**
     * 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 cursor constant, determining the resizing direction.
     */
    private int sectionOfClick(int x, int y)
    {
      Rectangle b = frame.getBounds();
      int corner = InternalFrameBorder.cornerSize;
      
      if (x < corner && y < corner)
        return Cursor.NW_RESIZE_CURSOR;
      else if (x > b.width - corner && y < corner)
        return Cursor.NE_RESIZE_CURSOR;
      else if (x > b.width - corner && y > b.height - corner)
        return Cursor.SE_RESIZE_CURSOR;
      else if (x < corner && y > b.height - corner)
        return Cursor.SW_RESIZE_CURSOR;
      else if (y < corner)
        return Cursor.N_RESIZE_CURSOR;
      else if (x < corner)
        return Cursor.W_RESIZE_CURSOR;
      else if (y > b.height - corner)
        return Cursor.S_RESIZE_CURSOR;
      else if (x > b.width - corner)
        return Cursor.E_RESIZE_CURSOR;

      return Cursor.DEFAULT_CURSOR;
    }
  }

  /**
   * 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)
    {
      // Nothing to do here.
    }

    /**
     * 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;

      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);
    }

    /**
     * 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)
    {
      // Nothing to do here.
    }
  }

  /**
   * 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;

    private Component dragTarget;

    /**
     * Indicates if we are currently in a dragging operation or not.
     */
    private boolean isDragging;

    /**
     * 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)
    {
      // Experiments show that this seems to call the
      // borderListener.mousePressed() method to activate the frame.
      if (borderListener != null)
        borderListener.mousePressed(e);
      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 is a helper method that dispatches the GlassPane MouseEvents to the
     * proper component.
     * 
     * @param e the mouse event to be dispatched
     */
    private void handleEvent(MouseEvent e)
    {
      // Find candidate component inside the JInternalFrame.
      Component target = frame.getLayeredPane().findComponentAt(e.getX(),
                                                                e.getY());

      // Now search upwards to find a component that actually has
      // a MouseListener attached.
      while (target != null
             && target.getMouseListeners().length == 0
             && target.getMouseMotionListeners().length == 0
             && target.getMouseWheelListeners().length == 0)
        {
          target = target.getParent();
        }

      if (target != null)
        {
          int id = e.getID();
          switch (id)
          {
            case MouseEvent.MOUSE_ENTERED:
              // Now redispatch the thing.
              if (! isDragging || frame.isSelected())
                {
                  mouseEventTarget = target;
                  redispatch(id, e, mouseEventTarget);
                }
              break;
            case MouseEvent.MOUSE_EXITED:
              if (! isDragging || frame.isSelected())
                {
                  redispatch(id, e, mouseEventTarget);
                }
              break;
            case MouseEvent.MOUSE_PRESSED:
              mouseEventTarget = target;
              redispatch(id, e, mouseEventTarget);
              // Start dragging.
              dragTarget = target;
              break;
            case MouseEvent.MOUSE_RELEASED:
              if (isDragging)
                {
                  redispatch(id, e, dragTarget);
                  isDragging = false;
                }
              else
                redispatch(id, e, mouseEventTarget);
              break;
            case MouseEvent.MOUSE_CLICKED:
              redispatch(id, e, mouseEventTarget);
              break;
            case MouseEvent.MOUSE_MOVED:
              if (target != mouseEventTarget)
                {
                  // Create additional MOUSE_EXITED/MOUSE_ENTERED pairs.
                  redispatch(MouseEvent.MOUSE_EXITED, e, mouseEventTarget);
                  mouseEventTarget = target;
                  redispatch(MouseEvent.MOUSE_ENTERED, e, mouseEventTarget);
                }
              redispatch(id, e, mouseEventTarget);
              break;
            case MouseEvent.MOUSE_DRAGGED:
              if (! isDragging)
                isDragging = true;
              redispatch(id, e, mouseEventTarget);
              break;
            case MouseEvent.MOUSE_WHEEL:
              redispatch(id, e, mouseEventTarget);
              break;
            default:
              assert false : "Must not reach here";
          }
        }
    }

    /**
     * Redispatches the event to the real target with the specified id.
     *
     * @param id the new event ID
     * @param e the original event
     * @param target the real event target
     */
    private void redispatch(int id, MouseEvent e, Component target)
    {
      Point p = SwingUtilities.convertPoint(frame.getLayeredPane(), e.getX(),
                                            e.getY(), target);
      MouseEvent ev = new MouseEvent(target, id, e.getWhen(),
                                     e.getModifiers() | e.getModifiersEx(),
                                     p.x, p.y, e.getClickCount(),
                                     e.isPopupTrigger());
      target.dispatchEvent(ev);
    }
  }

  /**
   * 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)
    {
      String property = evt.getPropertyName();
      if (property.equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
        {
          if (frame.isMaximum())
            maximizeFrame(frame);
          else
            minimizeFrame(frame);
        }
      else if (property.equals(JInternalFrame.IS_ICON_PROPERTY))
        {
          if (frame.isIcon())
            iconifyFrame(frame);
          else
            deiconifyFrame(frame);
        }
      else if (property.equals(JInternalFrame.IS_SELECTED_PROPERTY))
        {
          Component glassPane = frame.getGlassPane();
          if (frame.isSelected())
            {
              activateFrame(frame);
              glassPane.setVisible(false);
            }
          else
            {
              deactivateFrame(frame);
              glassPane.setVisible(true);
            }
        }
      else if (property.equals(JInternalFrame.ROOT_PANE_PROPERTY)
               || property.equals(JInternalFrame.GLASS_PANE_PROPERTY))
        {
          Component old = (Component) evt.getOldValue();
          if (old != null)
            {
              old.removeMouseListener(glassPaneDispatcher);
              old.removeMouseMotionListener(glassPaneDispatcher);
            }

          Component newPane = (Component) evt.getNewValue();
          if (newPane != null)
            {
              newPane.addMouseListener(glassPaneDispatcher);
              newPane.addMouseMotionListener(glassPaneDispatcher);
            }

          frame.revalidate();
        }
      else if (property.equals(JInternalFrame.IS_CLOSED_PROPERTY))
        {
          if (evt.getNewValue() == Boolean.TRUE)
            {
              closeFrame(frame);
            }
        }
      /*
       * 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.
   */
  class InternalFrameBorder extends AbstractBorder implements
      UIResource
  {
    /** 
     * The width of the border. 
     */
    static final int bSize = 5;

    /**
     * The size of the corners (also used by the mouse listener).
     */
    static final int cornerSize = 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, cornerSize, bSize, b.height - 2 * cornerSize, false);
      g.fill3DRect(cornerSize, 0, b.width - 2 * cornerSize, bSize, false);
      g.fill3DRect(cornerSize, b.height - bSize, b.width - 2 * cornerSize, 
                   bSize, false);
      g.fill3DRect(b.width - bSize, cornerSize, bSize, 
                   b.height - 2 * cornerSize, false);

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

  /**
   * This action triggers the system menu.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  private class ShowSystemMenuAction
    extends AbstractAction
  {
    public void actionPerformed(ActionEvent e)
    {
      if (titlePane != null)
        {
          titlePane.showSystemMenu();
        }
    }
  }

  /**
   * 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)
  {
    // Nothing to do here.
  }

  /**
   * 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;

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

        if (! frame.isSelected())
          frame.getGlassPane().setVisible(true);
      }
  }

  /**
   * 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.getRootPane().getGlassPane().setVisible(false);
    frame = null;
  }

  /**
   * This method installs the defaults specified by the look and feel.
   */
  protected void installDefaults()
    {
      internalFrameLayout = createLayoutManager();
      frame.setLayout(internalFrameLayout);
      LookAndFeel.installBorder(frame, "InternalFrame.border");
      frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));

      // Let the content pane inherit the background color from its
      // frame by setting the background to null.
      Component contentPane = frame.getContentPane();
      if (contentPane != null
          && contentPane.getBackground() instanceof UIResource)
        {
          contentPane.setBackground(null);
        }
  }

  /**
   * This method installs the keyboard actions for the JInternalFrame.
   */
  protected void installKeyboardActions()
  {
    ActionMapUIResource am = new ActionMapUIResource();
    am.put("showSystemMenu", new ShowSystemMenuAction());

    // The RI impl installs the audio actions as parent of the UI action map,
    // so do we.
    BasicLookAndFeel blaf = (BasicLookAndFeel) UIManager.getLookAndFeel();
    ActionMap audioActionMap = blaf.getAudioActionMap();
    am.setParent(audioActionMap);

    SwingUtilities.replaceUIActionMap(frame, am);
  }

  /**
   * 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);
    frame.setLayout(null);
    internalFrameLayout = 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()
  {
    SwingUtilities.replaceUIActionMap(frame, null);
    SwingUtilities.replaceUIInputMap(frame, JComponent.WHEN_IN_FOCUSED_WINDOW,
                                     null);
  }

  /**
   * 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)
  {
    Dimension pref = null;
    LayoutManager layout = frame.getLayout();
    if (frame == x && layout != null)
      pref = layout.preferredLayoutSize(frame);
    else
      pref = new Dimension(100, 100);
    return pref;
  }

  /**
   * 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)
  {
    Dimension min = null;
    LayoutManager layout = frame.getLayout();
    if (frame == x && layout != null)
      min = layout.minimumLayoutSize(frame);
    else
      min = new Dimension(0, 0);
    return min;
  }

  /**
   * 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)
  {
    Dimension max = null;
    LayoutManager layout = frame.getLayout();
    if (frame == x && layout != null && layout instanceof LayoutManager2)
      max = ((LayoutManager2) layout).maximumLayoutSize(frame);
    else
      max = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    return max;
  }

  /**
   * 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 = null;
    JDesktopPane pane = frame.getDesktopPane();
    if (pane != null)
      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 is a convenience method that deactivates the JInternalFrame.
   *
   * @param f the JInternalFrame to deactivate
   */
  protected void deactivateFrame(JInternalFrame f)
  {
    getDesktopManager().deactivateFrame(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();
  }
}
