/*******************************************************************************
 * 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.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;

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

		}
	}

}