/* ScrollPaneLayout.java --
   Copyright (C) 2002, 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., 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.LayoutManager;
import java.awt.Rectangle;
import java.io.Serializable;

/**
 * ScrollPaneLayout
 * @author	Andrew Selkirk
 * @version	1.0
 */
public class ScrollPaneLayout
  implements LayoutManager, ScrollPaneConstants, Serializable
{
  private static final long serialVersionUID = -4480022884523193743L;

  public static class UIResource extends ScrollPaneLayout 
    implements javax.swing.plaf.UIResource
  {
    public UIResource()
    {
      super();
    }
  }

  protected JViewport viewport;
  protected JScrollBar vsb;
  protected JScrollBar hsb;
  protected JViewport rowHead;
  protected JViewport colHead;
  protected Component lowerLeft;
  protected Component lowerRight;
  protected Component upperLeft;
  protected Component upperRight;
  protected int vsbPolicy;
  protected int hsbPolicy;

  public ScrollPaneLayout()
  {
	// Nothing to do here.
  }

  public void syncWithScrollPane(JScrollPane scrollPane) 
  {
    viewport = scrollPane.getViewport();
    rowHead = scrollPane.getRowHeader();
    colHead = scrollPane.getColumnHeader();
    vsb = scrollPane.getVerticalScrollBar();
    hsb = scrollPane.getHorizontalScrollBar();
    vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
    hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
    lowerLeft = scrollPane.getCorner(LOWER_LEFT_CORNER);
    lowerRight = scrollPane.getCorner(LOWER_RIGHT_CORNER);
    upperLeft = scrollPane.getCorner(UPPER_LEFT_CORNER);
    upperRight = scrollPane.getCorner(UPPER_RIGHT_CORNER);    
  }

  /**
   * Removes an existing component.  If oldComponent is not null
   * and is not equal to newComponent, oldComponent must be removed
   * from its parent.
   * @param oldComponent the old Component that may need to be removed.
   * @param newComponent the Component to add.
   * @return the newComponent
   */
  protected Component addSingletonComponent(Component oldComponent,
                                            Component newComponent) 
  {
    if (oldComponent != null && oldComponent != newComponent)
      oldComponent.getParent().remove(oldComponent);
    return newComponent;
  }

  /**
   * Add the specified component to the layout. 
   * @param key must be one of VIEWPORT, VERTICAL_SCROLLBAR,
   * HORIZONTAL_SCROLLBAR, ROW_HEADER, COLUMN_HEADER,
   * LOWER_RIGHT_CORNER, LOWER_LEFT_CORNER, UPPER_RIGHT_CORNER,
   * UPPER_LEFT_CORNER.
   * @param component the Component to add
   * @throws IllegalArgumentException if key is not as above
   */
  public void addLayoutComponent(String key, Component component) 
  {
    if (key == VIEWPORT)
      viewport = (JViewport) component;
    else if (key == VERTICAL_SCROLLBAR)
      vsb = (JScrollBar) component;
    else if (key == HORIZONTAL_SCROLLBAR)
      hsb = (JScrollBar) component;
    else if (key == ROW_HEADER)
      rowHead = (JViewport) component;
    else if (key == COLUMN_HEADER)
      colHead = (JViewport) component;
    else if (key == LOWER_RIGHT_CORNER)
      lowerRight = component;
    else if (key == UPPER_RIGHT_CORNER)
      upperRight = component;
    else if (key == LOWER_LEFT_CORNER)
      lowerLeft = component;
    else if (key == UPPER_LEFT_CORNER)
      upperLeft = component;
    else
      throw new IllegalArgumentException();
  }

  public void removeLayoutComponent(Component component) 
  {
    if (component == viewport)
      viewport = null;
    else if (component == vsb)
      vsb = null;
    else if (component == hsb)
      hsb = null;
    else if (component == rowHead)
      rowHead = null;
    else if (component == colHead)
      colHead = null;
    else if (component == lowerRight)
      lowerRight = null;
    else if (component == upperRight)
      upperRight = null;
    else if (component == lowerLeft)
      lowerLeft = null;
    else if (component == upperLeft)
      upperLeft = null;
  }

  public int getVerticalScrollBarPolicy()
  {
    return vsbPolicy;
  }
  
  /**
   * Sets the vertical scrollbar policy.
   * @param policy must be one of VERTICAL_SCROLLBAR_AS_NEEDED,
   * VERTICAL_SCROLLBAR_NEVER, VERTICAL_SCROLLBAR_ALWAYS.
   * @throws IllegalArgumentException if policy is not one of the valid
   * JScrollBar policies.
   */
  public void setVerticalScrollBarPolicy(int policy)
  {
    if (policy != VERTICAL_SCROLLBAR_AS_NEEDED && 
        policy != VERTICAL_SCROLLBAR_NEVER &&
        policy != VERTICAL_SCROLLBAR_ALWAYS)
      throw new IllegalArgumentException("Illegal Scrollbar Policy");
    vsbPolicy = policy;
  }

  public int getHorizontalScrollBarPolicy()
  {
    return hsbPolicy;
  }

  /**
   * Sets the horizontal scrollbar policy.
   * @param policy must be one of HORIZONTAL_SCROLLBAR_AS_NEEDED,
   * HORIZONTAL_SCROLLBAR_NEVER, HORIZONTAL_SCROLLBAR_ALWAYS.
   * @throws IllegalArgumentException if policy is not one of the valid 
   * JScrollbar policies.
   */
  public void setHorizontalScrollBarPolicy(int policy)
  {
    if (policy != HORIZONTAL_SCROLLBAR_AS_NEEDED && 
        policy != HORIZONTAL_SCROLLBAR_NEVER &&
        policy != HORIZONTAL_SCROLLBAR_ALWAYS)
      throw new IllegalArgumentException("Illegal Scrollbar Policy");
    hsbPolicy = policy;
  }

  public JViewport getViewport()
  {
    return viewport;
  }

  public JScrollBar getHorizontalScrollBar()
  {
    return hsb;
  }

  public JScrollBar getVerticalScrollBar()
  {
    return vsb;
  }

  public JViewport getRowHeader()
  {
    return rowHead;
  }

  public JViewport getColumnHeader()
  {
    return colHead;
  }

  /**
   * Returns the Component at the specified corner.
   * @param key the corner.
   * @return the Component at the specified corner, or null if
   * key is not one of the four valid corners.
   */
  public Component getCorner(String key)
  {
    if (key == LOWER_RIGHT_CORNER)
      return lowerRight;
    else if (key == UPPER_RIGHT_CORNER)
      return upperRight;
    else if (key == LOWER_LEFT_CORNER)
      return lowerLeft;
    else if (key == UPPER_LEFT_CORNER)
      return upperLeft;
    return null;
  }

  public Dimension preferredLayoutSize(Container parent) 
  {
    // Sun's implementation simply throws a ClassCastException if
    // parent is no JScrollPane, so do we.
    JScrollPane sc = (JScrollPane) parent;
    Dimension viewportSize = viewport.getPreferredSize();
    Dimension viewSize = viewport.getViewSize();
    int width = viewportSize.width;
    int height = viewportSize.height;

    // horizontal scrollbar needed if the view's preferred width
    // is larger than the viewport's preferred width
    if (hsb != null && viewSize.width > viewportSize.width)
      height += hsb.getPreferredSize().height;

    // vertical scrollbar needed if the view's preferred height
    // is larger than the viewport's preferred height
    if (vsb != null && viewSize.height > viewportSize.height)
      width += vsb.getPreferredSize().width;
    if (rowHead != null && rowHead.isVisible())
      width += rowHead.getPreferredSize().width;
    if (colHead != null && colHead.isVisible())
      height += colHead.getPreferredSize().height;
    Insets i = sc.getInsets();
    return new Dimension(width + i.left + i.right,
                         height + i.left + i.right);
  }

  public Dimension minimumLayoutSize(Container parent)
  {
    // Sun's implementation simply throws a ClassCastException if
    // parent is no JScrollPane, so do we.
    JScrollPane sc = (JScrollPane) parent;
    Insets i = sc.getInsets();
    Dimension viewportMinSize = sc.getViewport().getMinimumSize();

    int width = i.left + i.right + viewportMinSize.width;
    if (sc.getVerticalScrollBarPolicy()
        != JScrollPane.VERTICAL_SCROLLBAR_NEVER)
      width += sc.getVerticalScrollBar().getMinimumSize().width;

    int height = i.top + i.bottom + viewportMinSize.height;
    if (sc.getHorizontalScrollBarPolicy()
        != JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
      height += sc.getHorizontalScrollBar().getMinimumSize().height;

    return new Dimension(width, height);
  }

  /**
   *
   *     +----+--------------------+----+ y1
   *     | c1 |   column header    | c2 |
   *     +----+--------------------+----+ y2
   *     | r  |                    | v  |
   *     | o  |                    |    |
   *     | w  |                    | s  |
   *     |    |                    | r  |
   *     | h  |                    | o  |
   *     | e  |      viewport      | l  |
   *     | a  |                    | l  |
   *     | d  |                    | b  |
   *     | e  |                    | a  |
   *     | r  |                    | r  |
   *     +----+--------------------+----+ y3
   *     | c3 |    h scrollbar     | c4 |
   *     +----+--------------------+----+ y4
   *    x1   x2                   x3   x4
   *   
   */
  public void layoutContainer(Container parent)
  {
    // Sun's implementation simply throws a ClassCastException if
    // parent is no JScrollPane, so do we.
    JScrollPane sc = (JScrollPane) parent;
    JViewport viewport = sc.getViewport();
    Component view = viewport.getView();
    
    // If there is no view in the viewport, there is no work to be done.
    if (view == null)
      return;
    
    Dimension viewSize = viewport.getView().getPreferredSize();

    int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
    int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
    Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);

    x1 = scrollPaneBounds.x;
    y1 = scrollPaneBounds.y;
    x4 = scrollPaneBounds.x + scrollPaneBounds.width;
    y4 = scrollPaneBounds.y + scrollPaneBounds.height;
    if (colHead != null)
      y2 = y1 + colHead.getPreferredSize().height;
    else
      y2 = y1;

    if (rowHead != null)
      x2 = x1 + rowHead.getPreferredSize().width;
    else
      x2 = x1;

    int vsbPolicy = sc.getVerticalScrollBarPolicy();
    int hsbPolicy = sc.getHorizontalScrollBarPolicy();
    
    int vsWidth = 0;
    int hsHeight = 0;

    boolean showVsb = 
      (vsb != null)
      && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
          || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED 
              && viewSize.height > (y4 - y2)));
    
    if (showVsb)
      vsWidth = vsb.getPreferredSize().width;
    
    // The horizontal scroll bar may become necessary if the vertical scroll
    // bar appears, reducing the space, left for the component.
    
    boolean showHsb = 
      (hsb != null)
      && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
          || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED 
              && viewSize.width > (x4 - x2 - vsWidth)));
    
    if (showHsb)
      hsHeight = hsb.getPreferredSize().height;
    
    // If the horizontal scroll bar appears, and the vertical scroll bar
    // was not necessary assuming that there is no horizontal scroll bar,
    // the vertical scroll bar may become necessary because the horizontal
    // scroll bar reduces the vertical space for the component.
    if (!showVsb)
      {
        showVsb = 
          (vsb != null)
          && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
              || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED 
                  && viewSize.height > (y4 - y2)));
    
        if (showVsb)
          vsWidth = vsb.getPreferredSize().width;
      }

    x3 = x4 - vsWidth;
    y3 = y4 - hsHeight;

    // now set the layout
    if (viewport != null)
      viewport.setBounds(new Rectangle(x2, y2, x3 - x2, y3 - y2));

    if (colHead != null)
      colHead.setBounds(new Rectangle(x2, y1, x3 - x2, y2 - y1));

    if (rowHead != null)
      rowHead.setBounds(new Rectangle(x1, y2, x2 - x1, y3 - y2));

    if (showVsb)
      {
        vsb.setVisible(true);
        vsb.setBounds(new Rectangle(x3, y2, x4 - x3, y3 - y2));
      }
    else if (vsb != null)
      vsb.setVisible(false);

    if (showHsb)
      {
        hsb.setVisible(true);
        hsb.setBounds(new Rectangle(x2, y3, x3 - x2, y4 - y3));
      }
    else if (hsb != null)
      hsb.setVisible(false);

    if (upperLeft != null)
      upperLeft.setBounds(new Rectangle(x1, y1, x2 - x1, y2 - y1));

    if (upperRight != null)
      upperRight.setBounds(new Rectangle(x3, y1, x4 - x3, y2 - y1));

    if (lowerLeft != null)
      lowerLeft.setBounds(new Rectangle(x1, y3, x2 - x1, y4 - y3));

    if (lowerRight != null)
      lowerRight.setBounds(new Rectangle(x3, y3, x4 - x3, y4 - y3));
  }

  /**
   * Returns the bounds of the border around a ScrollPane's viewport.
   *
   * @param scrollPane the ScrollPane for which's viewport the border
   *     is requested
   *
   * @deprecated As of Swing 1.1 replaced by
   *     {@link javax.swing.JScrollPane#getViewportBorderBounds}.
   */
  public Rectangle getViewportBorderBounds(JScrollPane scrollPane) 
  {
    return null;
  }


}
