/* BoxLayout.java -- A layout for swing components.
   Copyright (C) 2002, 2003, 2005 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.AWTError;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.io.Serializable;

/**
 * A layout that stacks the children of a container in a Box, either
 * horizontally or vertically.
 *
 * @author Ronald Veldema (rveldema@cs.vu.nl)
 * @author Roman Kennke (roman@kennke.org)
 */
public class BoxLayout implements LayoutManager2, Serializable
{

  /**
   * Specifies that components are laid out left to right.
   */
  public static final int X_AXIS = 0;

  /**
   * Specifies that components are laid out top to bottom.
   */
  public static final int Y_AXIS = 1;

  /**
   * Specifies that components are laid out in the direction of a line of text.
   */
  public static final int LINE_AXIS = 2;

  /**
   * Sepcifies that components are laid out in the direction of the line flow.
   */
  public static final int PAGE_AXIS = 3;

  /*
   * Needed for serialization.
   */
  private static final long serialVersionUID = -2474455742719112368L;

  /*
   * The container given to the constructor.
   */
  private Container container;

  /**
   * Current type of component layouting. Defaults to X_AXIS.
   */
  private int way = X_AXIS;

  /**
   * The size requirements of the containers children for the X direction.
   */
  private SizeRequirements[] xChildren;

  /**
   * The size requirements of the containers children for the Y direction.
   */
  private SizeRequirements[] yChildren;

  /**
   * The size requirements of the container to be laid out for the X direction.
   */
  private SizeRequirements xTotal;

  /**
   * The size requirements of the container to be laid out for the Y direction.
   */
  private SizeRequirements yTotal;

  /**
   * The offsets of the child components in the X direction.
   */
  private int[] offsetsX;

  /**
   * The offsets of the child components in the Y direction.
   */
  private int[] offsetsY;

  /**
   * The spans of the child components in the X direction.
   */
  private int[] spansX;

  /**
   * The spans of the child components in the Y direction.
   */
  private int[] spansY;

  /**
   * Constructs a <code>BoxLayout</code> object.
   *
   * @param container The container that needs to be laid out.
   * @param way The orientation of the components.
   *
   * @exception AWTError If way has an invalid value.
   */
  public BoxLayout(Container container, int way)
  {
    if (way != X_AXIS && way != Y_AXIS && way != LINE_AXIS && way != PAGE_AXIS)
      throw new AWTError("Invalid axis");

    int width = 0;
    int height = 0;
    this.container = container;
    this.way = way;
  }

  /**
   * Adds a component to the layout. Not used in BoxLayout.
   *
   * @param name The name of the component to add.
   * @param component the component to add to the layout.
   */
  public void addLayoutComponent(String name, Component component)
  {
    // Nothing to do here.
  }

  /**
   * Removes a component from the layout. Not used in BoxLayout.
   *
   * @param component The component to remove from the layout.
   */
  public void removeLayoutComponent(Component component)
  {
    // Nothing to do here.
  }

  private boolean isHorizontalIn(Container parent)
  {
    ComponentOrientation orientation = parent.getComponentOrientation();
    return this.way == X_AXIS
      || (this.way == LINE_AXIS
          && orientation.isHorizontal())
      || (this.way == PAGE_AXIS
          && (!orientation.isHorizontal()));
  }



  /**
   * Returns the preferred size of the layout.
   *
   * @param parent The container that needs to be laid out.
   *
   * @return The dimension of the layout.
   */
  public Dimension preferredLayoutSize(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkTotalRequirements();
        Insets i = container.getInsets();
        return new Dimension(xTotal.preferred + i.left + i.right,
                             yTotal.preferred + i.top + i.bottom);
      }
  }

  /**
   * Returns the minimum size of the layout.
   *
   * @param parent The container that needs to be laid out.
   *
   * @return The dimension of the layout.
   */
  public Dimension minimumLayoutSize(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkTotalRequirements();
        Insets i = container.getInsets();
        return new Dimension(xTotal.minimum + i.left + i.right,
                             yTotal.minimum + i.top + i.bottom);
      }
  }

  /**
   * Lays out the specified container using this layout.
   *
   * @param parent The container that needs to be laid out.
   */
  public void layoutContainer(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkLayout();
        Component[] children = container.getComponents();
        Insets in = container.getInsets();
        for (int i = 0; i < children.length; i++)
          children[i].setBounds(offsetsX[i] + in.left, offsetsY[i] + in.top,
                                spansX[i], spansY[i]);
      }
  }

  /**
   * Adds a component to the layout. Not used in BoxLayout
   *
   * @param child The component to add to the layout.
   * @param constraints The constraints for the component in the layout.
   */
  public void addLayoutComponent(Component child, Object constraints)
  {
    // Nothing to do here.
  }

  /**
   * Returns the alignment along the X axis for the container.
   *
   * @param parent The container that needs to be laid out.
   *
   * @return The alignment.
   */
  public float getLayoutAlignmentX(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkTotalRequirements();
        return xTotal.alignment;
      }
  }

  /**
   * Returns the alignment along the Y axis for the container.
   *
   * @param parent The container that needs to be laid out.
   *
   * @return The alignment.
   */
  public float getLayoutAlignmentY(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkTotalRequirements();
        return yTotal.alignment;
      }
  }

  /**
   * Invalidates the layout.
   *
   * @param parent The container that needs to be laid out.
   */
  public void invalidateLayout(Container parent)
  {
    if (container != parent)
      throw new AWTError("BoxLayout can't be shared");

    synchronized (container.getTreeLock())
      {
        xChildren = null;
        yChildren = null;
        xTotal = null;
        yTotal = null;
        offsetsX = null;
        offsetsY = null;
        spansX = null;
        spansY = null;
      }
  }

  /**
   * Returns the maximum size of the layout gived the components
   * in the given container.
   *
   * @param parent The container that needs to be laid out.
   *
   * @return The dimension of the layout.
   */
  public Dimension maximumLayoutSize(Container parent)
  {
    synchronized (container.getTreeLock())
      {
        if (container != parent)
          throw new AWTError("BoxLayout can't be shared");

        checkTotalRequirements();
        Insets i = container.getInsets();
        int xDim = xTotal.maximum + i.left + i.right;
        int yDim = yTotal.maximum + i.top + i.bottom;

        // Check for overflow
        if (xDim < xTotal.maximum)
          xDim = Integer.MAX_VALUE;
        if (yDim < yTotal.maximum)
          yDim = Integer.MAX_VALUE;
        return new Dimension(xDim, yDim);
      }
  }

  /**
   * Makes sure that the xTotal and yTotal fields are set up correctly. A call
   * to {@link #invalidateLayout} sets these fields to null and they have to be
   * recomputed.
   */
  private void checkTotalRequirements()
  {
    if (xTotal == null || yTotal == null)
      {
        checkRequirements();
        if (isHorizontalIn(container))
          {
            xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
            yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
          }
        else
          {
            xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
            yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
          }
      }
  }

  /**
   * Makes sure that the xChildren and yChildren fields are correctly set up.
   * A call to {@link #invalidateLayout(Container)} sets these fields to null,
   * so they have to be set up again.
   */
  private void checkRequirements()
  {
    if (xChildren == null || yChildren == null)
      {
        Component[] children = container.getComponents();
        xChildren = new SizeRequirements[children.length];
        yChildren = new SizeRequirements[children.length];
        for (int i = 0; i < children.length; i++)
          {
            if (! children[i].isVisible())
              {
                xChildren[i] = new SizeRequirements();
                yChildren[i] = new SizeRequirements();
              }
            else
              {
                xChildren[i] =
                  new SizeRequirements(children[i].getMinimumSize().width,
                                       children[i].getPreferredSize().width,
                                       children[i].getMaximumSize().width,
                                       children[i].getAlignmentX());
                yChildren[i] =
                  new SizeRequirements(children[i].getMinimumSize().height,
                                       children[i].getPreferredSize().height,
                                       children[i].getMaximumSize().height,
                                       children[i].getAlignmentY());
              }
          }
      }
  }

  /**
   * Makes sure that the offsetsX, offsetsY, spansX and spansY fields are set
   * up correctly. A call to {@link #invalidateLayout} sets these fields
   * to null and they have to be recomputed.
   */
  private void checkLayout()
  {
    if (offsetsX == null || offsetsY == null || spansX == null
        || spansY == null)
      {
        checkRequirements();
        checkTotalRequirements();
        int len = container.getComponents().length;
        offsetsX = new int[len];
        offsetsY = new int[len];
        spansX = new int[len];
        spansY = new int[len];

        Insets in = container.getInsets();
        int width = container.getWidth() - in.left - in.right;
        int height = container.getHeight() - in.top - in.bottom;

        if (isHorizontalIn(container))
          {
            SizeRequirements.calculateTiledPositions(width,
                                                     xTotal, xChildren,
                                                     offsetsX, spansX);
            SizeRequirements.calculateAlignedPositions(height,
                                                       yTotal, yChildren,
                                                       offsetsY, spansY);
          }
        else
          {
            SizeRequirements.calculateAlignedPositions(width,
                                                       xTotal, xChildren,
                                                       offsetsX, spansX);
            SizeRequirements.calculateTiledPositions(height,
                                                     yTotal, yChildren,
                                                     offsetsY, spansY);
          }
      }
  }
}
