/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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
   * @param hgap The horizontal gap
   * @exception IllegalArgumentException If the hgap value is less than zero.
   */
  public void setHgap (int hgap)
  {
    if (hgap < 0)
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
    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.
   * @param vgap The vertical gap
   * @exception IllegalArgumentException If the vgap value is less than zero.
   */
  public void setVgap (int vgap)
  {
    if (vgap < 0)
      throw new IllegalArgumentException ("vertical gap must be nonnegative");
    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;
}
