/* OverlayLayout.java -- A layout manager
   Copyright (C) 2002, 2004, 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.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
   *
   * @returns 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
   *
   * @returns 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
   *
   * @returns 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
   *
   * @returns 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
   *
   * @returns 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);
      }
  }
}
