package org.eclipse.swt.layout;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public final class RowLayout extends Layout {
	/**
	 * type specifies whether the layout places controls in rows or 
	 * columns.
	 * 
	 * The default value is horizontal.
	 * 
	 * @since 2.0
	 */
	public int type = SWT.HORIZONTAL;	
	/**
	 * wrap specifies whether a control will be wrapped to the next
	 * row if there is insufficient space on the current row.
	 *
	 * The default value is true.
	 */
	public boolean wrap = true;
	/**
	 * pack specifies whether all controls in the layout are forced
	 * to be the same size.
	 *
	 * The default value is true.
	 */
	public boolean pack = true;
	/**
	 * justify specifies whether the controls in a row should be
	 * fully justified, with any extra space placed between the controls.
	 *
	 * The default value is false.
	 */
	public boolean justify = false;
	/**
	 * spacing specifies the number of pixels between the edge of one cell
	 * and the edge of its neighbouring cell.
	 *
	 * The default value is 3.
	 */
	public int spacing = 3;
	/**
	 * marginLeft specifies the number of pixels of horizontal margin
	 * that will be placed along the left edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginLeft = 3;
	/**
	 * marginTop specifies the number of pixels of vertical margin
	 * that will be placed along the top edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginTop = 3;
	/**
	 * marginRight specifies the number of pixels of horizontal margin
	 * that will be placed along the right edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginRight = 3;
	/**
	 * marginBottom specifies the number of pixels of vertical margin
	 * that will be placed along the bottom edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginBottom = 3;

public RowLayout () {
}

protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) {
	Point extent;
	if (type == SWT.HORIZONTAL) {
		extent = layoutHorizontal (composite, false, (wHint != SWT.DEFAULT) && wrap, wHint, flushCache);
	} else {
		extent = layoutVertical (composite, false, (hHint != SWT.DEFAULT) && wrap, wHint, flushCache);
	}
	if (wHint != SWT.DEFAULT) extent.x = wHint;
	if (hHint != SWT.DEFAULT) extent.y = hHint;
	return extent;
}

Point getSize (Control control, boolean flushCache) {
	int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT;
	RowData data = (RowData) control.getLayoutData ();
	if (data != null) {
		wHint = data.width;
		hHint = data.height;
	}
	return control.computeSize (wHint, hHint, flushCache);
}

protected void layout (Composite composite, boolean flushCache) {
	Rectangle clientArea = composite.getClientArea ();
	if (type == SWT.HORIZONTAL) {
		layoutHorizontal (composite, true, wrap, clientArea.width, flushCache);
	} else {
		layoutVertical (composite, true, wrap, clientArea.height, flushCache);
	}
}

Point layoutHorizontal (Composite composite, boolean move, boolean wrap, int width, boolean flushCache) {
	Control [] children = composite.getChildren ();
	int count = children.length;
	int childWidth = 0, childHeight = 0, maxHeight = 0;
	if (!pack) {
		for (int i=0; i<count; i++) {
			Control child = children [i];
			Point pt = getSize (child, flushCache);
			childWidth = Math.max (childWidth, pt.x);
			childHeight = Math.max (childHeight, pt.y);
		}
		maxHeight = childHeight;
	}
	int clientX = 0, clientY = 0;
	if (move) {
		Rectangle rect = composite.getClientArea ();
		clientX = rect.x;  clientY = rect.y;
	}
	boolean wrapped = false;
	Rectangle [] bounds = null;
	if (move && justify) bounds = new Rectangle [count];
	int maxX = 0, x = marginLeft, y = marginTop;
	for (int i=0; i<count; i++) {
		Control child = children [i];
		if (pack) {
			Point pt = getSize (child, flushCache);
			childWidth = pt.x;  childHeight = pt.y;
		}
		if (wrap && (i != 0) && (x + childWidth > width)) {
			wrapped = true;
			x = marginLeft;  y += spacing + maxHeight;
		}
		if (pack) {
			maxHeight = Math.max (maxHeight, childHeight);
		}
		if (move) {
			int childX = x + clientX, childY = y + clientY;
			if (justify) {
				bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
			} else {
				child.setBounds (childX, childY, childWidth, childHeight);
			}
		}
		x += spacing + childWidth;
		maxX = Math.max (maxX, x);
	}
	if (!wrap) maxX = x + marginRight;
	if (move && justify) {
		int space = 0, margin = 0;
		if (!wrapped) {
			space = Math.max (0, (width - maxX) / (count + 1));
			margin = Math.max (0, ((width - maxX) % (count + 1)) / 2);
		}
		for (int i=0; i<count; i++) {
			Control child = children [i];
			bounds [i].x += (space * (i + 1)) + margin;
			child.setBounds (bounds [i]);
		}
	}
	return new Point (maxX, y + maxHeight + marginBottom);
}

Point layoutVertical (Composite composite, boolean move, boolean wrap, int height, boolean flushCache) {
	Control [] children = composite.getChildren ();
	int count = children.length;
	int childWidth = 0, childHeight = 0, maxWidth = 0;
	if (!pack) {
		for (int i=0; i<count; i++) {
			Control child = children [i];
			Point pt = getSize (child, flushCache);
			childWidth = Math.max (childWidth, pt.x);
			childHeight = Math.max (childHeight, pt.y);
		}
		maxWidth = childWidth;
	}
	int clientX = 0, clientY = 0;
	if (move) {
		Rectangle rect = composite.getClientArea ();
		clientX = rect.x;  clientY = rect.y;
	}
	boolean wrapped = false;
	Rectangle [] bounds = null;
	if (move && justify) bounds = new Rectangle [count];
	int maxY = 0, x = marginLeft, y = marginTop;
	for (int i=0; i<count; i++) {
		Control child = children [i];
		if (pack) {
			Point pt = getSize (child, flushCache);
			childWidth = pt.x;  childHeight = pt.y;
		}
		if (wrap && (i != 0) && (y + childHeight > height)) {
			wrapped = true;
			x += spacing + maxWidth;  y = marginTop;
		}
		if (pack) {
			maxWidth = Math.max (maxWidth, childWidth);
		}
		if (move) {
			int childX = x + clientX, childY = y + clientY;
			if (justify) {
				bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
			} else {
				child.setBounds (childX, childY, childWidth, childHeight);
			}
		}
		y += spacing + childHeight;
		maxY = Math.max (maxY, y);
	}
	if (!wrap) maxY = y + marginBottom;
	if (move && justify) {
		int space = 0, margin = 0;
		if (!wrapped) {
			space = Math.max (0, (height - maxY) / (count + 1));
			margin = Math.max (0, ((height - maxY) % (count + 1)) / 2);
		}
		for (int i=0; i<count; i++) {
			Control child = children [i];
			bounds [i].y += (space * (i + 1)) + margin;
			child.setBounds (bounds [i]);
		}
	}
	return new Point (x + maxWidth + marginRight, maxY);
}
}
