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

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

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