/* 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 = comptable.get (component);

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

        return result;
    }

    private GridBagConstraints lookupInternalConstraints (Component component)
    {
        GridBagConstraints result = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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(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(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);
    }
}
