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

This file is part of GNU Classpath.

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

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

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

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

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


package javax.swing;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;
import java.beans.PropertyVetoException;
import java.io.Serializable;

import javax.swing.JInternalFrame.JDesktopIcon;

/**
 * The default implementation of DesktopManager for
 * Swing. It implements the basic beaviours for JInternalFrames in arbitrary
 * parents. The methods provided by the class are not meant to be called by
 * the user, instead, the JInternalFrame methods will call these methods.
 */
public class DefaultDesktopManager implements DesktopManager, Serializable
{
  /** DOCUMENT ME! */
  private static final long serialVersionUID = 4657624909838017887L;

  /** The property change event fired when the wasIcon property changes. */
  static final String WAS_ICON_ONCE_PROPERTY = "wasIconOnce";

  /**
   * The method of dragging used by the JDesktopPane that parents the
   * JInternalFrame that is being dragged.
   */
  private int currentDragMode = 0;

  /**
   * The cache of the bounds used to draw the outline rectangle when
   * OUTLINE_DRAG_MODE is used.
   */
  private transient Rectangle dragCache = new Rectangle();

  /**
   * A cached JDesktopPane that is stored when the JInternalFrame is initially
   * dragged.
   */
  private transient Container pane;

  /**
   * An array of Rectangles that holds the bounds of the JDesktopIcons in the
   * JDesktopPane when looking for where to place a new icon.
   */
  private transient Rectangle[] iconRects;

  /**
   * This creates a new DefaultDesktopManager object.
   */
  public DefaultDesktopManager()
  {
    // Nothing to do here.
  }

  /**
   * This method is not normally called since the user will typically add the
   * JInternalFrame to a Container. If this is called, it will try to
   * determine the parent of the JInternalFrame and remove any icon that
   * represents this JInternalFrame and add this JInternalFrame.
   *
   * @param frame The JInternalFrame to open.
   */
  public void openFrame(JInternalFrame frame)
  {
    Container c = frame.getParent();
    if (c == null)
      c = frame.getDesktopIcon().getParent();
    if (c == null)
      return;

    c.remove(frame.getDesktopIcon());
    c.add(frame);
    frame.setVisible(true);
  }

  /**
   * This method removes the JInternalFrame and JDesktopIcon (if one is
   * present) from their parents.
   *
   * @param frame The JInternalFrame to close.
   */
  public void closeFrame(JInternalFrame frame)
  {
    Container c = frame.getParent();
    if (c != null)
      {
	if (frame.isIcon())
	  c.remove(frame.getDesktopIcon());
	else
	  c.remove(frame);
	c.repaint();
      }
  }

  /**
   * This method resizes the JInternalFrame to match its parent's bounds.
   *
   * @param frame The JInternalFrame to maximize.
   */
  public void maximizeFrame(JInternalFrame frame)
  {
    // Can't maximize from iconified state.
    // It can only return to maximized state, but that would fall under
    // deiconify.
    if (frame.isIcon())
      return;
    frame.setNormalBounds(frame.getBounds());

    Container p = frame.getParent();
    if (p != null)
      {
	Rectangle pBounds = p.getBounds();
	Insets insets = p.getInsets();
	pBounds.width -= insets.left + insets.right;
	pBounds.height -= insets.top + insets.bottom;

	setBoundsForFrame(frame, 0, 0, pBounds.width, pBounds.height);
      }
    if (p instanceof JDesktopPane)
      ((JDesktopPane) p).setSelectedFrame(frame);
    else
      {
	try
	  {
	    frame.setSelected(true);
	  }
	catch (PropertyVetoException e)
	  {
	    // Do nothing.
	  }
      }
  }

  /**
   * This method restores the JInternalFrame's bounds to what they were
   * previous to the setMaximize call.
   *
   * @param frame The JInternalFrame to minimize.
   */
  public void minimizeFrame(JInternalFrame frame)
  {
    Rectangle normalBounds = frame.getNormalBounds();

    JDesktopPane p = frame.getDesktopPane();
    if (p != null)
      p.setSelectedFrame(frame);
    else
      {
        try
          {
            frame.setSelected(true);
          }
        catch (PropertyVetoException e)
          {
            // Do nothing.
          }
      }

    setBoundsForFrame(frame, normalBounds.x, normalBounds.y,
                      normalBounds.width, normalBounds.height);
  }

  /**
   * This method removes the JInternalFrame from its parent and adds its
   * JDesktopIcon representation.
   *
   * @param frame The JInternalFrame to iconify.
   */
  public void iconifyFrame(JInternalFrame frame)
  {
    JDesktopPane p = frame.getDesktopPane();
    JDesktopIcon icon = frame.getDesktopIcon();
    if (p != null && p.getSelectedFrame() == frame)
      p.setSelectedFrame(null);
    else
      {
        try
          {
            frame.setSelected(false);
          }
        catch (PropertyVetoException e)
          {
            // Do nothing if attempt is vetoed.
          }
      }

    Container c = frame.getParent();

    if (!wasIcon(frame))
      {
        Rectangle r = getBoundsForIconOf(frame);
        icon.setBounds(r);
        setWasIcon(frame, Boolean.TRUE);
      }

    if (c != null)
      {
        if (icon != null)
          {
            c.add(icon);
            icon.setVisible(true);
          }
        Rectangle b = frame.getBounds();
        c.remove(frame);
        c.repaint(b.x, b.y, b.width, b.height);
      }
  }

  /**
   * This method removes the JInternalFrame's JDesktopIcon representation and
   * adds the JInternalFrame back to its parent.
   *
   * @param frame The JInternalFrame to deiconify.
   */
  public void deiconifyFrame(JInternalFrame frame)
  {
    JDesktopIcon icon = frame.getDesktopIcon();
    Container c = icon.getParent();

    removeIconFor(frame);
    c.add(frame);
    frame.setVisible(true);

    if (!frame.isSelected())
      {
        JDesktopPane p = frame.getDesktopPane();
        if (p != null)
          p.setSelectedFrame(frame);
        else
          {
            try
              {
                frame.setSelected(true);
              }
            catch (PropertyVetoException e)
              {
                // Do nothing.
              }
          }
      }

    c.invalidate();
  }

  /**
   * This method activates the JInternalFrame by moving it to the front and
   * selecting it.
   *
   * @param frame The JInternalFrame to activate.
   */
  public void activateFrame(JInternalFrame frame)
  {
    JDesktopPane p = frame.getDesktopPane();
    JInternalFrame active = null;
    if (p != null)
      active = p.getSelectedFrame();
    if (active == null)
      {
        if (p != null)
          {
            p.setSelectedFrame(frame);
          }
      }
    else if (active != frame)
      {
        if (active.isSelected())
          {
            try
              {
                active.setSelected(false);
              }
            catch (PropertyVetoException ex)
              {
                // Not allowed.
              }
          }
        if (p != null)
          {
            p.setSelectedFrame(frame);
          }
        
      }
    frame.toFront();
  }

  /**
   * This method is called when the JInternalFrame loses focus.
   *
   * @param frame The JInternalFram to deactivate.
   */
  public void deactivateFrame(JInternalFrame frame)
  {
    JDesktopPane p = frame.getDesktopPane();
    if (p != null)
      {
        if (p.getSelectedFrame() == frame)
          p.setSelectedFrame(null);
      }
    else
      {
        try
          {
            frame.setSelected(false);
          }
        catch (PropertyVetoException e)
          {
            // Do nothing if attempt is vetoed.
          }
      }
  }

  /**
   * This method is called to indicate that the DesktopManager should prepare
   * to drag the JInternalFrame. Any state information needed to drag the
   * frame will be prepared now.
   *
   * @param component The JComponent to drag, usually a JInternalFrame.
   */
  public void beginDraggingFrame(JComponent component)
  {
    if (component instanceof JDesktopIcon)
      pane = ((JDesktopIcon) component).getInternalFrame().getDesktopPane();
    else
      pane = ((JInternalFrame) component).getDesktopPane();
    if (pane == null)
      return;

    dragCache = component.getBounds();

    if (! (pane instanceof JDesktopPane))
      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
    else
      currentDragMode = ((JDesktopPane) pane).getDragMode();
  }

  /**
   * This method is called to drag the JInternalFrame to a new location.
   *
   * @param component The JComponent to drag, usually a JInternalFrame.
   *
   * @param newX The new x coordinate.
   * @param newY The new y coordinate.
   */
  public void dragFrame(JComponent component, int newX, int newY)
  {
    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
      {
        // FIXME: Do outline drag mode painting.
      }
    else
      {
        Rectangle b = component.getBounds();
        if (component instanceof JDesktopIcon)
          component.setBounds(newX, newY, b.width, b.height);
        else
          setBoundsForFrame((JInternalFrame) component, newX, newY, b.width,
                            b.height);
      }
  }

  /**
   * This method indicates that the dragging is done. Any state information
   * stored by the DesktopManager can be cleared.
   *
   * @param component The JComponent that has finished dragging.
   */
  public void endDraggingFrame(JComponent component)
  {
    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
      {
        setBoundsForFrame((JInternalFrame) component, dragCache.x, dragCache.y,
                          dragCache.width, dragCache.height);
        pane = null;
        dragCache = null;
        component.repaint();        
      }
  }

  /**
   * This method is called to indicate that the given JComponent will be
   * resized. Any state information necessary to resize the JComponent will
   * be prepared now.
   *
   * @param component The JComponent to resize, usually a JInternalFrame.
   * @param direction The direction to drag in (a SwingConstant).
   */
  public void beginResizingFrame(JComponent component, int direction)
  {
    pane = ((JInternalFrame) component).getDesktopPane();
    if (pane == null)
      return;

    dragCache = component.getBounds();
    if (! (pane instanceof JDesktopPane))
      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
    else
      currentDragMode = ((JDesktopPane) pane).getDragMode();
  }

  /**
   * This method resizes the give JComponent.
   *
   * @param component The JComponent to resize.
   * @param newX The new x coordinate.
   * @param newY The new y coordinate.
   * @param newWidth The new width.
   * @param newHeight The new height.
   */
  public void resizeFrame(JComponent component, int newX, int newY,
                          int newWidth, int newHeight)
  {
    dragCache.setBounds(newX, newY, newWidth, newHeight);

    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
      {
        // FIXME: Do outline drag painting.
      }
    else
      setBoundsForFrame(component, dragCache.x, dragCache.y, dragCache.width,
                        dragCache.height);
  }

  /**
   * This method is called to indicate that the given JComponent has finished
   * dragging. Any state information stored by the DesktopManager can be
   * cleared.
   *
   * @param component The JComponent that finished resizing.
   */
  public void endResizingFrame(JComponent component)
  {
    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
      {
        setBoundsForFrame((JInternalFrame) component, dragCache.x, dragCache.y,
                          dragCache.width, dragCache.height);
        pane = null;
        dragCache = null;
        component.repaint();        
      }
  }

  /**
   * This method calls setBounds with the given parameters and repaints the
   * JComponent.
   *
   * @param component The JComponent to set bounds for.
   * @param newX The new x coordinate.
   * @param newY The new y coordinate.
   * @param newWidth The new width.
   * @param newHeight The new height.
   */
  public void setBoundsForFrame(JComponent component, int newX, int newY,
                                int newWidth, int newHeight)
  {
    component.setBounds(newX, newY, newWidth, newHeight);
  }

  /**
   * This is a helper method that removes the JDesktopIcon of the given
   * JInternalFrame from the parent.
   *
   * @param frame The JInternalFrame to remove an icon for.
   */
  protected void removeIconFor(JInternalFrame frame)
  {
    JDesktopIcon icon = frame.getDesktopIcon();
    Container c = icon.getParent();
    if (c != null && icon != null)
      {
        Rectangle b = icon.getBounds();
        c.remove(icon);
        c.repaint(b.x, b.y, b.width, b.height);
      }
  }

  /**
   * This method is called by iconifyFrame to determine the bounds of the
   * JDesktopIcon for the given JInternalFrame.
   *
   * @param frame The JInternalFrame to find the bounds of its JDesktopIcon
   *        for.
   *
   * @return The bounds of the JDesktopIcon.
   */
  protected Rectangle getBoundsForIconOf(JInternalFrame frame)
  {
    // IconRects has no order to it.
    // The icon _must_ be placed in the first free slot (working from 
    // the bottom left corner)
    // The icon also must not be placed where another icon is placed 
    // (regardless whether that frame is an icon currently or not)
    JDesktopPane desktopPane = frame.getDesktopPane();

    if (desktopPane == null)
      return frame.getDesktopIcon().getBounds();

    Rectangle paneBounds = desktopPane.getBounds();
    Insets insets = desktopPane.getInsets();
    Dimension pref = frame.getDesktopIcon().getPreferredSize();

    Component[] frames = desktopPane.getComponents();

    int count = 0;
    for (int i = 0, j = 0; i < frames.length; i++)
      if (frames[i] instanceof JDesktopIcon
          || frames[i] instanceof JInternalFrame
          && ((JInternalFrame) frames[i]).getWasIcon() && frames[i] != frame)
	count++;
    iconRects = new Rectangle[count];
    for (int i = 0, j = 0; i < frames.length; i++)
      if (frames[i] instanceof JDesktopIcon)
        iconRects[--count] = frames[i].getBounds();
      else if (frames[i] instanceof JInternalFrame
               && ((JInternalFrame) frames[i]).getWasIcon()
               && frames[i] != frame)
        iconRects[--count] = ((JInternalFrame) frames[i])
                                                 .getDesktopIcon().getBounds();

    int startingX = insets.left;
    int startingY = paneBounds.height - insets.bottom - pref.height;
    Rectangle ideal = new Rectangle(startingX, startingY, pref.width,
                                    pref.height);
    boolean clear = true;

    while (iconRects.length > 0)
      {
        clear = true;
        for (int i = 0; i < iconRects.length; i++)
          {
            if (iconRects[i] != null && iconRects[i].intersects(ideal))
              {
                clear = false;
                break;
              }
          }
        if (clear)
          return ideal;

        startingX += pref.width;
        if (startingX + pref.width > paneBounds.width - insets.right)
          {
            startingX = insets.left;
            startingY -= pref.height;
          }
        ideal.setBounds(startingX, startingY, pref.width, pref.height);
      }

    return ideal;
  }

  /**
   * This method sets the bounds of the JInternalFrame right before the
   * maximizeFrame call.
   *
   * @param frame The JInternalFrame being maximized.
   * @param rect The normal bounds.
   */
  protected void setPreviousBounds(JInternalFrame frame, Rectangle rect)
  {
    frame.setNormalBounds(rect);
  }

  /**
   * This method returns the normal bounds of the JInternalFrame from before
   * the maximize call.
   *
   * @param frame The JInternalFrame that is being restored.
   *
   * @return The previous bounds of the JInternalFrame.
   */
  protected Rectangle getPreviousBounds(JInternalFrame frame)
  {
    return frame.getNormalBounds();
  }

  /**
   * This method sets the value to true if the given JInternalFrame has been
   * iconized and the bounds of its DesktopIcon are valid.
   *
   * @param frame The JInternalFrame for the JDesktopIcon.
   * @param value True if the JInternalFrame has been iconized and the bounds
   *        of the JDesktopIcon are valid.
   */
  protected void setWasIcon(JInternalFrame frame, Boolean value)
  {
    frame.setWasIcon(value.booleanValue(), WAS_ICON_ONCE_PROPERTY);
  }

  /**
   * This method returns true if the given JInternalFrame has been iconized
   * and the bounds of its DesktopIcon are valid.
   *
   * @param frame The JInternalFrame for the JDesktopIcon.
   *
   * @return True if the given JInternalFrame has been iconized and the bounds
   *         of its DesktopIcon are valid.
   */
  protected boolean wasIcon(JInternalFrame frame)
  {
    return frame.getWasIcon();
  }
}
