/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 *******************************************************************************/
package org.eclipse.swt.layout;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * Instances of this class determine the size and position of the 
 * children of a <code>Composite</code> by placing them either in 
 * horizontal rows or vertical columns within the parent <code>Composite</code>. 
 * <p>
 * <code>RowLayout</code> aligns all controls in one row if the
 * <code>type</code> is set to horizontal, and one column if it is
 * set to vertical. It has the ability to wrap, and provides configurable 
 * margins and spacing. <code>RowLayout</code> has a number of configuration 
 * fields. In addition, the height and width of each control in a 
 * <code>RowLayout</code> can be specified by setting a <code>RowData</code>
 * object into the control using <code>setLayoutData ()</code>.
 * </p>
 * <p>
 * The following example code creates a <code>RowLayout</code>, sets all 
 * of its fields to non-default values, and then sets it into a 
 * <code>Shell</code>. 
 * <pre>
 * 		RowLayout rowLayout = new RowLayout();
 * 		rowLayout.wrap = false;
 * 		rowLayout.pack = false;
 * 		rowLayout.justify = true;
 * 		rowLayout.type = SWT.VERTICAL;
 * 		rowLayout.marginLeft = 5;
 * 		rowLayout.marginTop = 5;
 * 		rowLayout.marginRight = 5;
 * 		rowLayout.marginBottom = 5;
 * 		rowLayout.spacing = 0;
 * 		shell.setLayout(rowLayout);
 * </pre>
 * If you are using the default field values, you only need one line of code:
 * <pre>
 * 		shell.setLayout(new RowLayout());
 * </pre>
 * </p>
 * 
 * @see RowData
 * @see <a href="http://www.eclipse.org/swt/snippets/#rowlayout">RowLayout snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: LayoutExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public final class RowLayout extends Layout {
	
	/**
	 * type specifies whether the layout places controls in rows or 
	 * columns.
	 * 
	 * The default value is HORIZONTAL.
	 * 
	 * Possible values are: <ul>
	 *    <li>HORIZONTAL: Position the controls horizontally from left to right</li>
	 *    <li>VERTICAL: Position the controls vertically from top to bottom</li>
	 * </ul>
	 * 
	 * @since 2.0
	 */
	public int type = SWT.HORIZONTAL;
	
	/**
	 * 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 0.
	 * 
	 * @since 3.0
	 */
 	public int marginWidth = 0;
 	
	/**
	 * 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 0.
	 * 
	 * @since 3.0
	 */
 	public int marginHeight = 0;

	/**
	 * 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;
	 		
	/**
	 * 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 take
	 * their preferred size.  If pack is false, all controls will 
	 * have the same size which is the size required to accommodate the 
	 * largest preferred height and the largest preferred width of all 
	 * the controls in the layout.
	 *
	 * The default value is true.
	 */
	public boolean pack = true;
	
	/**
	 * fill specifies whether the controls in a row should be
	 * all the same height for horizontal layouts, or the same
	 * width for vertical layouts.
	 *
	 * The default value is false.
	 * 
	 * @since 3.0
	 */
	public boolean fill = false;

	/**
	 * center specifies whether the controls in a row should be
	 * centered vertically in each cell for horizontal layouts,
	 * or centered horizontally in each cell for vertical layouts.
	 *
	 * The default value is false.
	 * 
	 * @since 3.4
	 */
	public boolean center = false;
	
	/**
	 * 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;

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

/**
 * Constructs a new instance of this class.
 */
public RowLayout () {
}

/**
 * Constructs a new instance of this class given the type.
 *
 * @param type the type of row layout
 * 
 * @since 2.0
 */
public RowLayout (int type) {
	this.type = type;
}

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, hHint, flushCache);
	}
	if (wHint != SWT.DEFAULT) extent.x = wHint;
	if (hHint != SWT.DEFAULT) extent.y = hHint;
	return extent;
}

Point computeSize (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 boolean flushCache (Control control) {
	return true;
}

String getName () {
	String string = getClass ().getName ();
	int index = string.lastIndexOf ('.');
	if (index == -1) return string;
	return string.substring (index + 1, string.length ());
}

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 = 0;
	for (int i=0; i<children.length; i++) {
		Control control = children [i];
		RowData data = (RowData) control.getLayoutData ();
		if (data == null || !data.exclude) {
			children [count++] = children [i];
		} 
	}
	if (count == 0) {
		return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
	}
	int childWidth = 0, childHeight = 0, maxHeight = 0;
	if (!pack) {
		for (int i=0; i<count; i++) {
			Control child = children [i];
			Point size = computeSize (child, flushCache);
			childWidth = Math.max (childWidth, size.x);
			childHeight = Math.max (childHeight, size.y);
		}
		maxHeight = childHeight;
	}
	int clientX = 0, clientY = 0;
	if (move) {
		Rectangle rect = composite.getClientArea ();
		clientX = rect.x;
		clientY = rect.y;
	}
	int [] wraps = null;
	boolean wrapped = false;
	Rectangle [] bounds = null;
	if (move && (justify || fill || center)) {
		bounds = new Rectangle [count];
		wraps = new int [count];
	}
	int maxX = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
	for (int i=0; i<count; i++) {
		Control child = children [i];
		if (pack) {
			Point size = computeSize (child, flushCache);
			childWidth = size.x;
			childHeight = size.y;
		}
		if (wrap && (i != 0) && (x + childWidth > width)) {
			wrapped = true;
			if (move && (justify || fill || center)) wraps [i - 1] = maxHeight;
			x = marginLeft + marginWidth;
			y += spacing + maxHeight;
			if (pack) maxHeight = 0;
		}
		if (pack || fill || center) {
			maxHeight = Math.max (maxHeight, childHeight);
		}
		if (move) {
			int childX = x + clientX, childY = y + clientY;
			if (justify || fill || center) {
				bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
			} else {
				child.setBounds (childX, childY, childWidth, childHeight);
			}
		}
		x += spacing + childWidth;
		maxX = Math.max (maxX, x);
	}
	maxX = Math.max (clientX + marginLeft + marginWidth, maxX - spacing);
	if (!wrapped) maxX += marginRight + marginWidth;
	if (move && (justify || fill || center)) {
		int space = 0, margin = 0;
		if (!wrapped) {
			space = Math.max (0, (width - maxX) / (count + 1));
			margin = Math.max (0, ((width - maxX) % (count + 1)) / 2);
		} else {
			if (fill || justify || center) {
				int last = 0;
				if (count > 0) wraps [count - 1] = maxHeight;
				for (int i=0; i<count; i++) {
					if (wraps [i] != 0) {
						int wrapCount = i - last + 1;
						if (justify) {
							int wrapX = 0;
							for (int j=last; j<=i; j++) {
								wrapX += bounds [j].width + spacing;
							}
							space = Math.max (0, (width - wrapX) / (wrapCount + 1));
							margin = Math.max (0, ((width - wrapX) % (wrapCount + 1)) / 2);
						}
						for (int j=last; j<=i; j++) {
							if (justify) bounds [j].x += (space * (j - last + 1)) + margin;
							if (fill) {
								bounds [j].height = wraps [i];
							} else {
								if (center) {
									bounds [j].y += Math.max (0, (wraps [i] - bounds [j].height) / 2);
								}
							}
						}
						last = i + 1;
					}
				}
			}
		}
		for (int i=0; i<count; i++) {
			if (!wrapped) {
				if (justify) bounds [i].x += (space * (i + 1)) + margin;
				if (fill) {
					bounds [i].height = maxHeight;
				} else {
					if (center) {
						bounds [i].y += Math.max (0, (maxHeight - bounds [i].height) / 2);
					}
				}
			}
			children [i].setBounds (bounds [i]);
		}
	}
	return new Point (maxX, y + maxHeight + marginBottom + marginHeight);
}

Point layoutVertical (Composite composite, boolean move, boolean wrap, int height, boolean flushCache) {
	Control [] children = composite.getChildren ();
	int count = 0;
	for (int i=0; i<children.length; i++) {
		Control control = children [i];
		RowData data = (RowData) control.getLayoutData ();
		if (data == null || !data.exclude) {
			children [count++] = children [i];
		} 
	}
	if (count == 0) {
		return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
	}
	int childWidth = 0, childHeight = 0, maxWidth = 0;
	if (!pack) {
		for (int i=0; i<count; i++) {
			Control child = children [i];
			Point size = computeSize (child, flushCache);
			childWidth = Math.max (childWidth, size.x);
			childHeight = Math.max (childHeight, size.y);
		}
		maxWidth = childWidth;
	}
	int clientX = 0, clientY = 0;
	if (move) {
		Rectangle rect = composite.getClientArea ();
		clientX = rect.x;
		clientY = rect.y;
	}
	int [] wraps = null;
	boolean wrapped = false;
	Rectangle [] bounds = null;
	if (move && (justify || fill || center)) {
		bounds = new Rectangle [count];
		wraps = new int [count];
	}
	int maxY = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
	for (int i=0; i<count; i++) {
		Control child = children [i];
		if (pack) {
			Point size = computeSize (child, flushCache);
			childWidth = size.x;
			childHeight = size.y;
		}
		if (wrap && (i != 0) && (y + childHeight > height)) {
			wrapped = true;
			if (move && (justify || fill || center)) wraps [i - 1] = maxWidth;
			x += spacing + maxWidth;
			y = marginTop + marginHeight;
			if (pack) maxWidth = 0;
		}
		if (pack || fill || center) {
			maxWidth = Math.max (maxWidth, childWidth);
		}
		if (move) {
			int childX = x + clientX, childY = y + clientY;
			if (justify || fill || center) {
				bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
			} else {
				child.setBounds (childX, childY, childWidth, childHeight);
			}
		}
		y += spacing + childHeight;
		maxY = Math.max (maxY, y);
	}
	maxY = Math.max (clientY + marginTop + marginHeight, maxY - spacing);
	if (!wrapped) maxY += marginBottom + marginHeight;
	if (move && (justify || fill || center)) {
		int space = 0, margin = 0;
		if (!wrapped) {
			space = Math.max (0, (height - maxY) / (count + 1));
			margin = Math.max (0, ((height - maxY) % (count + 1)) / 2);
		} else {
			if (fill || justify || center) {
				int last = 0;
				if (count > 0) wraps [count - 1] = maxWidth;
				for (int i=0; i<count; i++) {
					if (wraps [i] != 0) {
						int wrapCount = i - last + 1;
						if (justify) {
							int wrapY = 0;
							for (int j=last; j<=i; j++) {
								wrapY += bounds [j].height + spacing;
							}
							space = Math.max (0, (height - wrapY) / (wrapCount + 1));
							margin = Math.max (0, ((height - wrapY) % (wrapCount + 1)) / 2);
						}
						for (int j=last; j<=i; j++) {
							if (justify) bounds [j].y += (space * (j - last + 1)) + margin;
							if (fill) {
								bounds [j].width = wraps [i];
							} else {
								if (center) {
									bounds [j].x += Math.max (0, (wraps [i] - bounds [j].width) / 2);
								}
							}
						}
						last = i + 1;
					}
				}
			}
		}
		for (int i=0; i<count; i++) {
			if (!wrapped) {
				if (justify) bounds [i].y += (space * (i + 1)) + margin;
				if (fill) {
					bounds [i].width = maxWidth;
				} else {
					if (center) {
						bounds [i].x += Math.max (0, (maxWidth - bounds [i].width) / 2);
					}
				}

			}
			children [i].setBounds (bounds [i]);
		}
	}
	return new Point (x + maxWidth + marginRight + marginWidth, maxY);
}

/**
 * Returns a string containing a concise, human-readable
 * description of the receiver.
 *
 * @return a string representation of the layout
 */
public String toString () {
 	String string = getName ()+" {";
 	string += "type="+((type != SWT.HORIZONTAL) ? "SWT.VERTICAL" : "SWT.HORIZONTAL")+" ";
 	if (marginWidth != 0) string += "marginWidth="+marginWidth+" ";
 	if (marginHeight != 0) string += "marginHeight="+marginHeight+" ";
 	if (marginLeft != 0) string += "marginLeft="+marginLeft+" ";
 	if (marginTop != 0) string += "marginTop="+marginTop+" ";
 	if (marginRight != 0) string += "marginRight="+marginRight+" ";
 	if (marginBottom != 0) string += "marginBottom="+marginBottom+" ";
 	if (spacing != 0) string += "spacing="+spacing+" ";
 	string += "wrap="+wrap+" ";
	string += "pack="+pack+" ";
	string += "fill="+fill+" ";
	string += "justify="+justify+" ";
	string = string.trim();
	string += "}";
 	return string;
}
}
