/*
 * ColumnLayout.java  1.0  96/08/13  Jean-Guy Speton
 *
 * Copyright (c) 1996 Oregon State University.  All rights reserved.
 *
 * Permission for NON-COMMERCIAL use is hereby granted.
 */

import java.awt.*;

/**
 * Column layout is used to layout components in a panel. It will arrange
 * components top to bottom, one component per row.
 * Each row can be aligned left, centered, or right.
 *
 * @version 	1.0, 13 Aug 96
 * @author 	Jean-Guy Speton
 */
public class ColumnLayout implements LayoutManager
{
  /**
   * The left alignment variable. 
   */
  public static final int LEFT 	= 0;

  /**
   * The right alignment variable. 
   */
  public static final int CENTER 	= 1;

  /**
   * The right alignment variable.
   */
  public static final int RIGHT 	= 2;

  int align;
  int vgap;

  /**
   * Constructs a new Column Layout with a centered alignment.
   */
  public ColumnLayout() {
    this(LEFT, 5);
  }

  /**
   * Constructs a new Column Layout with the specified alignment.
   * @param align the alignment value
   */
  public ColumnLayout(int align) {
    this(align, 5);
  }

  /**
   * Constructs a new Column Layout with the specified alignment and gap
   * values.
   * @param align the alignment value
   * @param hgap the horizontal gap variable
   * @param vgap the vertical gap variable
   */
  public ColumnLayout(int align, int vgap) {
    this.align = align;
    this.vgap = vgap;
  }

  /**
   * Adds the specified component to the layout. Not used by this class.
   * @param name the name of the component
   * @param comp the the component to be added
   */
  public void addLayoutComponent(String name, Component comp) {
  }

  /**
   * Removes the specified component from the layout. Not used by
   * this class.  
   * @param comp the component to remove
   */
  public void removeLayoutComponent(Component comp) {
  }

  /**
   * Returns the preferred dimensions for this layout given the components
   * in the specified target container.
   * @param target the component which needs to be laid out
   * @see Container
   * @see #minimumLayoutSize
   */
  public Dimension preferredLayoutSize(Container target)
  {
    Dimension dim = new Dimension(0, 0);
    int nmembers = target.countComponents();

    for (int i = 0 ; i < nmembers ; i++) {
      Component m = target.getComponent(i);
      if (m.isVisible()) {
	Dimension d = m.preferredSize();
	dim.width = Math.max(dim.width, d.width);
	if (i > 0) {
	  dim.height += vgap;
	}
	dim.height += d.height;
      }
    }
    Insets insets = target.insets();
    dim.width += insets.left + insets.right;
    dim.height += insets.top + insets.bottom + vgap*2;
    return dim;
  }

  /**
   * Returns the minimum dimensions needed to layout the components
   * contained in the specified target container.
   * @param target the component which needs to be laid out 
   * @see #preferredLayoutSize
   */
  public Dimension minimumLayoutSize(Container target)
  {
    Dimension dim = new Dimension(0, 0);
    int nmembers = target.countComponents();

    for (int i = 0 ; i < nmembers ; i++) {
      Component m = target.getComponent(i);
      if (m.isVisible()) {
	Dimension d = m.minimumSize();
	dim.width = Math.max(dim.width, d.width);
	if (i > 0) {
	  dim.height += vgap;
	}
	dim.height += d.height;
      }
    }
    Insets insets = target.insets();
    dim.width += insets.left + insets.right;
    dim.height += insets.top + insets.bottom + vgap*2;
    return dim;
  }

  /**
   * Lays out the container. This method will actually reshape the
   * components in the target in order to satisfy the constraints of
   * the BorderLayout object. 
   * @param target the specified component being laid out.
   * @see Container
   */
  public void layoutContainer(Container target)
  {
    Insets insets = target.insets();
    int maxwidth = target.size().width - (insets.left + insets.right);
    int nmembers = target.countComponents();
    int x = 0, y = insets.top + vgap;
    int rowh = 0, start = 0;

    for (int i = 0 ; i < nmembers ; i++) {
      Component m = target.getComponent(i);
      if (m.isVisible()) {
	Dimension d = m.preferredSize();
	m.resize(d.width, d.height);
	      
	if (align == LEFT) {
	  x = insets.left;
	} else if (align == CENTER) {
	  x = (maxwidth - insets.left - insets.right - d.width) / 2;
	} else {
	  x = maxwidth - insets.left - insets.right - d.width;
	}
	m.move(x, y);
	y += vgap + d.height;
      }
    }
  }
    
  /**
   * Returns the String representation of this ColumnLayout's values.
   */
  public String toString() {
    String str = "";
    switch (align) {
    case LEFT:    str = ",align=left"; break;
    case CENTER:  str = ",align=center"; break;
    case RIGHT:   str = ",align=right"; break;
    }
    return getClass().getName() + "[vgap=" + vgap + str + "]";
  }
}

