/* OverlayLayout.java -- A layout manager
   Copyright (C) 2002, 2004, 2005, 2006, 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.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.io.Serializable;

/**
 * A layout manager that lays out the components of a container one over
 * another.
 *
 * The components take as much space as is available in the container, but not
 * more than specified by their maximum size.
 *
 * The overall layout is mainly affected by the components
 * <code>alignmentX</code> and <code>alignmentY</code> properties. All
 * components are aligned, so that their alignment points (for either
 * direction) are placed in one line (the baseline for this direction).
 *
 * For example: An X alignment of 0.0 means that the component's alignment
 * point is at it's left edge, an X alignment of 0.5 means that the alignment
 * point is in the middle, an X alignment of 1.0 means, the aligment point is
 * at the right edge. So if you have three components, the first with 0.0, the
 * second with 0.5 and the third with 1.0, then they are laid out like this:
 * 
 * <pre>
 *          +-------+
 *          |   1   |
 *          +-------+
 *      +-------+
 *      |   2   |
 *      +-------+
 * +---------+
 * |    3    +
 * +---------+
 * </pre>
 * The above picture shows the X alignment between the components. An Y
 * alignment like shown above cannot be achieved with this layout manager. The
 * components are place on top of each other, with the X alignment shown above.
 *
 * @author Roman Kennke (kennke@aicas.com)
 * @author Andrew Selkirk
 */
public class OverlayLayout implements LayoutManager2, Serializable
{
  private static final long serialVersionUID = 18082829169631543L;

  /**
   * The container to be laid out.
   */
  private Container target;

  /**
   * 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;

  /**
   * Creates a new OverlayLayout for the specified container.
   *
   * @param target the container to be laid out
   */
  public OverlayLayout(Container target)
  {
    this.target = target;
  }

  /**
   * Notifies the layout manager that the layout has become invalid. It throws
   * away cached layout information and recomputes it the next time it is
   * requested.
   *
   * @param target not used here
   */
  public void invalidateLayout(Container target)
  {
    xChildren = null;
    yChildren = null;
    xTotal = null;
    yTotal = null;
    offsetsX = null;
    offsetsY = null;
    spansX = null;
    spansY = null;
  }

  /**
   * This method is not used in this layout manager.
   *
   * @param string not used here
   * @param component not used here
   */
  public void addLayoutComponent(String string, Component component)
  {
    // Nothing to do here.
  }

  /**
   * This method is not used in this layout manager.
   *
   * @param component not used here
   * @param constraints not used here
   */
  public void addLayoutComponent(Component component, Object constraints)
  {
    // Nothing to do here.
  }

  /**
   * This method is not used in this layout manager.
   *
   * @param component not used here
   */
  public void removeLayoutComponent(Component component)
  {
    // Nothing to do here.
  }

  /**
   * Returns the preferred size of the container that is laid out. This is
   * computed by the children's preferred sizes, taking their alignments into
   * account.
   *
   * @param target not used here
   *
   * @return the preferred size of the container that is laid out
   */
  public Dimension preferredLayoutSize(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkTotalRequirements();
    return new Dimension(xTotal.preferred, yTotal.preferred);
  }

  /**
   * Returns the minimum size of the container that is laid out. This is
   * computed by the children's minimum sizes, taking their alignments into
   * account.
   *
   * @param target not used here
   *
   * @return the minimum size of the container that is laid out
   */
  public Dimension minimumLayoutSize(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkTotalRequirements();
    return new Dimension(xTotal.minimum, yTotal.minimum);
  }

  /**
   * Returns the maximum size of the container that is laid out. This is
   * computed by the children's maximum sizes, taking their alignments into
   * account.
   *
   * @param target not used here
   *
   * @return the maximum size of the container that is laid out
   */
  public Dimension maximumLayoutSize(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkTotalRequirements();
    return new Dimension(xTotal.maximum, yTotal.maximum);
  }

  /**
   * Returns the X alignment of the container that is laid out. This is
   * computed by the children's preferred sizes, taking their alignments into
   * account.
   *
   * @param target not used here
   *
   * @return the X alignment of the container that is laid out
   */
  public float getLayoutAlignmentX(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkTotalRequirements();
    return xTotal.alignment;
  }

  /**
   * Returns the Y alignment of the container that is laid out. This is
   * computed by the children's preferred sizes, taking their alignments into
   * account.
   *
   * @param target not used here
   *
   * @return the X alignment of the container that is laid out
   */
  public float getLayoutAlignmentY(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkTotalRequirements();
    return yTotal.alignment;
  }

  /**
   * Lays out the container and it's children.
   *
   * The children are laid out one over another.
   *
   * The components take as much space as is available in the container, but
   * not more than specified by their maximum size.
   *
   * The overall layout is mainly affected by the components
   * <code>alignmentX</code> and <code>alignmentY</code> properties. All
   * components are aligned, so that their alignment points (for either
   * direction) are placed in one line (the baseline for this direction).
   *
   * For example: An X alignment of 0.0 means that the component's alignment
   * point is at it's left edge, an X alignment of 0.5 means that the alignment
   * point is in the middle, an X alignment of 1.0 means, the aligment point is
   * at the right edge. So if you have three components, the first with 0.0,
   * the second with 0.5 and the third with 1.0, then they are laid out like
   * this:
   * 
   * <pre>
   *          +-------+
   *          |   1   |
   *          +-------+
   *      +-------+
   *      |   2   |
   *      +-------+
   * +---------+
   * |    3    +
   * +---------+
   * </pre>
   * The above picture shows the X alignment between the components. An Y
   * alignment like shown above cannot be achieved with this layout manager.
   * The components are place on top of each other, with the X alignment shown
   * above.
   *
   * @param target not used here
   */
  public void layoutContainer(Container target)
  {
    if (target != this.target)
      throw new AWTError("OverlayLayout can't be shared");

    checkLayout();
    Component[] children = target.getComponents();
    for (int i = 0; i < children.length; i++)
      children[i].setBounds(offsetsX[i], offsetsY[i], spansX[i], spansY[i]);
  }

  /**
   * 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 = target.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 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();
        xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
        yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
      }
  }

  /**
   * 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 = target.getComponents().length;
        offsetsX = new int[len];
        offsetsY = new int[len];
        spansX = new int[len];
        spansY = new int[len];

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

        SizeRequirements.calculateAlignedPositions(width, xTotal,
                                                   xChildren, offsetsX, spansX);
        SizeRequirements.calculateAlignedPositions(height, yTotal,
                                                   yChildren, offsetsY, spansY);
      }
  }
}
