/* GridLayout.java -- Grid-based layout engine
   Copyright (C) 1999, 2000, 2002, 2004  Free Software Foundation

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 java.awt;

import java.io.Serializable;

/** This class implements a grid-based layout scheme.  Components are
 * all given the same size and are laid out from left to right and top
 * to bottom.  A GridLayout is configured with a number of rows and a
 * number of columns.  If both are specified, then the number of
 * columns is ignored and is derived from the number of rows and the
 * total number of components.  If either is zero then that dimension
 * is computed based on the actual size of the container.  An
 * exception is thrown if an attempt is made to set both the number of
 * rows and the number of columns to 0.  This class also supports
 * horizontal and vertical gaps; these are used as spacing between
 * cells.
 *
 * @author Tom Tromey (tromey@redhat.com)
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public class GridLayout implements LayoutManager, Serializable
{
  static final long serialVersionUID = -7411804673224730901L;

  /** Add a new component to the layout.  This particular implementation
   * does nothing.
   * @param name The name of the component to add.
   * @param comp The component to add.
   */
  public void addLayoutComponent (String name, Component comp)
  {
    // Nothing.
  }

  /** Return the number of columns in this layout.  */
  public int getColumns ()
  {
    return cols;
  }

  /** Return the horizontal gap.  */
  public int getHgap ()
  {
    return hgap;
  }

  /** Return the number of rows in this layout.  */
  public int getRows ()
  {
    return rows;
  }

  /** Return the vertical gap.  */
  public int getVgap ()
  {
    return vgap;
  }

  /** Create a new <code>GridLayout</code> with one row and any number
   * of columns.  Both gaps are set to 0.
   */
  public GridLayout ()
  {
    this (1, 0, 0, 0);
  }

  /** Create a new <code>GridLayout</code> with the specified number
   * of rows and columns.  Both gaps are set to 0.  Note that the row
   * and column settings cannot both be zero.  If both the row and
   * column values are non-zero, the rows value takes precedence.
   * @param rows Number of rows
   * @param cols Number of columns
   * @exception IllegalArgumentException If rows and columns are both
   *        0, or if either are negative
   */
  public GridLayout (int rows, int cols)
  {
    this (rows, cols, 0, 0);
  }

  /** Create a new GridLayout with the specified number of rows and
   * columns and the specified gaps.
   * Note that the row and column settings cannot both be
   * zero.  If both the row and column values are non-zero, the rows value
   * takes precedence.
   * @param rows Number of rows
   * @param cols Number of columns
   * @param hgap The horizontal gap
   * @param vgap The vertical gap
   * @exception IllegalArgumentException If rows and columns are both
   *        0, if either are negative, or if either gap is negative
   */
  public GridLayout (int rows, int cols, int hgap, int vgap)
  {
    if (rows < 0)
      throw new IllegalArgumentException ("number of rows cannot be negative");
    if (cols < 0)
      throw new IllegalArgumentException ("number of columns cannot be negative");
    if (rows == 0 && cols == 0)
      throw new IllegalArgumentException ("both rows and columns cannot be 0");
    if (hgap < 0)
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
    if (vgap < 0)
      throw new IllegalArgumentException ("vertical gap must be nonnegative");
    this.rows = rows;
    this.cols = cols;
    this.hgap = hgap;
    this.vgap = vgap;
  }

  /** Lay out the container's components based on current settings.
   * The free space in the container is divided evenly into the specified
   * number of rows and columns in this object.
   * @param parent The container to lay out
   */
  public void layoutContainer (Container parent)
  {
    synchronized (parent.getTreeLock ())
      {
        int num = parent.ncomponents;

        // There's no point, and handling this would mean adding special
        // cases.
        if (num == 0)
          return;

        // This is more efficient than calling getComponents().
        Component[] comps = parent.component;

        int real_rows = rows;
        int real_cols = cols;
        if (real_rows == 0)
          real_rows = (num + real_cols - 1) / real_cols;
        else
          real_cols = (num + real_rows - 1) / real_rows;

        // We might have less than a single row.  In this case we expand
        // to fill.
        if (num < real_cols)
          real_cols = num;

        Dimension d = parent.getSize ();
        Insets ins = parent.getInsets ();

        // Compute width and height of each cell in the grid.
        int tw = d.width - ins.left - ins.right;
        tw = (tw - (real_cols - 1) * hgap) / real_cols;
        int th = d.height - ins.top - ins.bottom;
        th = (th - (real_rows - 1) * vgap) / real_rows;

        // If the cells are too small, still try to do something.
        if (tw < 0)
          tw = 1;
        if (th < 0)
          th = 1;

        int x = ins.left;
        int y = ins.top;
        int i = 0;
        int recount = 0;

        while (i < num)
          {
            comps[i].setBounds (x, y, tw, th);

            ++i;
            ++recount;
            if (recount == real_cols)
              {
                recount = 0;
                y += vgap + th;
                x = ins.left;
              }
            else
              x += hgap + tw;
          }
      }
  }

  /** Get the minimum layout size of the container.
   * @param cont The parent container
   */
  public Dimension minimumLayoutSize (Container cont)
  {
    return getSize (cont, true);
  }

  /** Get the preferred layout size of the container.
   * @param cont The parent container
   */
  public Dimension preferredLayoutSize (Container cont)
  {
    return getSize (cont, false);
  }

  /** Remove the indicated component from this layout manager.
   * This particular implementation does nothing.
   * @param comp The component to remove
   */
  public void removeLayoutComponent (Component comp)
  {
    // Nothing.
  }

  /** Set the number of columns.
   * @param newCols
   * @exception IllegalArgumentException If the number of columns is
   *     negative, or if the number of columns is zero and the number
   *     of rows is already 0.
   */
  public void setColumns (int newCols)
  {
    if (newCols < 0)
      throw new IllegalArgumentException ("number of columns cannot be negative");
    if (newCols == 0 && rows == 0)
      throw new IllegalArgumentException ("number of rows is already 0");
    this.cols = newCols;
  }

  /** Set the horizontal gap.  An Exception is not thrown if hgap < 0.
   * @param hgap The horizontal gap
   */
  public void setHgap (int hgap)
  {
    this.hgap = hgap;
  }

  /** Set the number of rows
   * @param newRows
   * @exception IllegalArgumentException If the number of rows is
   *     negative, or if the number of rows is zero and the number
   *     of columns is already 0.
   */
  public void setRows (int newRows)
  {
    if (newRows < 0)
      throw new IllegalArgumentException ("number of rows cannot be negative");
    if (newRows == 0 && cols == 0)
      throw new IllegalArgumentException ("number of columns is already 0");
    this.rows = newRows;
  }

  /** Set the vertical gap.  An Exception is not thrown if vgap < 0.
   * @param vgap The vertical gap
   */
  public void setVgap (int vgap)
  {
    this.vgap = vgap;
  }

  /** Return String description of this object.  */
  public String toString ()
  {
    return (getClass ().getName () + "["
            + "hgap=" + hgap + ",vgap=" + vgap
            + ",rows=" + rows + ",cols=" + cols
            + "]");
  }

  // This method is used to compute the various sizes.
  private Dimension getSize (Container parent, boolean is_min)
  {
    synchronized (parent.getTreeLock ())
      {
        int w = 0, h = 0, num = parent.ncomponents;
        // This is more efficient than calling getComponents().
        Component[] comps = parent.component;

        for (int i = 0; i < num; ++i)
          {
            Dimension d;

            if (is_min)
              d = comps[i].getMinimumSize ();
            else
              d = comps[i].getPreferredSize ();

            w = Math.max (d.width, w);
            h = Math.max (d.height, h);
          }

        int real_rows = rows;
        int real_cols = cols;
        if (real_rows == 0)
          real_rows = (num + real_cols - 1) / real_cols;
        else
          real_cols = (num + real_rows - 1) / real_rows;

        Insets ins = parent.getInsets ();
        // We subtract out an extra gap here because the gaps are only
        // between cells.
        w = ins.left + ins.right + real_cols * (w + hgap) - hgap;
        h = ins.top + ins.bottom + real_rows * (h + vgap) - vgap;
        return new Dimension (w, h);
      }
  }

  /**
   * @serial The number of columns in the grid.
   */
  private int cols;

  /**
   * @serial The number of rows in the grid.
   */
  private int rows;

  /**
   * @serial The horizontal gap between columns
   */
  private int hgap;

  /**
   * @serial The vertical gap between rows
   */
  private int vgap;
}
