/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Asim Ullah - Ported for use in draw2d (c.f Bugzilla 71684). [Sep 10, 2004]
 *******************************************************************************/
package org.eclipse.draw2d;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * Lays out children into a Grid arrangement in which overall aligment and
 * spacing can be configured, as well as specfic layout requirements for the
 * each individual member of the GridLayout. This layout is a Draw2D port of the
 * swt GridLayout.
 * 
 * <code>GridLayout</code> has a number of configuration fields, and the Figures
 * it lays out can have an associated layout data object, called
 * <code>GridData</code> (similar to the swt GridData object). The power of
 * <code>GridLayout</code> lies in the ability to configure
 * <code>GridData</code> for each Figure in the layout.
 * <p>
 * The following code creates a container Figure managed by a
 * <code>GridLayout</code> with 2 columns, containing 3 RectangleFigure shapes,
 * the last of which has been given further layout instructions. Note that it is
 * the <code>GridLayout</code> method <code>setConstraint</code> that binds the
 * child <code>Figure</code> to its layout <code>GridData</code> object.
 * 
 * <pre>
 * Figure container = new Figure();
 * GridLayout gridLayout = new GridLayout();
 * gridLayout.numColumns = 2;
 * container.setLayout(gridLayout);
 * 
 * Shape rect;
 * rect = new RectangleFigure();
 * container.add(rect);
 * 
 * rect = new RectangleFigure();
 * container.add(rect);
 * 
 * rect = new RectangleFigure();
 * GridData gridData = new GridData();
 * gridData.widthHint = 150;
 * layout.setConstraint(rect, gridData);
 * 
 * container.add(rect);
 * </pre>
 * 
 * <p>
 * The <code>numColumns</code> field is the most important field in a
 * <code>GridLayout</code>. Widgets are laid out in columns from left to right,
 * and a new row is created when <code>numColumns</code>+ 1 figures are added to
 * the <code>Figure<code> parent container.
 * 
 * @see GridData
 * 
 */
public class GridLayout extends AbstractLayout {

	/**
	 * numColumns specifies the number of cell columns in the layout.
	 * 
	 * The default value is 1.
	 */
	public int numColumns = 1;

	/**
	 * makeColumnsEqualWidth specifies whether all columns in the layout will be
	 * forced to have the same width.
	 * 
	 * The default value is false.
	 */
	public boolean makeColumnsEqualWidth = false;

	/**
	 * marginWidth specifies the number of pixels of horizontal margin that will
	 * be placed along the left and right edges of the layout.
	 * 
	 * The default value is 5.
	 */
	public int marginWidth = 5;

	/**
	 * marginHeight specifies the number of pixels of vertical margin that will
	 * be placed along the top and bottom edges of the layout.
	 * 
	 * The default value is 5.
	 */
	public int marginHeight = 5;

	/**
	 * horizontalSpacing specifies the number of pixels between the right edge
	 * of one cell and the left edge of its neighbouring cell to the right.
	 * 
	 * The default value is 5.
	 */
	public int horizontalSpacing = 5;

	/**
	 * verticalSpacing specifies the number of pixels between the bottom edge of
	 * one cell and the top edge of its neighbouring cell underneath.
	 * 
	 * The default value is 5.
	 */
	public int verticalSpacing = 5;

	/** The layout contraints */
	protected Map constraints = new HashMap();

	/**
	 * Default Constructor
	 */
	public GridLayout() {
		super();
	}

	/**
	 * Constructs a new instance of this class given the number of columns, and
	 * whether or not the columns should be forced to have the same width.
	 * 
	 * @param numColumns
	 *            the number of columns in the grid
	 * @param makeColumnsEqualWidth
	 *            whether or not the columns will have equal width
	 * 
	 */
	public GridLayout(int numColumns, boolean makeColumnsEqualWidth) {
		this.numColumns = numColumns;
		this.makeColumnsEqualWidth = makeColumnsEqualWidth;
	}

	/**
	 * @param child
	 * @param wHint
	 * @param hHint
	 * @return the child size.
	 */
	protected Dimension getChildSize(IFigure child, int wHint, int hHint) {
		return child.getPreferredSize(wHint, hHint);
	}

	GridData getData(IFigure[][] grid, int row, int column, int rowCount,
			int columnCount, boolean first) {
		IFigure figure = grid[row][column];
		if (figure != null) {
			GridData data = (GridData) getConstraint(figure);
			int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
			int vSpan = Math.max(1, data.verticalSpan);
			int i = first ? row + vSpan - 1 : row - vSpan + 1;
			int j = first ? column + hSpan - 1 : column - hSpan + 1;
			if (0 <= i && i < rowCount) {
				if (0 <= j && j < columnCount) {
					if (figure == grid[i][j])
						return data;
				}
			}
		}
		return null;
	}

	void initChildren(IFigure container) {
		List children = container.getChildren();
		for (int i = 0; i < children.size(); i++) {
			IFigure child = (IFigure) children.get(i);
			if (child.getLayoutManager() == null)
				child.setLayoutManager(this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse.
	 * draw2d.IFigure, int, int)
	 */
	protected Dimension calculatePreferredSize(IFigure container, int wHint,
			int hHint) {
		Dimension size = layout(container, false, 0, 0, wHint, hHint, /* flushCache */
		true);
		if (wHint != SWT.DEFAULT)
			size.width = wHint;
		if (hHint != SWT.DEFAULT)
			size.height = hHint;

		/*
		 * Adjust for the size of the border
		 */
		size.expand(container.getInsets().getWidth(), container.getInsets()
				.getHeight());
		size.union(getBorderPreferredSize(container));

		return size;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure)
	 */
	public void layout(IFigure container) {
		// initChildren( container);
		Rectangle rect = container.getClientArea();
		layout(container, true, rect.x, rect.y, rect.width, rect.height, /* flushCache */
		true);

	}

	Dimension layout(IFigure container, boolean move, int x, int y, int width,
			int height, boolean flushCache) {
		if (numColumns < 1)
			return new Dimension(marginWidth * 2, marginHeight * 2);
		List children = container.getChildren();
		for (int i = 0; i < children.size(); i++) {
			IFigure child = (IFigure) children.get(i);

			GridData data = (GridData) getConstraint(child);
			if (data == null)
				setConstraint(child, data = new GridData());
			if (flushCache)
				data.flushCache();
			data.computeSize(child, flushCache);
		}

		/* Build the grid */
		int row = 0, column = 0, rowCount = 0, columnCount = numColumns;
		IFigure[][] grid = new IFigure[4][columnCount];
		for (int i = 0; i < children.size(); i++) {
			IFigure child = (IFigure) children.get(i);
			GridData data = (GridData) getConstraint(child);
			int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
			int vSpan = Math.max(1, data.verticalSpan);
			while (true) {
				int lastRow = row + vSpan;
				if (lastRow >= grid.length) {
					IFigure[][] newGrid = new IFigure[lastRow + 4][columnCount];
					System.arraycopy(grid, 0, newGrid, 0, grid.length);
					grid = newGrid;
				}
				if (grid[row] == null) {
					grid[row] = new IFigure[columnCount];
				}
				while (column < columnCount && grid[row][column] != null) {
					column++;
				}
				int endCount = column + hSpan;
				if (endCount <= columnCount) {
					int index = column;
					while (index < endCount && grid[row][index] == null) {
						index++;
					}
					if (index == endCount)
						break;
					column = index;
				}
				if (column + hSpan >= columnCount) {
					column = 0;
					row++;
				}
			}
			for (int j = 0; j < vSpan; j++) {
				if (grid[row + j] == null) {
					grid[row + j] = new IFigure[columnCount];
				}
				for (int k = 0; k < hSpan; k++) {
					grid[row + j][column + k] = child;
				}
			}
			rowCount = Math.max(rowCount, row + vSpan);
			column += hSpan;
		}

		/* Column widths */
		int availableWidth = width - horizontalSpacing * (columnCount - 1)
				- marginWidth * 2;
		int expandCount = 0;
		int[] widths = new int[columnCount];
		int[] minWidths = new int[columnCount];
		boolean[] expandColumn = new boolean[columnCount];
		for (int j = 0; j < columnCount; j++) {
			for (int i = 0; i < rowCount; i++) {
				GridData data = getData(grid, i, j, rowCount, columnCount, true);
				if (data != null) {
					int hSpan = Math.max(1,
							Math.min(data.horizontalSpan, columnCount));
					if (hSpan == 1) {
						int w = data.cacheWidth + data.horizontalIndent;
						widths[j] = Math.max(widths[j], w);
						if (data.grabExcessHorizontalSpace) {
							if (!expandColumn[j])
								expandCount++;
							expandColumn[j] = true;
						}
						if (data.widthHint != SWT.DEFAULT
								|| !data.grabExcessHorizontalSpace) {
							minWidths[j] = Math.max(minWidths[j], w);
						}
					}
				}
			}
			for (int i = 0; i < rowCount; i++) {
				GridData data = getData(grid, i, j, rowCount, columnCount,
						false);
				if (data != null) {
					int hSpan = Math.max(1,
							Math.min(data.horizontalSpan, columnCount));
					if (hSpan > 1) {
						int spanWidth = 0, spanMinWidth = 0, spanExpandCount = 0;
						for (int k = 0; k < hSpan; k++) {
							spanWidth += widths[j - k];
							spanMinWidth += minWidths[j - k];
							if (expandColumn[j - k])
								spanExpandCount++;
						}
						if (data.grabExcessHorizontalSpace
								&& spanExpandCount == 0) {
							expandCount++;
							expandColumn[j] = true;
						}
						int w = data.cacheWidth + data.horizontalIndent
								- spanWidth - (hSpan - 1) * horizontalSpacing;
						if (w > 0) {
							if (spanExpandCount == 0) {
								widths[j] += w;
							} else {
								int delta = w / spanExpandCount;
								int remainder = w % spanExpandCount, last = -1;
								for (int k = 0; k < hSpan; k++) {
									if (expandColumn[j - k]) {
										widths[last = j - k] += delta;
									}
								}
								if (last > -1)
									widths[last] += remainder;
							}
						}
						if (data.widthHint != SWT.DEFAULT
								|| !data.grabExcessHorizontalSpace) {
							w = data.cacheWidth + data.horizontalIndent
									- spanMinWidth - (hSpan - 1)
									* horizontalSpacing;
							if (w > 0) {
								if (spanExpandCount == 0) {
									minWidths[j] += w;
								} else {
									int delta = w / spanExpandCount;
									int remainder = w % spanExpandCount, last = -1;
									for (int k = 0; k < hSpan; k++) {
										if (expandColumn[j - k]) {
											minWidths[last = j - k] += delta;
										}
									}
									if (last > -1)
										minWidths[last] += remainder;
								}
							}
						}
					}
				}
			}
		}
		if (makeColumnsEqualWidth) {
			int minColumnWidth = 0;
			int columnWidth = 0;
			for (int i = 0; i < columnCount; i++) {
				minColumnWidth = Math.max(minColumnWidth, minWidths[i]);
				columnWidth = Math.max(columnWidth, widths[i]);
			}
			columnWidth = width == SWT.DEFAULT || expandCount == 0 ? columnWidth
					: Math.max(minColumnWidth, availableWidth / columnCount);
			for (int i = 0; i < columnCount; i++) {
				expandColumn[i] = expandCount > 0;
				widths[i] = columnWidth;
			}
		} else {
			if (width != SWT.DEFAULT && expandCount > 0) {
				int totalWidth = 0;
				for (int i = 0; i < columnCount; i++) {
					totalWidth += widths[i];
				}
				int count = expandCount;
				int delta = (availableWidth - totalWidth) / count;
				int remainder = (availableWidth - totalWidth) % count;
				int last = -1;
				while (totalWidth != availableWidth) {
					for (int j = 0; j < columnCount; j++) {
						if (expandColumn[j]) {
							if (widths[j] + delta > minWidths[j]) {
								widths[last = j] = widths[j] + delta;
							} else {
								widths[j] = minWidths[j];
								expandColumn[j] = false;
								count--;
							}
						}
					}
					if (last > -1)
						widths[last] += remainder;

					for (int j = 0; j < columnCount; j++) {
						for (int i = 0; i < rowCount; i++) {
							GridData data = getData(grid, i, j, rowCount,
									columnCount, false);
							if (data != null) {
								int hSpan = Math.max(1, Math.min(
										data.horizontalSpan, columnCount));
								if (hSpan > 1) {
									if (data.widthHint != SWT.DEFAULT
											|| !data.grabExcessHorizontalSpace) {
										int spanWidth = 0, spanExpandCount = 0;
										for (int k = 0; k < hSpan; k++) {
											spanWidth += widths[j - k];
											if (expandColumn[j - k])
												spanExpandCount++;
										}
										int w = data.cacheWidth
												+ data.horizontalIndent
												- spanWidth - (hSpan - 1)
												* horizontalSpacing;
										if (w > 0) {
											if (spanExpandCount == 0) {
												widths[j] += w;
											} else {
												int delta2 = w
														/ spanExpandCount;
												int remainder2 = w
														% spanExpandCount, last2 = -1;
												for (int k = 0; k < hSpan; k++) {
													if (expandColumn[j - k]) {
														widths[last2 = j - k] += delta2;
													}
												}
												if (last2 > -1)
													widths[last2] += remainder2;
											}
										}
									}
								}
							}
						}
					}
					if (count == 0)
						break;
					totalWidth = 0;
					for (int i = 0; i < columnCount; i++) {
						totalWidth += widths[i];
					}
					delta = (availableWidth - totalWidth) / count;
					remainder = (availableWidth - totalWidth) % count;
					last = -1;
				}
			}
		}

		/* Wrapping */
		GridData[] flush = null;
		int flushLength = 0;
		if (width != SWT.DEFAULT) {
			for (int j = 0; j < columnCount; j++) {
				for (int i = 0; i < rowCount; i++) {
					GridData data = getData(grid, i, j, rowCount, columnCount,
							false);
					if (data != null) {
						if (data.heightHint == SWT.DEFAULT) {
							IFigure child = grid[i][j];
							// TEMPORARY CODE
							int hSpan = Math.max(1,
									Math.min(data.horizontalSpan, columnCount));
							int currentWidth = 0;
							for (int k = 0; k < hSpan; k++) {
								currentWidth += widths[j - k];
							}
							currentWidth += (hSpan - 1) * horizontalSpacing
									- data.horizontalIndent;
							if ((currentWidth != data.cacheWidth && data.horizontalAlignment == SWT.FILL)
									|| (data.cacheWidth > currentWidth)) {
								int trim = 0;
								/*
								 * // *Note*: Left this in place from SWT //
								 * GridLayout. Not sure if Draw2D Borders or //
								 * Scrollbars 'trim' will need to be takeninto
								 * account.
								 * 
								 * if (child instanceof Group) { Group g
								 * =(Group)child; trim = g.getSize ().x -
								 * g.getClientArea ().width; } else if (child
								 * instanceof Scrollable) { Rectangle rect =
								 * ((Scrollable) child).computeTrim (0, 0, 0,0);
								 * trim = rect.width; } else { trim =
								 * child.getBorderWidth () * 2; }
								 */
								int oldWidthHint = data.widthHint;
								data.widthHint = Math.max(0, currentWidth
										- trim);
								data.cacheWidth = data.cacheHeight = SWT.DEFAULT;
								data.computeSize(child, false);
								data.widthHint = oldWidthHint;
								if (flush == null)
									flush = new GridData[children.size()];
								flush[flushLength++] = data;
							}
						}
					}
				}
			}
		}

		/* Row heights */
		int availableHeight = height - verticalSpacing * (rowCount - 1)
				- marginHeight * 2;
		expandCount = 0;
		int[] heights = new int[rowCount];
		int[] minHeights = new int[rowCount];
		boolean[] expandRow = new boolean[rowCount];
		for (int i = 0; i < rowCount; i++) {
			for (int j = 0; j < columnCount; j++) {
				GridData data = getData(grid, i, j, rowCount, columnCount, true);
				if (data != null) {
					int vSpan = Math.max(1,
							Math.min(data.verticalSpan, rowCount));
					if (vSpan == 1) {
						int h = data.cacheHeight; // + data.verticalIndent;
						heights[i] = Math.max(heights[i], h);
						if (data.grabExcessVerticalSpace) {
							if (!expandRow[i])
								expandCount++;
							expandRow[i] = true;
						}
						if (data.heightHint != SWT.DEFAULT
								|| !data.grabExcessVerticalSpace) {
							minHeights[i] = Math.max(minHeights[i], h);
						}
					}
				}
			}
			for (int j = 0; j < columnCount; j++) {
				GridData data = getData(grid, i, j, rowCount, columnCount,
						false);
				if (data != null) {
					int vSpan = Math.max(1,
							Math.min(data.verticalSpan, rowCount));
					if (vSpan > 1) {
						int spanHeight = 0, spanMinHeight = 0, spanExpandCount = 0;
						for (int k = 0; k < vSpan; k++) {
							spanHeight += heights[i - k];
							spanMinHeight += minHeights[i - k];
							if (expandRow[i - k])
								spanExpandCount++;
						}
						if (data.grabExcessVerticalSpace
								&& spanExpandCount == 0) {
							expandCount++;
							expandRow[i] = true;
						}
						int h = data.cacheHeight - spanHeight - (vSpan - 1)
								* verticalSpacing; // + data.verticalalIndent
						if (h > 0) {
							if (spanExpandCount == 0) {
								heights[i] += h;
							} else {
								int delta = h / spanExpandCount;
								int remainder = h % spanExpandCount, last = -1;
								for (int k = 0; k < vSpan; k++) {
									if (expandRow[i - k]) {
										heights[last = i - k] += delta;
									}
								}
								if (last > -1)
									heights[last] += remainder;
							}
						}
						if (data.heightHint != SWT.DEFAULT
								|| !data.grabExcessVerticalSpace) {
							h = data.cacheHeight - spanMinHeight - (vSpan - 1)
									* verticalSpacing; // + data.verticalIndent
							if (h > 0) {
								if (spanExpandCount == 0) {
									minHeights[i] += h;
								} else {
									int delta = h / spanExpandCount;
									int remainder = h % spanExpandCount, last = -1;
									for (int k = 0; k < vSpan; k++) {
										if (expandRow[i - k]) {
											minHeights[last = i - k] += delta;
										}
									}
									if (last > -1)
										minHeights[last] += remainder;
								}
							}
						}
					}
				}
			}
		}
		if (height != SWT.DEFAULT && expandCount > 0) {
			int totalHeight = 0;
			for (int i = 0; i < rowCount; i++) {
				totalHeight += heights[i];
			}
			int count = expandCount;
			int delta = (availableHeight - totalHeight) / count;
			int remainder = (availableHeight - totalHeight) % count;
			int last = -1;
			while (totalHeight != availableHeight) {
				for (int i = 0; i < rowCount; i++) {
					if (expandRow[i]) {
						if (heights[i] + delta > minHeights[i]) {
							heights[last = i] = heights[i] + delta;
						} else {
							heights[i] = minHeights[i];
							expandRow[i] = false;
							count--;
						}
					}
				}
				if (last > -1)
					heights[last] += remainder;

				for (int i = 0; i < rowCount; i++) {
					for (int j = 0; j < columnCount; j++) {
						GridData data = getData(grid, i, j, rowCount,
								columnCount, false);
						if (data != null) {
							int vSpan = Math.max(1,
									Math.min(data.verticalSpan, rowCount));
							if (vSpan > 1) {
								if (data.heightHint != SWT.DEFAULT
										|| !data.grabExcessVerticalSpace) {
									int spanHeight = 0, spanExpandCount = 0;
									for (int k = 0; k < vSpan; k++) {
										spanHeight += heights[i - k];
										if (expandRow[i - k])
											spanExpandCount++;
									}
									int h = data.cacheHeight - spanHeight
											- (vSpan - 1) * verticalSpacing; // +
									// data.verticalIndent
									if (h > 0) {
										if (spanExpandCount == 0) {
											heights[i] += h;
										} else {
											int delta2 = h / spanExpandCount;
											int remainder2 = h
													% spanExpandCount, last2 = -1;
											for (int k = 0; k < vSpan; k++) {
												if (expandRow[i - k]) {
													heights[last2 = i - k] += delta2;
												}
											}
											if (last2 > -1)
												heights[last2] += remainder2;
										}
									}
								}
							}
						}
					}
				}
				if (count == 0)
					break;
				totalHeight = 0;
				for (int i = 0; i < rowCount; i++) {
					totalHeight += heights[i];
				}
				delta = (availableHeight - totalHeight) / count;
				remainder = (availableHeight - totalHeight) % count;
				last = -1;
			}
		}

		/* Position the IFigures */
		if (move) {
			int gridY = y + marginHeight;
			for (int i = 0; i < rowCount; i++) {
				int gridX = x + marginWidth;
				for (int j = 0; j < columnCount; j++) {
					GridData data = getData(grid, i, j, rowCount, columnCount,
							true);
					if (data != null) {
						int hSpan = Math.max(1,
								Math.min(data.horizontalSpan, columnCount));
						int vSpan = Math.max(1, data.verticalSpan);
						int cellWidth = 0, cellHeight = 0;
						for (int k = 0; k < hSpan; k++) {
							cellWidth += widths[j + k];
						}
						for (int k = 0; k < vSpan; k++) {
							cellHeight += heights[i + k];
						}
						cellWidth += horizontalSpacing * (hSpan - 1);
						int childX = gridX + data.horizontalIndent;
						int childWidth = Math.min(data.cacheWidth, cellWidth);
						switch (data.horizontalAlignment) {
						case SWT.CENTER:
						case GridData.CENTER:
							childX = gridX
									+ Math.max(0, (cellWidth - childWidth) / 2);
							break;
						case SWT.RIGHT:
						case SWT.END:
						case GridData.END:
							childX = gridX
									+ Math.max(0, cellWidth - childWidth);
							break;
						case SWT.FILL:
							childWidth = cellWidth - data.horizontalIndent;
							break;
						}
						cellHeight += verticalSpacing * (vSpan - 1);
						int childY = gridY; // + data.verticalIndent;
						int childHeight = Math
								.min(data.cacheHeight, cellHeight);
						switch (data.verticalAlignment) {
						case SWT.CENTER:
						case GridData.CENTER:
							childY = gridY
									+ Math.max(0,
											(cellHeight - childHeight) / 2);
							break;
						case SWT.BOTTOM:
						case SWT.END:
						case GridData.END:
							childY = gridY
									+ Math.max(0, cellHeight - childHeight);
							break;
						case SWT.FILL:
							childHeight = cellHeight; // -
							// data.verticalIndent;
							break;
						}
						IFigure child = grid[i][j];
						if (child != null) {
							// following param could be replaced by
							// Rectangle.SINGLETON
							child.setBounds(new Rectangle(childX, childY,
									childWidth, childHeight));
						}
					}
					gridX += widths[j] + horizontalSpacing;
				}
				gridY += heights[i] + verticalSpacing;
			}
		}

		// clean up cache
		for (int i = 0; i < flushLength; i++) {
			flush[i].cacheWidth = flush[i].cacheHeight = -1;
		}

		int totalDefaultWidth = 0;
		int totalDefaultHeight = 0;
		for (int i = 0; i < columnCount; i++) {
			totalDefaultWidth += widths[i];
		}
		for (int i = 0; i < rowCount; i++) {
			totalDefaultHeight += heights[i];
		}
		totalDefaultWidth += horizontalSpacing * (columnCount - 1)
				+ marginWidth * 2;
		totalDefaultHeight += verticalSpacing * (rowCount - 1) + marginHeight
				* 2;
		return new Dimension(totalDefaultWidth, totalDefaultHeight);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.draw2d.LayoutManager#getConstraint(org.eclipse.draw2d.IFigure
	 * )
	 */
	public Object getConstraint(IFigure child) {
		return constraints.get(child);
	}

	/**
	 * Sets the layout constraint of the given figure. The constraints can only
	 * be of type {@link GridData}.
	 * 
	 * @see LayoutManager#setConstraint(IFigure, Object)
	 */
	public void setConstraint(IFigure figure, Object newConstraint) {
		super.setConstraint(figure, newConstraint);
		if (newConstraint != null) {
			constraints.put(figure, newConstraint);

		}
	}

}