// GridLayout.java - Grid-based layout engine

/* Copyright (C) 2000  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.awt;

import java.io.Serializable;

/** This class implements a flow-based layout.  Components are laid
 * out in order from left to right.  When a component cannot be placed
 * without horizontal clipping, a new row is started.  This class
 * supports horizontal and vertical gaps.  These are used for spacing
 * between components.
 */
public class FlowLayout implements LayoutManager, Serializable
{
  /** Constant that specifies left alignment.  */
  public static final int LEFT = 0;
  /** Constant that specifies center alignment.  */
  public static final int CENTER = 1;
  /** Constant that specifies right alignment.  */
  public static final int RIGHT = 2;

  /** Constant that specifies alignment to leading edge of container's
   * orientation.  */
  public static final int LEADING = 3;
  /** Constant that specifies alignment to trailing edge of container's
   * orientation.  */
  public static final int TRAILING = 4;

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

  /** Return the alignment.  */
  public int getAlignment ()
  {
    return align;
  }

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

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

  /** Create a new FlowLayout with center alignment.
   * Both gaps are set to 0.
   */
  public FlowLayout ()
  {
    this (CENTER, 0, 0);
  }

  /** Create a new FlowLayout with the alignment.
   * columns.  Both gaps are set to 0.
   * @param align Alignment
   */
  public FlowLayout (int align)
  {
    this (align, 0, 0);
  }

  /** Create a new FlowLayout with the specified alignment and gaps.
   * @param align Alignment
   * @param hgap The horizontal gap
   * @param vgap The vertical gap
   * @exception IllegalArgumentException If either gap is negative
   */
  public FlowLayout (int align, int hgap, int vgap)
  {
    if (hgap < 0)
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
    if (vgap < 0)
      throw new IllegalArgumentException ("vertical gap must be nonnegative");
    if (align != LEFT && align != RIGHT && align != CENTER
	&& align != LEADING && align != TRAILING)
      throw new IllegalArgumentException ("invalid align: " + align);
    this.align = align;
    this.hgap = hgap;
    this.vgap = vgap;
  }

  /** Lay out the container's components based on current settings.
   * @param parent The parent container
   */
  public void layoutContainer (Container parent)
  {
    int num = parent.getComponentCount ();
    // This is more efficient than calling getComponents().
    Component[] comps = parent.component;

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

    ComponentOrientation orient = parent.getComponentOrientation ();
    boolean left_to_right = orient.isLeftToRight ();

    int y = ins.top + vgap;
    int i = 0;
    while (i < num)
      {
	// Find the components which go in the current row.
	int new_w = ins.left + hgap + ins.right;
	int new_h = 0;
	int j;
	for (j = i; j < num; ++j)
	  {
	    // FIXME: this is very inefficient.
	    Dimension c = comps[i].getPreferredSize ();
	    int next_w = new_w + hgap + c.width;
	    if (next_w > d.width)
	      {
		// We must start a new row.
		break;
	      }
	    new_w = next_w;
	    new_h = Math.max (new_h, c.height);
	  }
	// We always need at least one item.
	if (j == i)
	  ++j;

	// Set the location of each component for this row.
	int x;

	int myalign = align;
	if (align == LEADING)
	  myalign = left_to_right ? LEFT : RIGHT;
	else if (align == TRAILING)
	  myalign = left_to_right ? RIGHT : LEFT;

	if (myalign == LEFT)
	  x = ins.left + hgap;
	else if (myalign == CENTER)
	  x = (d.width - new_w) / 2;
	else
	  x = d.width - new_w;

	for (int k = i; i < j; ++k)
	  {
	    // FIXME: this is very inefficient.
	    Dimension c = comps[i].getPreferredSize ();
	    comps[i].setLocation (x, y);
	    x += c.width + vgap;
	  }

	// Advance to next row.
	i = j;
	y += new_h + vgap;
      }
  }

  /** 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 alignment.
   * @param align The alignment
   */
  public void setAlignment (int align)
  {
    if (align != LEFT && align != RIGHT && align != CENTER
	&& align != LEADING && align != TRAILING)
      throw new IllegalArgumentException ("invalid align: " + align);
    this.align = align;
  }

  /** Set the horizontal gap
   * @param hgap The horizontal gap
   */
  public void setHgap (int hgap)
  {
    if (hgap < 0)
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
    this.hgap = hgap;
  }

  /** Set the vertical gap.
   * @param vgap The vertical gap
   */
  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
	    + ",align=" + align + "]");
  }

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

    w = 0;
    h = 0;
    for (int i = 0; i < num; ++i)
      {
	// FIXME: can we just directly read the fields in Component?
	// Or will that not work with subclassing?
	Dimension d;

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

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

    Insets ins = parent.getInsets ();

    w += (num + 1) * hgap + ins.left + ins.right;
    h += 2 * vgap + ins.top + ins.bottom;

    return new Dimension (w, h);
  }

  // Alignment.
  private int align;
  // The gaps.
  private int hgap;
  private int vgap;
}
