/* GridBagLayout - Layout manager for components according to GridBagConstraints
   Copyright (C) 2002, 2003, 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 java.awt;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;

/**
 * @author Michael Koch (konqueror@gmx.de)
 * @author Jeroen Frijters (jeroen@frijters.net)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 */
public class GridBagLayout
    implements Serializable, LayoutManager2
{
    private static final long serialVersionUID = 8838754796412211005L;

    protected static final int MINSIZE = 1;
    protected static final int PREFERREDSIZE = 2;
    protected static final int MAXGRIDSIZE = 512;

    // comptable remembers the original contraints given to us.
    // internalcomptable is used to keep track of modified constraint values
    // that we calculate, particularly when we are given RELATIVE and
    // REMAINDER constraints.
    // Constraints kept in comptable are never modified, and constraints
    // kept in internalcomptable can be modified internally only.
    protected Hashtable<Component,GridBagConstraints> comptable;
    private Hashtable<Component,GridBagConstraints> internalcomptable;
    protected GridBagLayoutInfo layoutInfo;
    protected GridBagConstraints defaultConstraints;

    public double[] columnWeights;
    public int[] columnWidths;
    public double[] rowWeights;
    public int[] rowHeights;

    public GridBagLayout ()
    {
	this.comptable = new Hashtable<Component,GridBagConstraints>();
	this.internalcomptable = new Hashtable<Component,GridBagConstraints>();
	this.defaultConstraints= new GridBagConstraints();
    }

    /**
     * Helper method to calc the sum of a range of elements in an int array.
     */
    private int sumIntArray (int[] array, int upto)
    {
	int result = 0;

	for (int i = 0; i < upto; i++)
	    result += array [i];

	return result;
    }

    /**
     * Helper method to calc the sum of all elements in an int array.
     */
    private int sumIntArray (int[] array)
    {
	return sumIntArray(array, array.length);
    }

    /**
     * Helper method to calc the sum of all elements in an double array.
     */
    private double sumDoubleArray (double[] array)
    {
	double result = 0;

	for (int i = 0; i < array.length; i++)
	    result += array [i];

	return result;
    }

    public void addLayoutComponent (String name, Component component)
    {
	// do nothing here.
    }

    public void removeLayoutComponent (Component component)
    {
	// do nothing here
    }

    public void addLayoutComponent (Component component, Object constraints)
    {
	if (constraints == null)
	    return;

	if (!(constraints instanceof GridBagConstraints))
	    throw new IllegalArgumentException("constraints " 
					       + constraints 
					       + " are not an instance of GridBagConstraints");

	setConstraints (component, (GridBagConstraints) constraints);
    }

    public Dimension preferredLayoutSize (Container parent)
    {
	if (parent == null)
	    return new Dimension (0, 0);
    
	GridBagLayoutInfo li = getLayoutInfo (parent, PREFERREDSIZE);
	return getMinSize (parent, li);
    }

    public Dimension minimumLayoutSize (Container parent)
    {
	if (parent == null)
	    return new Dimension (0, 0);
    
	GridBagLayoutInfo li = getLayoutInfo (parent, MINSIZE);
	return getMinSize (parent, li);
    }

    public Dimension maximumLayoutSize (Container target)
    {
	return new Dimension (Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    public void layoutContainer (Container parent)
    {
      arrangeGrid (parent);
    }

    public float getLayoutAlignmentX (Container target)
    {
	return Component.CENTER_ALIGNMENT;
    }

    public float getLayoutAlignmentY (Container target)
    {
	return Component.CENTER_ALIGNMENT;
    }

    public void invalidateLayout (Container target)
    {
	this.layoutInfo = null;
    }

    public void setConstraints (Component component,
	GridBagConstraints constraints)
    {
	GridBagConstraints clone = (GridBagConstraints) constraints.clone();

	if (clone.gridx < 0)
	    clone.gridx = GridBagConstraints.RELATIVE;
    
	if (clone.gridy < 0)
	    clone.gridy = GridBagConstraints.RELATIVE;

	if (clone.gridwidth == 0)
	    clone.gridwidth = GridBagConstraints.REMAINDER;
	else if (clone.gridwidth < 0)
	    clone.gridwidth = 1;
    
	if (clone.gridheight == 0)
	    clone.gridheight = GridBagConstraints.REMAINDER;
	else if (clone.gridheight < 0)
	    clone.gridheight = 1;
    
	comptable.put (component, clone);
    }

    public GridBagConstraints getConstraints (Component component)
    {
	return (GridBagConstraints) (lookupConstraints (component).clone());
    }

    protected GridBagConstraints lookupConstraints (Component component)
    {
	GridBagConstraints result = (GridBagConstraints) comptable.get (component);

	if (result == null)
	{
	    setConstraints (component, defaultConstraints);
	    result = (GridBagConstraints) comptable.get (component);
	}
    
	return result;
    }

    private GridBagConstraints lookupInternalConstraints (Component component)
    {
	GridBagConstraints result =
            (GridBagConstraints) internalcomptable.get (component);

	if (result == null)
	{
	    result = (GridBagConstraints) lookupConstraints(component).clone();
	    internalcomptable.put (component, result);
	}
    
	return result;
    }

    /**
     * @since 1.1
     */
    public Point getLayoutOrigin ()
    {
	if (layoutInfo == null)
	    return new Point (0, 0);
    
	return new Point (layoutInfo.pos_x, layoutInfo.pos_y);
    }

    /**
     * @since 1.1
     */
    public int[][] getLayoutDimensions ()
    {
	int[][] result = new int [2][];
	if (layoutInfo == null)
	  {
	    result[0] = new int[0];
	    result[1] = new int[0];

	    return result;
	  }

	result [0] = new int [layoutInfo.cols];
	System.arraycopy (layoutInfo.colWidths, 0, result [0], 0, layoutInfo.cols);
	result [1] = new int [layoutInfo.rows];
	System.arraycopy (layoutInfo.rowHeights, 0, result [1], 0, layoutInfo.rows);
	return result;
    }

    public double[][] getLayoutWeights ()
    {
	double[][] result = new double [2][];
	if (layoutInfo == null)
	  {
	    result[0] = new double[0];
	    result[1] = new double[0];

	    return result;
	  }

	result [0] = new double [layoutInfo.cols];
	System.arraycopy (layoutInfo.colWeights, 0, result [0], 0, layoutInfo.cols);
	result [1] = new double [layoutInfo.rows];
	System.arraycopy (layoutInfo.rowWeights, 0, result [1], 0, layoutInfo.rows);
	return result;
    }

    /**
     * @since 1.1
     */
    public Point location (int x, int y)
    {
	if (layoutInfo == null)
	    return new Point (0, 0);

	int col;
	int row;
	int pixel_x = layoutInfo.pos_x;
	int pixel_y = layoutInfo.pos_y;

	for (col = 0; col < layoutInfo.cols; col++)
	{
	    int w = layoutInfo.colWidths [col];
	    if (x < pixel_x + w)
		break;

	    pixel_x += w;
	}

	for (row = 0; row < layoutInfo.rows; row++)
	{
	    int h = layoutInfo.rowHeights [row];
	    if (y < pixel_y + h)
		break;

	    pixel_y += h;
	}

	return new Point (col, row);
    }

    /**
     * Return a string representation of this GridBagLayout.
     *
     * @return a string representation
     */
    public String toString()
    {
      return getClass().getName();
    }
    
    /**
     * Move and resize a rectangle according to a set of grid bag
     * constraints.  The x, y, width and height fields of the
     * rectangle argument are adjusted to the new values.
     *
     * @param constraints position and size constraints
     * @param r rectangle to be moved and resized
     */
    protected void AdjustForGravity (GridBagConstraints constraints,
                                     Rectangle r)
    {
      Insets insets = constraints.insets;
      if (insets != null)
	{
	  r.x += insets.left;
	  r.y += insets.top;
	  r.width -= insets.left + insets.right;
	  r.height -= insets.top + insets.bottom;
	}
    }

    /**
     * Obsolete.
     */
    protected void ArrangeGrid (Container parent)
    {
      Component[] components = parent.getComponents();

      if (components.length == 0)
        return;

      GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE);
      if (info.cols == 0 && info.rows == 0)
        return;

      // DEBUG
      //dumpLayoutInfo (info);

      // Calling setBounds on these components causes this layout to
      // be invalidated, clearing the layout information cache,
      // layoutInfo.  So we wait until after this for loop to set
      // layoutInfo.
      Component lastComp = null;

      Rectangle cell = new Rectangle();

      for (int i = 0; i < components.length; i++)
      {
        Component component = components[i];

        // If component is not visible we dont have to care about it.
        if (! component.isVisible())
          continue;

        Dimension dim = component.getPreferredSize();
        GridBagConstraints constraints = lookupInternalConstraints(component);
        
        if (lastComp != null
            && constraints.gridheight == GridBagConstraints.REMAINDER)
          cell.y += cell.height;
        else
          cell.y = sumIntArray(info.rowHeights, constraints.gridy);
        
        if (lastComp != null
            && constraints.gridwidth == GridBagConstraints.REMAINDER)
          cell.x += cell.width;
        else
          cell.x = sumIntArray(info.colWidths, constraints.gridx);

        cell.width = sumIntArray(info.colWidths, constraints.gridx
                                            + constraints.gridwidth) - cell.x;
        cell.height = sumIntArray(info.rowHeights, constraints.gridy
                                             + constraints.gridheight) - cell.y;
	
        // Adjust for insets.
 	AdjustForGravity( constraints, cell );

        // Note: Documentation says that padding is added on both sides, but
        // visual inspection shows that the Sun implementation only adds it
        // once, so we do the same.
        dim.width += constraints.ipadx;
        dim.height += constraints.ipady;

        switch (constraints.fill)
          {
          case GridBagConstraints.HORIZONTAL:
            dim.width = cell.width;
            break;
          case GridBagConstraints.VERTICAL:
            dim.height = cell.height;
            break;
          case GridBagConstraints.BOTH:
            dim.width = cell.width;
            dim.height = cell.height;
            break;
          }

        int x = 0;
        int y = 0;

        switch (constraints.anchor)
          {
          case GridBagConstraints.NORTH:
            x = cell.x + (cell.width - dim.width) / 2;
            y = cell.y;
            break;
          case GridBagConstraints.SOUTH:
            x = cell.x + (cell.width - dim.width) / 2;
            y = cell.y + cell.height - dim.height;
            break;
          case GridBagConstraints.WEST:
            x = cell.x;
            y = cell.y + (cell.height - dim.height) / 2;
            break;
          case GridBagConstraints.EAST:
            x = cell.x + cell.width - dim.width;
            y = cell.y + (cell.height - dim.height) / 2;
            break;
          case GridBagConstraints.NORTHEAST:
            x = cell.x + cell.width - dim.width;
            y = cell.y;
            break;
          case GridBagConstraints.NORTHWEST:
            x = cell.x;
            y = cell.y;
            break;
          case GridBagConstraints.SOUTHEAST:
            x = cell.x + cell.width - dim.width;
            y = cell.y + cell.height - dim.height;
            break;
          case GridBagConstraints.SOUTHWEST:
            x = cell.x;
            y = cell.y + cell.height - dim.height;
            break;
          default:
            x = cell.x + (cell.width - dim.width) / 2;
            y = cell.y + (cell.height - dim.height) / 2;
            break;
          }
        component.setBounds(info.pos_x + x, info.pos_y + y, dim.width,
                            dim.height);
        lastComp = component;
      }

    // DEBUG
    //dumpLayoutInfo(info);

    // Cache layout information.
    layoutInfo = getLayoutInfo(parent, PREFERREDSIZE);
  }

    /**
     * Obsolete.
     */
    protected GridBagLayoutInfo GetLayoutInfo (Container parent, int sizeflag)
    {
      if (sizeflag != MINSIZE && sizeflag != PREFERREDSIZE)
        throw new IllegalArgumentException();

      Dimension parentDim = parent.getSize ();
      Insets parentInsets = parent.getInsets ();
      parentDim.width -= parentInsets.left + parentInsets.right;
      parentDim.height -= parentInsets.top + parentInsets.bottom;
   
      int current_y = 0;
      int max_x = 0;
      int max_y = 0;

      // Guaranteed to contain the last component added to the given row
      // or column, whose gridwidth/height is not REMAINDER.
      HashMap<Integer,Component> lastInRow = new HashMap<Integer,Component>();
      HashMap<Integer,Component> lastInCol = new HashMap<Integer,Component>();

      Component[] components = parent.getComponents();

      // Components sorted by gridwidths/heights,
      // smallest to largest, with REMAINDER and RELATIVE at the end.
      // These are useful when determining sizes and weights.
      ArrayList<Component> sortedByWidth =
	new ArrayList<Component>(components.length);
      ArrayList<Component> sortedByHeight =
	new ArrayList<Component>(components.length);

      // STEP 1: first we figure out how many rows/columns
      for (int i = 0; i < components.length; i++)
	{
          Component component = components [i];
          // If component is not visible we dont have to care about it.
          if (!component.isVisible())
            continue;

          // When looking up the constraint for the first time, check the
          // original unmodified constraint.  After the first time, always
          // refer to the internal modified constraint.
          GridBagConstraints originalConstraints = lookupConstraints (component);
          GridBagConstraints constraints = (GridBagConstraints) originalConstraints.clone();
          internalcomptable.put(component, constraints);

          // Cases:
          //
          // 1. gridy == RELATIVE, gridx == RELATIVE
          //
          //       use y as the row number; check for the next
          //       available slot at row y
          //
          // 2. only gridx == RELATIVE
          //
          //       check for the next available slot at row gridy
          //
          // 3. only gridy == RELATIVE
          //
          //       check for the next available slot at column gridx
          //
          // 4. neither gridx or gridy == RELATIVE
          //
          //       nothing to check; just add it

          // cases 1 and 2
          if(constraints.gridx == GridBagConstraints.RELATIVE)
            {
              if (constraints.gridy == GridBagConstraints.RELATIVE)
              constraints.gridy = current_y;

              int x;

              // Check the component that occupies the right-most spot in this
              // row. We want to add this component after it.
              // If this row is empty, add to the 0 position.
              if (!lastInRow.containsKey(new Integer(constraints.gridy))) 
                x = 0;
              else
                {
                  Component lastComponent = (Component) lastInRow.get(new Integer(constraints.gridy));
                  GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                  x = lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth);
                }

              // Determine if this component will fit in the slot vertically.
              // If not, bump it over to where it does fit.
              for (int y = constraints.gridy + 1; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
                {
                  if (lastInRow.containsKey(new Integer(y)))
                    {
                      Component lastComponent = (Component) lastInRow.get(new Integer(y));
                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                      x = Math.max (x,
                                    lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth));
                    }
                }

              constraints.gridx = x;
            }
          // case 3
          else if(constraints.gridy == GridBagConstraints.RELATIVE)
            {
              int y;
              // Check the component that occupies the bottom-most spot in
              // this column. We want to add this component below it.
              // If this column is empty, add to the 0 position.
              if (!lastInCol.containsKey(new Integer(constraints.gridx))) 
                {
                  y = current_y;
                }
              else
                {
                  Component lastComponent = (Component)lastInCol.get(new Integer(constraints.gridx));
                  GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                  y = lastConstraints.gridy + Math.max(1, lastConstraints.gridheight);
                }

              // Determine if this component will fit in the slot horizontally.
              // If not, bump it down to where it does fit.
              for (int x = constraints.gridx + 1; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
                {
                  if (lastInCol.containsKey(new Integer(x)))
                    {
                      Component lastComponent = (Component) lastInCol.get(new Integer(x));
                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                      y = Math.max (y,
                                    lastConstraints.gridy + Math.max(1, lastConstraints.gridheight));
                    }
                }

              constraints.gridy = y;
            }
          // case 4: do nothing

          max_x = Math.max(max_x, 
                           constraints.gridx + Math.max(1, constraints.gridwidth));
          max_y = Math.max(max_y,
                           constraints.gridy + Math.max(1, constraints.gridheight));

          sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
          sortBySpan(component, constraints.gridheight, sortedByHeight, false);

          // Update our reference points for RELATIVE gridx and gridy.
          if(constraints.gridwidth == GridBagConstraints.REMAINDER)
	    {
          current_y = constraints.gridy + Math.max(1, constraints.gridheight);
	    }
          else if (constraints.gridwidth != GridBagConstraints.REMAINDER)
	    {
              for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
                {
                  if(lastInRow.containsKey(new Integer(y)))
                    {
                      Component lastComponent = (Component) lastInRow.get(new Integer(y));
                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                      if (constraints.gridx > lastConstraints.gridx)
                        {
                          lastInRow.put(new Integer(y), component);
                        }
                    }
                  else
                    {
                      lastInRow.put(new Integer(y), component);
                    }
                }

              for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
                {
                  if(lastInCol.containsKey(new Integer(x)))
                    {
                      Component lastComponent = (Component) lastInCol.get(new Integer(x));
                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
                      if (constraints.gridy > lastConstraints.gridy)
                        {
                          lastInCol.put(new Integer(x), component);
                        }
                    }
                  else
                    {
                      lastInCol.put(new Integer(x), component);
                    }
                }
	    }
	} // end of STEP 1
	
      GridBagLayoutInfo info = new GridBagLayoutInfo(max_x, max_y);

      // Check if column widths and row heights are overridden.

      for (int x = 0; x < max_x; x++)
        {
          if(columnWidths != null && columnWidths.length > x)
            info.colWidths[x] = columnWidths[x];
          if(columnWeights != null && columnWeights.length > x)
            info.colWeights[x] = columnWeights[x];
        }

      for (int y = 0; y < max_y; y++)
        {
          if(rowHeights != null && rowHeights.length > y)
            info.rowHeights[y] = rowHeights[y];
          if(rowWeights != null && rowWeights.length > y)
            info.rowWeights[y] = rowWeights[y];
        }

      // STEP 2: Fix up any cells with width/height as REMAINDER/RELATIVE.
      for (int i = 0; i < components.length; i++)
        {
          Component component = components [i];
			
          // If component is not visible we dont have to care about it.
          if (!component.isVisible())
            continue;
			
          GridBagConstraints constraints = lookupInternalConstraints (component);

          if(constraints.gridwidth == GridBagConstraints.REMAINDER || constraints.gridwidth == GridBagConstraints.RELATIVE)
            {
              if(constraints.gridwidth == GridBagConstraints.REMAINDER)
                {
                  for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
                    {
                      if (lastInRow.containsKey(new Integer(y)))
                        {
                          Component lastComponent = (Component) lastInRow.get(new Integer(y));
                          GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);

                          if (lastConstraints.gridwidth == GridBagConstraints.RELATIVE)
                            {
                              constraints.gridx = max_x - 1;
                              break;
                            }
                          else
                            {
                              constraints.gridx = Math.max (constraints.gridx,
                                                            lastConstraints.gridx + Math.max (1, lastConstraints.gridwidth));
                            }
                        }
                    }
                  constraints.gridwidth = max_x - constraints.gridx;
                }
              else if (constraints.gridwidth == GridBagConstraints.RELATIVE)
                {
                  constraints.gridwidth = max_x - constraints.gridx - 1;
                }

              // Re-sort
              sortedByWidth.remove(sortedByWidth.indexOf(component));
              sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
            }

          if(constraints.gridheight == GridBagConstraints.REMAINDER || constraints.gridheight == GridBagConstraints.RELATIVE)
            {
              if(constraints.gridheight == GridBagConstraints.REMAINDER)
                {
                  for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
                    {
                      if (lastInCol.containsKey(new Integer(x)))
                        {
                          Component lastComponent = (Component) lastInRow.get(new Integer(x));
                          if (lastComponent != null)
                            {
                              GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
    
                              if (lastConstraints.gridheight == GridBagConstraints.RELATIVE)
                                {
                                  constraints.gridy = max_y - 1;
                                  break;
                                }
                              else
                                {
                                  constraints.gridy = Math.max (constraints.gridy,
                                                                lastConstraints.gridy + Math.max (1, lastConstraints.gridheight));
                                }
                            }
                        }
                    }
                  constraints.gridheight = max_y - constraints.gridy;
                }
              else if (constraints.gridheight == GridBagConstraints.RELATIVE)
                {
                  constraints.gridheight = max_y - constraints.gridy - 1;
                }

              // Re-sort
              sortedByHeight.remove(sortedByHeight.indexOf(component));
              sortBySpan(component, constraints.gridheight, sortedByHeight, false);
            }
        } // end of STEP 2

      // STEP 3: Determine sizes and weights for columns.
      for (int i = 0; i < sortedByWidth.size(); i++)
        {
          Component component = sortedByWidth.get(i);
			
          // If component is not visible we dont have to care about it.
          if (!component.isVisible())
            continue;

          GridBagConstraints constraints = lookupInternalConstraints (component);

          int width = (sizeflag == PREFERREDSIZE) ?
                      component.getPreferredSize().width :
                      component.getMinimumSize().width;

          if(constraints.insets != null)
            width += constraints.insets.left + constraints.insets.right;

          width += constraints.ipadx;

          distributeSizeAndWeight(width,
                                  constraints.weightx, 
                                  constraints.gridx,
                                  constraints.gridwidth,
                                  info.colWidths,
                                  info.colWeights);
        } // end of STEP 3

      // STEP 4: Determine sizes and weights for rows.
      for (int i = 0; i < sortedByHeight.size(); i++)
        {
          Component component = (Component) sortedByHeight.get(i);
			
          // If component is not visible we dont have to care about it.
          if (!component.isVisible())
            continue;

          GridBagConstraints constraints = lookupInternalConstraints (component);

          int height = (sizeflag == PREFERREDSIZE) ?
                       component.getPreferredSize().height :
                       component.getMinimumSize().height;

          if(constraints.insets != null)
            height += constraints.insets.top + constraints.insets.bottom;

          height += constraints.ipady;
          
          distributeSizeAndWeight(height,
                                  constraints.weighty, 
                                  constraints.gridy,
                                  constraints.gridheight,
                                  info.rowHeights,
                                  info.rowWeights);
        } // end of STEP 4

      // Adjust cell sizes iff parent size not zero.
      if (parentDim.width > 0 && parentDim.height > 0)
        {
          calcCellSizes (info.colWidths, info.colWeights, parentDim.width);
          calcCellSizes (info.rowHeights, info.rowWeights, parentDim.height);
        }

      int totalWidth = sumIntArray(info.colWidths);
      int totalHeight = sumIntArray(info.rowHeights);

      // Make sure pos_x and pos_y are never negative.
      if (totalWidth >= parentDim.width)
        info.pos_x = parentInsets.left;
      else
        info.pos_x = parentInsets.left + (parentDim.width - totalWidth) / 2;

      if (totalHeight >= parentDim.height)
        info.pos_y = parentInsets.top;
      else
        info.pos_y = parentInsets.top + (parentDim.height - totalHeight) / 2;

      // DEBUG
      //dumpLayoutInfo (info);

      return info;
    }

    /**
     * Obsolete.
     */
    protected Dimension GetMinSize (Container parent, GridBagLayoutInfo info)
    {
      if (parent == null || info == null)
        return new Dimension (0, 0);

      Insets insets = parent.getInsets();
      int width = sumIntArray (info.colWidths) + insets.left + insets.right;
      int height = sumIntArray (info.rowHeights) + insets.top + insets.bottom;
      return new Dimension (width, height);
    }

    /**
     * @since 1.4
     */
    protected Dimension getMinSize (Container parent, GridBagLayoutInfo info)
    {
      return GetMinSize (parent, info);
    }

    /**
     * Helper method used by GetLayoutInfo to keep components sorted, either
     * by gridwidth or gridheight.
     *
     * @param component   Component to add to the sorted list.
     * @param span        Either the component's gridwidth or gridheight.
     * @param list        <code>ArrayList</code> of components, sorted by
     *                    their span.
     * @param sortByWidth Flag indicating sorting index. If true, sort by
     *                    width. Otherwise, sort by height.
     * FIXME: Use a better sorting algorithm.
     */
    private void sortBySpan (Component component, int span,
			     ArrayList<Component> list, boolean sortByWidth)
    {
      if (span == GridBagConstraints.REMAINDER
          || span == GridBagConstraints.RELATIVE)
        {
          // Put all RELATIVE and REMAINDER components at the end.
          list.add(component);
        }
      else
        {
          int i = 0;
          if (list.size() > 0)
            {
              GridBagConstraints gbc = lookupInternalConstraints((Component) list.get(i));
              int otherspan = sortByWidth ?
                              gbc.gridwidth :
                              gbc.gridheight;
              while (otherspan != GridBagConstraints.REMAINDER
                     && otherspan != GridBagConstraints.RELATIVE
                     && span >= otherspan)
                {
                  i++;
                  if (i < list.size())
                    {
                      gbc = lookupInternalConstraints((Component) list.get(i));
                      otherspan = sortByWidth ?
                                  gbc.gridwidth :
                                  gbc.gridheight;
                    }
                  else
                    break;
                }
            }
          list.add(i, component);
        }
    }

    /**
     * Helper method used by GetLayoutInfo to distribute a component's size
     * and weight.
     *
     * @param size    Preferred size of component, with inset and padding
     *                already added.
     * @param weight  Weight of component.
     * @param start   Starting position of component. Either
     *                constraints.gridx or gridy.
     * @param span    Span of component. either contraints.gridwidth or
     *                gridheight.
     * @param sizes   Sizes of rows or columns.
     * @param weights Weights of rows or columns.
     */
    private void distributeSizeAndWeight (int size, double weight,
                                          int start, int span,
                                          int[] sizes, double[] weights)
    {
      if (span == 1)
        {
          sizes[start] = Math.max(sizes[start], size);
          weights[start] = Math.max(weights[start], weight);
        }
      else
        {
          int numOccupied = span;
          int lastOccupied = -1;

          for(int i = start; i < start + span; i++)
            {
              if (sizes[i] == 0.0)
                numOccupied--;
              else
                {
                  size -= sizes[i];
                  lastOccupied = i;
                }
            }

          // A component needs to occupy at least one row.
          if(numOccupied == 0)
            sizes[start + span - 1] = size;
          else if (size > 0)
            sizes[lastOccupied] += size;

          calcCellWeights(weight, weights, start, span);
        }
    }

    /**
     * Helper method used by GetLayoutInfo to calculate weight distribution.
     * @param weight  Weight of component.
     * @param weights Weights of rows/columns.
     * @param start   Starting position of component in grid (gridx/gridy).
     * @param span    Span of component (gridwidth/gridheight).
     */
    private void calcCellWeights (double weight, double[] weights, int start, int span)
    {
      double totalWeight = 0.0;
      for(int k = start; k < start + span; k++)
        totalWeight += weights[k];

      if(weight > totalWeight)
        {
          if (totalWeight == 0.0)
            {
              weights[start + span - 1] += weight;
            }
          else
            {
              double diff = weight - totalWeight ;
              double remaining = diff;

              for(int k = start; k < start + span; k++)
                {
                  double extraWeight = diff * weights[k] / totalWeight;
                  weights[k] += extraWeight;
                  remaining -= extraWeight;
                } 

              if (remaining > 0.0 && weights[start + span - 1] != 0.0)
                {
                  weights[start + span - 1] += remaining;
                }
            }
        }
    }

    /**
     * Helper method used by GetLayoutInfo to distribute extra space
     * based on weight distribution.
     *
     * @param sizes   Sizes of rows/columns.
     * @param weights Weights of rows/columns.
     * @param range   Dimension of container.
     */
    private void calcCellSizes (int[] sizes, double[] weights, int range)
    {
      int totalSize = sumIntArray (sizes);
      double totalWeight = sumDoubleArray (weights);

      int diff = range - totalSize;

      if (diff == 0)
        return;

      for (int i = 0; i < sizes.length; i++)
        {
          int newsize = (int) (sizes[i] + (((double) diff) * weights [i] / totalWeight ));

          if (newsize > 0)
            sizes[i] = newsize;
        }
    }

    private void dumpLayoutInfo (GridBagLayoutInfo info)
    {
	System.out.println ("GridBagLayoutInfo:");
	System.out.println ("cols: " + info.cols + ", rows: " + info.rows);
	System.out.print ("colWidths: ");
	dumpArray(info.colWidths);
	System.out.print ("rowHeights: ");
	dumpArray(info.rowHeights);
	System.out.print ("colWeights: ");
	dumpArray(info.colWeights);
	System.out.print ("rowWeights: ");
	dumpArray(info.rowWeights);
    }

    private void dumpArray(int[] array)
    {
	String sep = "";
	for(int i = 0; i < array.length; i++)
	{
	    System.out.print(sep);
	    System.out.print(array[i]);
	    sep = ", ";
	}
	System.out.println();
    }

    private void dumpArray(double[] array)
    {
	String sep = "";
	for(int i = 0; i < array.length; i++)
	{
	    System.out.print(sep);
	    System.out.print(array[i]);
	    sep = ", ";
	}
	System.out.println();
    }
  
    /**
     * @since 1.4
     */
    protected void arrangeGrid (Container parent)
    {
      ArrangeGrid (parent);
    }

    /**
     * @since 1.4
     */
    protected GridBagLayoutInfo getLayoutInfo (Container parent, int sizeflag)
    {
      return GetLayoutInfo (parent, sizeflag);
    }

    /**
     * Move and resize a rectangle according to a set of grid bag
     * constraints.  The x, y, width and height fields of the
     * rectangle argument are adjusted to the new values.
     *
     * @param constraints position and size constraints
     * @param r rectangle to be moved and resized
     *
     * @since 1.4
     */
    protected void adjustForGravity (GridBagConstraints constraints,
                                     Rectangle r)
    {
      AdjustForGravity (constraints, r);
    }
}
