/*******************************************************************************
 * Copyright (c) 2000, 2011 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.widgets;


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

/**
 * Instances of this class provide an area for dynamically
 * positioning the items they contain.
 * <p>
 * The item children that may be added to instances of this class
 * must be of type <code>CoolItem</code>.
 * </p><p>
 * Note that although this class is a subclass of <code>Composite</code>,
 * it does not make sense to add <code>Control</code> children to it,
 * or set a layout on it.
 * </p><p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>FLAT, HORIZONTAL, VERTICAL</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * </p><p>
 * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 * 
 * @see <a href="http://www.eclipse.org/swt/snippets/#coolbar">CoolBar snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class CoolBar extends Composite {
	CoolItem[][] items = new CoolItem[0][0];
	CoolItem[] originalItems = new CoolItem[0];
	Cursor hoverCursor, dragCursor, cursor;
	CoolItem dragging = null;
	int mouseXOffset, itemXOffset;
	boolean isLocked = false;
	boolean inDispose = false;
	static final int ROW_SPACING = 2;
	static final int CLICK_DISTANCE = 3;
	static final int DEFAULT_COOLBAR_WIDTH = 0;
	static final int DEFAULT_COOLBAR_HEIGHT = 0;
	
/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT
 * @see SWT#FLAT
 * @see SWT#HORIZONTAL
 * @see SWT#VERTICAL
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public CoolBar (Composite parent, int style) {
	super (parent, checkStyle(style));
	if ((style & SWT.VERTICAL) != 0) {
		this.style |= SWT.VERTICAL;
		hoverCursor = new Cursor(display, SWT.CURSOR_SIZENS);
	} else {
		this.style |= SWT.HORIZONTAL;
		hoverCursor = new Cursor(display, SWT.CURSOR_SIZEWE);
	}
	dragCursor = new Cursor(display, SWT.CURSOR_SIZEALL);
	Listener listener = new Listener() {
		public void handleEvent(Event event) {
			switch (event.type) {
				case SWT.Dispose:      		onDispose(event);        	break;
				case SWT.MouseDown:    		onMouseDown(event);			break;
				case SWT.MouseExit:    		onMouseExit();      		break;
				case SWT.MouseMove:    		onMouseMove(event); 		break;
				case SWT.MouseUp:      		onMouseUp(event);   		break;
				case SWT.MouseDoubleClick:	onMouseDoubleClick(event); 	break;
				case SWT.Paint:        		onPaint(event);     		break;
				case SWT.Resize:          	onResize();     			break;
			}
		}
	};
	int[] events = new int[] { 
		SWT.Dispose, 
		SWT.MouseDown,
		SWT.MouseExit, 
		SWT.MouseMove, 
		SWT.MouseUp, 
		SWT.MouseDoubleClick,
		SWT.Paint,
		SWT.Resize
	};
	for (int i = 0; i < events.length; i++) {
		addListener(events[i], listener);	
	}
}
static int checkStyle (int style) {
	style |= SWT.NO_FOCUS;
	return (style | SWT.NO_REDRAW_RESIZE) & ~(SWT.V_SCROLL | SWT.H_SCROLL);
}
void _setCursor (Cursor cursor) {
	if (this.cursor != null) return;
	super.setCursor (cursor);
}
protected void checkSubclass () {
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}
public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget();
	int width = 0, height = 0;
	wrapItems((style & SWT.VERTICAL) != 0 ? hHint : wHint);
	boolean flat = (style & SWT.FLAT) != 0;
	for (int row = 0; row < items.length; row++) {
		int rowWidth = 0, rowHeight = 0;
		for (int i = 0; i < items[row].length; i++) {
			CoolItem item = items[row][i];
			rowWidth += item.preferredWidth;
			rowHeight = Math.max(rowHeight, item.preferredHeight);
		}
		height += rowHeight;
		if (!flat && row > 0) height += ROW_SPACING;
		width = Math.max(width, rowWidth);
	}
	wrapItems(getWidth());
	if (width == 0) width = DEFAULT_COOLBAR_WIDTH;
	if (height == 0) height = DEFAULT_COOLBAR_HEIGHT;
	Point size = fixPoint(width, height);
	if (wHint != SWT.DEFAULT) size.x = wHint;
	if (hHint != SWT.DEFAULT) size.y = hHint;
	Rectangle trim = computeTrim(0, 0, size.x, size.y);
	return new Point(trim.width, trim.height);
}
CoolItem getGrabbedItem(int x, int y) {
	for (int row = 0; row < items.length; row++) {
		for (int i = 0; i < items[row].length; i++) {
			CoolItem item = items[row][i];
			Rectangle bounds = item.internalGetBounds();
			bounds.width = CoolItem.MINIMUM_WIDTH;
			if (bounds.x > x) break;
			if (bounds.y > y) return null;
			if (bounds.contains(x, y)) {
				return item;	
			}	
		}	
	}
	return null;
}
/**
 * Returns the item that is currently displayed at the given,
 * zero-relative index. Throws an exception if the index is
 * out of range.
 *
 * @param index the visual index of the item to return
 * @return the item at the given visual index
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public CoolItem getItem (int index) {
	checkWidget();
	if (index < 0) error (SWT.ERROR_INVALID_RANGE);
	for (int row = 0; row < items.length; row++) {
		if (items[row].length > index) {
			return items[row][index];			
		} else {
			index -= items[row].length;
		}
	}
	error (SWT.ERROR_INVALID_RANGE);
	return null;
}
/**
 * Returns the number of items contained in the receiver.
 *
 * @return the number of items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getItemCount () {
	checkWidget();
	return originalItems.length;
}
/**
 * Returns an array of <code>CoolItem</code>s in the order
 * in which they are currently being displayed.
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the receiver's items in their current visual order
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public CoolItem [] getItems () {
	checkWidget();
	CoolItem [] result = new CoolItem [getItemCount()];
	int offset = 0;
	for (int row = 0; row < items.length; row++) {
		System.arraycopy(items[row], 0, result, offset, items[row].length);
		offset += items[row].length;
	}
	return result;
}
Point findItem (CoolItem item) {
	for (int row = 0; row < items.length; row++) {
		for (int i = 0; i < items[row].length; i++) {
			if (items[row][i].equals(item)) return new Point(i, row);		
		}
	}
	return new Point(-1, -1);
}
void fixEvent (Event event) {
	if ((style & SWT.VERTICAL) != 0) {
		int tmp = event.x;
		event.x = event.y;
		event.y = tmp;
	}
}
Rectangle fixRectangle (int x, int y, int width, int height) {
	if ((style & SWT.VERTICAL) != 0) {
		return new Rectangle(y, x, height, width);
	}
	return new Rectangle(x, y, width, height);
}
Point fixPoint (int x, int y) {
	if ((style & SWT.VERTICAL) != 0) {
		return new Point(y, x);
	}
	return new Point(x, y);	
}
/**
 * Searches the receiver's items in the order they are currently
 * being displayed, starting at the first item (index 0), until
 * an item is found that is equal to the argument, and returns
 * the index of that item. If no item is found, returns -1.
 *
 * @param item the search item
 * @return the visual order index of the search item, or -1 if the item is not found
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item is disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int indexOf (CoolItem item) {
	checkWidget();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
	int answer = 0;
	for (int row = 0; row < items.length; row++) {
		for (int i = 0; i < items[row].length; i++) {
			if (items[row][i].equals(item)) {
				return answer;		
			} else {
				answer++;
			}
		}
	}
	return -1;
}
/**
 * Insert the item into the row. Adjust the x and width values
 * appropriately.
 */
boolean insertItemIntoRow(CoolItem item, int rowIndex, int x_root) {
	if (rowIndex < 0 || rowIndex >= items.length) {
		/* Create a new row for the item. */
		boolean bottom = rowIndex >= items.length;
		CoolItem[][] newRows = new CoolItem[items.length + 1][];
		System.arraycopy(items, 0, newRows, bottom ? 0 : 1, items.length);
		int row = bottom ? items.length : 0;
		newRows[row] = new CoolItem[1];
		newRows[row][0] = item;
		items = newRows;
		item.wrap = true;
		return true;
	}
	
	int barWidth = getWidth();
	Rectangle bounds = items[rowIndex][0].internalGetBounds();
	int rowY = bounds.y;
	int oldRowHeight = bounds.height;
	int x = Math.max(0, Math.abs(x_root - toDisplay(new Point(0, 0)).x));
	
	/* Find the insertion index and add the item. */
	int index;
	for (index = 0; index < items[rowIndex].length; index++) {
		if (x < items[rowIndex][index].internalGetBounds().x) break;
	}
	if (index == 0) {
		item.wrap = true;
		items[rowIndex][0].wrap = false;
	}
	int oldLength = items[rowIndex].length;
	CoolItem[] newRow = new CoolItem[oldLength + 1];
	System.arraycopy(items[rowIndex], 0, newRow, 0, index);
	newRow[index] = item;
	System.arraycopy(items[rowIndex], index, newRow, index + 1, oldLength - index);
	items[rowIndex] = newRow;

	/* Adjust the width of the item to the left. */
	if (index > 0) {
		CoolItem left = items[rowIndex][index - 1];
		Rectangle leftBounds = left.internalGetBounds();
		int newWidth = x - leftBounds.x;
		if (newWidth < left.internalGetMinimumWidth()) {
			x += left.internalGetMinimumWidth() - newWidth;
			newWidth = left.internalGetMinimumWidth();
		}
		left.setBounds(leftBounds.x, leftBounds.y, newWidth, leftBounds.height);
		left.requestedWidth = newWidth;
	}
	
	/* Set the item's bounds. */
	int width = 0, height = item.preferredHeight;
	if (index < items[rowIndex].length - 1) {
		CoolItem right = items[rowIndex][index + 1];
		width = right.internalGetBounds().x - x;
		if (width < right.internalGetMinimumWidth()) {
			moveRight(right, right.internalGetMinimumWidth() - width);
			width = right.internalGetBounds().x - x;
		}
		item.setBounds(x, rowY, width, height);
		if (width < item.internalGetMinimumWidth()) moveLeft(item, item.internalGetMinimumWidth() - width);
	} else {
		width = Math.max(item.internalGetMinimumWidth(), barWidth - x);
		item.setBounds(x, rowY, width, height);
		if (x + width > barWidth) moveLeft(item, x + width - barWidth); 
	}
	bounds = item.internalGetBounds();
	item.requestedWidth = bounds.width;
	internalRedraw(bounds.x, bounds.y, item.internalGetMinimumWidth(), bounds.height);
	return height > oldRowHeight;
}
void internalRedraw (int x, int y, int width, int height) {
	if ((style & SWT.VERTICAL) != 0) {
		redraw (y, x, height, width, false);
	} else {
		redraw (x, y, width, height, false);
	}
}
void createItem (CoolItem item, int index) {
	int itemCount = getItemCount(), row = 0;
	if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
	if (items.length == 0) {
		items = new CoolItem[1][1];
		items[0][0] = item;	
	} else {
		int i = index;
		/* find the row to insert into */
		if (index < itemCount) {
			while (i > items[row].length) {
				i -= items[row].length;
				row++;
			}   
		} else {
			row = items.length - 1;
			i = items[row].length;	
		}
		
		// Set the last item in the row to the preferred size 
		// and add the new one just to it's right
		int lastIndex = items[row].length - 1;
		CoolItem lastItem = items[row][lastIndex];
		if (lastItem.ideal) {
			Rectangle bounds = lastItem.internalGetBounds();
			bounds.width = lastItem.preferredWidth;
			bounds.height = lastItem.preferredHeight;
			lastItem.requestedWidth = lastItem.preferredWidth;
			lastItem.setBounds(bounds.x, bounds.y, bounds.width, bounds.height);  
		}
		if (i == 0) {
			item.wrap = true;
			items[row][0].wrap = false;
		}
		int oldLength = items[row].length;
		CoolItem[] newRow = new CoolItem[oldLength + 1];
		System.arraycopy(items[row], 0, newRow, 0, i);
		newRow[i] = item;
		System.arraycopy(items[row], i, newRow, i + 1, oldLength - i);
		items[row] = newRow;
	}
	item.requestedWidth = CoolItem.MINIMUM_WIDTH;
	
	int length = originalItems.length;
	CoolItem [] newOriginals = new CoolItem [length + 1];
	System.arraycopy (originalItems, 0, newOriginals, 0, index);
	System.arraycopy (originalItems, index, newOriginals, index + 1, length - index);
	newOriginals [index] = item;
	originalItems = newOriginals;
	layoutItems();

}
void destroyItem(CoolItem item) {
	if (inDispose) return;
	int row = findItem(item).y;
	if (row == -1) return;
	Rectangle bounds = item.internalGetBounds();
	removeItemFromRow(item, row, true);
	
	int index = 0;
	while (index < originalItems.length) {
		if (originalItems [index] == item) break;
		index++;
	}
	int length = originalItems.length - 1;
	CoolItem [] newOriginals = new CoolItem [length];
	System.arraycopy (originalItems, 0, newOriginals, 0, index);
	System.arraycopy (originalItems, index + 1, newOriginals, index, length - index);
	originalItems = newOriginals;
	
	internalRedraw(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height);
	relayout();
}
void moveDown(CoolItem item, int x_root) {
	int oldRowIndex = findItem(item).y;
	if (items[oldRowIndex].length == 1) {
		/* If this is the only item in the bottom row, don't move it. */
		if (oldRowIndex == items.length - 1) return;
	}
	int newRowIndex = (items[oldRowIndex].length == 1) ? oldRowIndex : oldRowIndex + 1;
	boolean resize = removeItemFromRow(item, oldRowIndex, false);
	Rectangle old = item.internalGetBounds();
	internalRedraw(old.x, old.y, CoolItem.MINIMUM_WIDTH, old.height);
	resize |= insertItemIntoRow(item, newRowIndex, x_root);
	if (resize) {
		relayout();
	} else {
		layoutItems();
	}
}
void moveLeft(CoolItem item, int pixels) {
	Point point = findItem(item);
	int row = point.y;
	int index = point.x;
	if (index == 0) return;	
	Rectangle bounds = item.internalGetBounds();
	int minSpaceOnLeft = 0;
	for (int i = 0; i < index; i++) {
		minSpaceOnLeft += items[row][i].internalGetMinimumWidth();
	}
	int x = Math.max(minSpaceOnLeft, bounds.x - pixels);
	CoolItem left = items[row][index - 1];
	Rectangle leftBounds = left.internalGetBounds();
	if (leftBounds.x + left.internalGetMinimumWidth() > x) {
		int shift = leftBounds.x + left.internalGetMinimumWidth() - x;
		moveLeft(left, shift);
		leftBounds = left.internalGetBounds();
	}
	int leftWidth = Math.max(left.internalGetMinimumWidth(), leftBounds.width - pixels);
	left.setBounds(leftBounds.x, leftBounds.y, leftWidth, leftBounds.height);
	left.requestedWidth = leftWidth;
	int width = bounds.width + (bounds.x - x);
	item.setBounds(x, bounds.y, width, bounds.height);
	item.requestedWidth = width;

	int damagedWidth = bounds.x - x + CoolItem.MINIMUM_WIDTH;
	if (damagedWidth > CoolItem.MINIMUM_WIDTH) {
		internalRedraw(x, bounds.y, damagedWidth, bounds.height);
	}
}
void moveRight(CoolItem item, int pixels) {
	Point point = findItem(item);
	int row = point.y;
	int index = point.x;
	if (index == 0) return;	
	Rectangle bounds = item.internalGetBounds();
	int minSpaceOnRight = 0;
	for (int i = index; i < items[row].length; i++) {
		minSpaceOnRight += items[row][i].internalGetMinimumWidth(); 
	}
	int max = getWidth() - minSpaceOnRight;
	int x = Math.min(max, bounds.x + pixels);	
	int width = 0;
	if (index + 1 == items[row].length) {
		width = getWidth() - x;
	} else {
		CoolItem right = items[row][index + 1];
		Rectangle rightBounds = right.internalGetBounds();
		if (x + item.internalGetMinimumWidth() > rightBounds.x) {
			int shift = x + item.internalGetMinimumWidth() - rightBounds.x;
			moveRight(right, shift);
			rightBounds = right.internalGetBounds();
		}
		width = rightBounds.x - x;
	}
	item.setBounds(x, bounds.y, width, bounds.height);
	item.requestedWidth = width;
	CoolItem left = items[row][index - 1];
	Rectangle leftBounds = left.internalGetBounds();
	int leftWidth = x - leftBounds.x;
	left.setBounds(leftBounds.x, leftBounds.y, leftWidth, leftBounds.height);
	left.requestedWidth = leftWidth;
	
	int damagedWidth = x - bounds.x + CoolItem.MINIMUM_WIDTH + CoolItem.MARGIN_WIDTH;
	if (x - bounds.x > 0) {
		internalRedraw(bounds.x - CoolItem.MARGIN_WIDTH, bounds.y, damagedWidth, bounds.height);
	}
}
void moveUp(CoolItem item, int x_root) {
	Point point = findItem(item);
	int oldRowIndex = point.y;
	if (items[oldRowIndex].length == 1) {
		/* If this is the only item in the top row, don't move it. */
		if (oldRowIndex == 0) return;
	}
	boolean resize = removeItemFromRow(item, oldRowIndex, false);
	Rectangle old = item.internalGetBounds();
	internalRedraw(old.x, old.y, CoolItem.MINIMUM_WIDTH, old.height);
	int newRowIndex = oldRowIndex - 1;
	resize |= insertItemIntoRow(item, newRowIndex, x_root);
	if (resize) {
		relayout();
	} else {
		layoutItems();
	}
}
void onDispose(Event event) {
	/*
	 * Usually when an item is disposed, destroyItem will change the size of the items array
	 * and reset the bounds of all the remaining cool items.
	 * Since the whole cool bar is being disposed, this is not necessary.  For speed
	 * the inDispose flag is used to skip over this part of the item dispose.
	 */
	if (inDispose) return;
	inDispose = true;
	notifyListeners(SWT.Dispose, event);
	event.type = SWT.None;
	for (int i = 0; i < items.length; i++) {
		for (int j = 0; j < items[i].length; j++) {
			items[i][j].dispose();
		}
	}
	hoverCursor.dispose();
	dragCursor.dispose();
	cursor = null;
}
void onMouseDown(Event event) {
	if (isLocked || event.button != 1) return;
	fixEvent(event);
	dragging = getGrabbedItem(event.x, event.y);
	if (dragging != null) {
		mouseXOffset = event.x;
		itemXOffset = mouseXOffset - dragging.internalGetBounds().x;
		_setCursor(dragCursor);
	}
	fixEvent(event);
}
void onMouseExit() {
	if (dragging == null) _setCursor(null);
}
void onMouseMove(Event event) {
	if (isLocked) return;
	fixEvent(event);
	CoolItem grabbed = getGrabbedItem(event.x, event.y);
	if (dragging != null) {
		int left_root = toDisplay(new Point(event.x - itemXOffset, event.y)).x;
		Rectangle bounds = dragging.internalGetBounds();
		if (event.y < bounds.y) {
			moveUp(dragging, left_root);
		} else if (event.y > bounds.y + bounds.height){
			moveDown(dragging, left_root);
		} else if (event.x < mouseXOffset) {
			int distance = Math.min(mouseXOffset, bounds.x + itemXOffset) - event.x;
			if (distance > 0) moveLeft(dragging, distance);
		} else if (event.x > mouseXOffset) {
			int distance = event.x - Math.max(mouseXOffset, bounds.x + itemXOffset);
			if (distance > 0) moveRight(dragging, distance);
		}
		mouseXOffset = event.x;		
	} else {
		if (grabbed != null) {
			_setCursor(hoverCursor);
		} else {
			_setCursor(null);	
		}
	}
	fixEvent(event);
}
void onMouseUp(Event event) {
	dragging = null;
	CoolItem grabbed = getGrabbedItem(event.x, event.y);
	if (grabbed != null) {
		_setCursor(hoverCursor);
	} else {
		_setCursor(null);	
	}
}
void onMouseDoubleClick(Event event) {
	if (isLocked) return;	
	dragging = null;
	fixEvent(event);
	CoolItem target = getGrabbedItem(event.x, event.y);
	if (target == null) {
		_setCursor(null);
	} else {
		Point location = findItem(target);
		int row = location.y;
		int index = location.x;
		if (items[row].length > 1) {
			Rectangle  bounds = target.internalGetBounds();
			int maxSize = getWidth ();
			for (int i = 0; i < items[row].length; i++) {
				if (i != index) {
					maxSize -= items[row][i].internalGetMinimumWidth();	
				}
			}
			if (bounds.width == maxSize) {
				/* The item is at its maximum width. It should be resized to its minimum width. */
				int distance = bounds.width - target.internalGetMinimumWidth();
				if (index + 1 < items[row].length) {
					/* There is an item to the right. Maximize it. */
					CoolItem right = items[row][index + 1];
					moveLeft(right, distance);
				} else {
					/* There is no item to the right. Move the item all the way right. */
					moveRight(target, distance);
				}
			} else if (bounds.width < target.preferredWidth) {
				/* The item is less than its preferredWidth. Resize to preferredWidth. */
				int distance = target.preferredWidth - bounds.width;
				if (index + 1 < items[row].length) {
					CoolItem right = items[row][index + 1];
					moveRight(right, distance);	
					distance = target.preferredWidth - target.internalGetBounds().width;
				}
				if (distance > 0) {
					moveLeft(target, distance);
				}
			} else {
				/* The item is at its minimum width. Maximize it. */
				for (int i = 0; i < items[row].length; i++) {
					if (i != index) {
						CoolItem item = items[row][i];
						item.requestedWidth = Math.max(item.internalGetMinimumWidth(), CoolItem.MINIMUM_WIDTH); 
					}
				}
				target.requestedWidth = maxSize;
				layoutItems();
			}
			_setCursor(hoverCursor);
		}
	}
	fixEvent(event);
}
void onPaint(Event event) {
	GC gc = event.gc;
	if (items.length == 0) return;
	Color shadowColor = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
	Color highlightColor = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
	boolean vertical = (style & SWT.VERTICAL) != 0;
	boolean flat = (style & SWT.FLAT) != 0;
	int stopX = getWidth();
	Rectangle rect;
	Rectangle clipping = gc.getClipping();
	for (int row = 0; row < items.length; row++) {
		Rectangle bounds = new Rectangle(0, 0, 0, 0);
		for (int i = 0; i < items[row].length; i++) {
			bounds = items[row][i].internalGetBounds();
			rect = fixRectangle(bounds.x, bounds.y, bounds.width, bounds.height);
			if (!clipping.intersects(rect)) continue;
			boolean nativeGripper = false;
			
			/* Draw gripper. */
			if (!isLocked) {
				rect = fixRectangle(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height);
				if (!flat) 	nativeGripper = drawGripper(rect.x, rect.y, rect.width, rect.height, vertical);
				if (!nativeGripper) {
					int grabberTrim = 2; 
					int grabberHeight = bounds.height - (2 * grabberTrim) - 1;
					gc.setForeground(shadowColor);
					rect = fixRectangle(
							bounds.x + CoolItem.MARGIN_WIDTH, 
							bounds.y + grabberTrim, 
							2, 
							grabberHeight);
					gc.drawRectangle(rect);
					gc.setForeground(highlightColor);
					rect = fixRectangle(
							bounds.x + CoolItem.MARGIN_WIDTH, 
							bounds.y + grabberTrim + 1, 
							bounds.x + CoolItem.MARGIN_WIDTH, 
							bounds.y + grabberTrim + grabberHeight - 1);
					gc.drawLine(rect.x, rect.y, rect.width, rect.height);
					rect = fixRectangle(
							bounds.x + CoolItem.MARGIN_WIDTH, 
							bounds.y + grabberTrim, 
							bounds.x + CoolItem.MARGIN_WIDTH + 1, 
							bounds.y + grabberTrim);
					gc.drawLine(rect.x, rect.y, rect.width, rect.height);
				}
			}
			
			/* Draw separator. */
			if (!flat && !nativeGripper && i != 0) {
				gc.setForeground(shadowColor);
				rect = fixRectangle(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1);
				gc.drawLine(rect.x, rect.y, rect.width, rect.height);
				gc.setForeground(highlightColor);
				rect = fixRectangle(bounds.x + 1, bounds.y, bounds.x + 1, bounds.y + bounds.height - 1);
				gc.drawLine(rect.x, rect.y, rect.width, rect.height);
			}
		}
		if (!flat && row + 1 < items.length) {
			/* Draw row separator. */
			int separatorY = bounds.y + bounds.height;
			gc.setForeground(shadowColor);
			rect = fixRectangle(0, separatorY, stopX, separatorY);
			gc.drawLine(rect.x, rect.y, rect.width, rect.height);	
			gc.setForeground(highlightColor);
			rect = fixRectangle(0, separatorY + 1, stopX, separatorY + 1);
			gc.drawLine(rect.x, rect.y, rect.width, rect.height);
		}
	}
}
void onResize () {
	layoutItems ();
}
void removeControl (Control control) {
	super.removeControl (control);
	CoolItem [] items = getItems ();
	for (int i=0; i<items.length; i++) {
		CoolItem item = items [i];
		if (item.control == control) item.setControl (null);
	}
}
/**
 * Remove the item from the row. Adjust the x and width values
 * appropriately.
 */
boolean removeItemFromRow(CoolItem item, int rowIndex, boolean disposed) {
	int index = findItem(item).x;
	int newLength = items[rowIndex].length - 1;
	Rectangle itemBounds = item.internalGetBounds();
	int oldRowHeight = itemBounds.height;
	item.wrap = false;
	if (newLength > 0) {
		CoolItem[] newRow = new CoolItem[newLength];
		System.arraycopy(items[rowIndex], 0, newRow, 0, index);
		System.arraycopy(items[rowIndex], index + 1, newRow, index, newRow.length - index);
		items[rowIndex] = newRow;
		items[rowIndex][0].wrap = true;
	} else {
		CoolItem[][] newRows = new CoolItem[items.length - 1][];
		System.arraycopy(items, 0, newRows, 0, rowIndex);
		System.arraycopy(items, rowIndex + 1, newRows, rowIndex, newRows.length - rowIndex);
		items = newRows;
		return true;
	}
	if (!disposed) {
		if (index == 0) {
			CoolItem first = items[rowIndex][0];
			Rectangle bounds = first.internalGetBounds();
			int width = bounds.x + bounds.width;
			first.setBounds(0, bounds.y, width, bounds.height);
			first.requestedWidth = width;
			internalRedraw(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height);
		} else {
			CoolItem previous = items[rowIndex][index - 1];
			Rectangle bounds = previous.internalGetBounds();
			int width = bounds.width + itemBounds.width;
			previous.setBounds(bounds.x, bounds.y, width, bounds.height);
			previous.requestedWidth = width;
		}
	}
	int newRowHeight = 0;
	for (int i = 0; i < newLength; i++) {
		newRowHeight = Math.max(newRowHeight, items[rowIndex][i].preferredHeight);
	}
	return newRowHeight != oldRowHeight;
}
/**
 * Return the height of the bar after it has
 * been properly laid out for the given width.
 */
int layoutItems () {
	int y = 0, width;
	if ((style&SWT.VERTICAL) != 0) {
		width = getClientArea().height; 
	} else {
		width = getClientArea().width;
	}
	wrapItems(width);
	int rowSpacing = (style & SWT.FLAT) != 0 ? 0 : ROW_SPACING; 
	for (int row = 0; row < items.length; row++) {
		int count = items[row].length;
		int x = 0;

		/* determine the height and the available width for the row */
		int rowHeight = 0;
		int available = width;
		for (int i = 0; i < count; i++) {
			CoolItem item = items[row][i];
			rowHeight = Math.max(rowHeight, item.preferredHeight);
			available -= item.internalGetMinimumWidth();	
		}
		if (row > 0) y += rowSpacing;
	
		/* lay the items out */
		for (int i = 0; i < count; i++) {
			CoolItem child = items[row][i];
			int newWidth = available + child.internalGetMinimumWidth();
			if (i + 1 < count) {
				newWidth = Math.min(newWidth, child.requestedWidth);
				available -= (newWidth - child.internalGetMinimumWidth());
			}
			Rectangle oldBounds = child.internalGetBounds();
			Rectangle newBounds = new Rectangle(x, y, newWidth, rowHeight);
			if (!oldBounds.equals(newBounds)) {
				child.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
				Rectangle damage = new Rectangle(0, 0, 0, 0);
				/* Cases are in descending order from most area to redraw to least. */
				if (oldBounds.y != newBounds.y) {
					damage = newBounds;
					damage.add(oldBounds);
					/* Redraw the row separator as well. */
					damage.y -= rowSpacing;
					damage.height += 2 * rowSpacing;
				} else if (oldBounds.height != newBounds.height) {
					/* 
					 * Draw from the bottom of the gripper to the bottom of the new area.
					 * (Bottom of the gripper is -3 from the bottom of the item).
					 */
					damage.y = newBounds.y + Math.min(oldBounds.height, newBounds.height) - 3;
					damage.height = newBounds.y + newBounds.height + rowSpacing;
					damage.x = oldBounds.x - CoolItem.MARGIN_WIDTH;
					damage.width = oldBounds.width + CoolItem.MARGIN_WIDTH;
				} else if (oldBounds.x != newBounds.x) {
					/* Redraw only the difference between the separators. */
					damage.x = Math.min(oldBounds.x, newBounds.x);
					damage.width = Math.abs(oldBounds.x - newBounds.x) + CoolItem.MINIMUM_WIDTH;
					damage.y = oldBounds.y;
					damage.height = oldBounds.height;
				}
				internalRedraw(damage.x, damage.y, damage.width, damage.height);
			}
			x += newWidth;
		}
		y += rowHeight;
	}
	return y;
}
void relayout() {
	Point size = getSize();
	int height = layoutItems();
	if ((style & SWT.VERTICAL) != 0) {
		Rectangle trim = computeTrim (0, 0, height, 0);
		if (height != size.x) super.setSize(trim.width, size.y);
	} else {
		Rectangle trim = computeTrim (0, 0, 0, height);
		if (height != size.y) super.setSize(size.x, trim.height);		
	}
}
/**
 * Returns an array of zero-relative ints that map
 * the creation order of the receiver's items to the
 * order in which they are currently being displayed.
 * <p>
 * Specifically, the indices of the returned array represent
 * the current visual order of the items, and the contents
 * of the array represent the creation order of the items.
 * </p><p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the current visual order of the receiver's items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int[] getItemOrder () {
	checkWidget ();
	int count = getItemCount ();
	int [] indices = new int [count];
	count = 0;
	for (int i = 0; i < items.length; i++) {
		for (int j = 0; j < items[i].length; j++) {
			CoolItem item = items[i][j];
			int index = 0;
			while (index<originalItems.length) {
				if (originalItems [index] == item) break;
				index++;	
			}
			if (index == originalItems.length) error (SWT.ERROR_CANNOT_GET_ITEM);
			indices [count++] = index;
		}
	}
	return indices;
}
void setItemOrder (int[] itemOrder) {
	if (itemOrder == null) error(SWT.ERROR_NULL_ARGUMENT);
	int count = originalItems.length;
	if (itemOrder.length != count) error(SWT.ERROR_INVALID_ARGUMENT);

	/* Ensure that itemOrder does not contain any duplicates. */	
	boolean [] set = new boolean [count];
	for (int i = 0; i < set.length; i++) set [i] = false;
	for (int i = 0; i < itemOrder.length; i++) {
		if (itemOrder [i] < 0 || itemOrder [i] >= count) error (SWT.ERROR_INVALID_ARGUMENT);
		if (set [itemOrder [i]]) error (SWT.ERROR_INVALID_ARGUMENT);
		set [itemOrder [i]] = true;
	}
	
	CoolItem[] row = new CoolItem[count];
	for (int i = 0; i < count; i++) {
		row[i] = originalItems[itemOrder[i]];
	}
	items = new CoolItem[1][count];
	items[0] = row;
}
/**
 * Returns an array of points whose x and y coordinates describe
 * the widths and heights (respectively) of the items in the receiver
 * in the order in which they are currently being displayed.
 *
 * @return the receiver's item sizes in their current visual order
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Point[] getItemSizes () {
	checkWidget();
	CoolItem[] items = getItems();
	Point[] sizes = new Point[items.length];
	for (int i = 0; i < items.length; i++) {
		sizes[i] = items[i].getSize();
	}
	return sizes;
}
void setItemSizes (Point[] sizes) {
	if (sizes == null) error(SWT.ERROR_NULL_ARGUMENT);
	CoolItem[] items = getItems();
	if (sizes.length != items.length) error(SWT.ERROR_INVALID_ARGUMENT);
	for (int i = 0; i < items.length; i++) {
		items[i].setSize(sizes[i]);
	}
}
/**
 * Returns whether or not the receiver is 'locked'. When a coolbar
 * is locked, its items cannot be repositioned.
 *
 * @return true if the coolbar is locked, false otherwise
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.0
 */
public boolean getLocked () {
	checkWidget ();
	return isLocked;
}
int getWidth () {
	if ((style & SWT.VERTICAL) != 0) return getSize().y;
	return getSize().x;	
}
/**
 * Returns an array of ints that describe the zero-relative
 * indices of any item(s) in the receiver that will begin on
 * a new row. The 0th visible item always begins the first row,
 * therefore it does not count as a wrap index.
 *
 * @return an array containing the receiver's wrap indices, or an empty array if all items are in one row
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int[] getWrapIndices () {
	checkWidget();
	if (items.length <= 1) return new int[]{};
	int[] wrapIndices = new int[items.length - 1];
	int i = 0, nextWrap = items[0].length;
	for (int row = 1; row < items.length; row++) {
		if (items[row][0].wrap) wrapIndices[i++] = nextWrap;
		nextWrap += items[row].length;
	}
	if (i != wrapIndices.length) {
		int[] tmp = new int[i];
		System.arraycopy(wrapIndices, 0, tmp, 0, i);
		return tmp;
	}
	return wrapIndices;
}
/**
 * Sets whether or not the receiver is 'locked'. When a coolbar
 * is locked, its items cannot be repositioned.
 *
 * @param locked lock the coolbar if true, otherwise unlock the coolbar
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.0
 */
public void setLocked (boolean locked) {
	checkWidget ();
	if (isLocked != locked) {
		redraw();
	}
	isLocked = locked;
	
}
/**
 * Sets the indices of all item(s) in the receiver that will
 * begin on a new row. The indices are given in the order in
 * which they are currently being displayed. The 0th item
 * always begins the first row, therefore it does not count
 * as a wrap index. If indices is null or empty, the items
 * will be placed on one line.
 *
 * @param indices an array of wrap indices, or null
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setWrapIndices (int[] indices) {
	checkWidget();
	if (indices == null) indices = new int[0];
	int count = originalItems.length;
	for (int i=0; i<indices.length; i++) {
		if (indices[i] < 0 || indices[i] >= count) {
			error (SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	for (int i=0; i<originalItems.length; i++) {
		originalItems[i].wrap = false;
	}
	for (int i=0; i<indices.length; i++) {
		int index = indices[i];
		for (int row = 0; row < items.length; row++) {
			if (items[row].length > index) {
				items[row][index].wrap = true;
				break;
			} else {
				index -= items[row].length;
			}
		}
	}
	relayout();
}

void reskinChildren (int flags) {
	if (items != null) {
		for (int row = 0; row < items.length; row++) {
			for (int i = 0; i < items[row].length; i++) {
				CoolItem item = items[row][i];
				if (item != null) item.reskin (flags);
			}
		}
	}
	super.reskinChildren (flags);
}

public void setCursor (Cursor cursor) {
	checkWidget ();
	super.setCursor (this.cursor = cursor);
}
/**
 * Sets the receiver's item order, wrap indices, and item sizes
 * all at once. This method is typically used to restore the
 * displayed state of the receiver to a previously stored state.
 * <p>
 * The item order is the order in which the items in the receiver
 * should be displayed, given in terms of the zero-relative ordering
 * of when the items were added.
 * </p><p>
 * The wrap indices are the indices of all item(s) in the receiver
 * that will begin on a new row. The indices are given in the order
 * specified by the item order. The 0th item always begins the first
 * row, therefore it does not count as a wrap index. If wrap indices
 * is null or empty, the items will be placed on one line.
 * </p><p>
 * The sizes are specified in an array of points whose x and y
 * coordinates describe the new widths and heights (respectively)
 * of the receiver's items in the order specified by the item order.
 * </p>
 *
 * @param itemOrder an array of indices that describe the new order to display the items in
 * @param wrapIndices an array of wrap indices, or null
 * @param sizes an array containing the new sizes for each of the receiver's items in visual order
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if item order or sizes is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if item order or sizes is not the same length as the number of items</li>
 * </ul>
 */
public void setItemLayout (int[] itemOrder, int[] wrapIndices, Point[] sizes) {
	checkWidget();
	setItemOrder(itemOrder);
	setWrapIndices(wrapIndices);
	setItemSizes(sizes);	
	relayout();
}
public void setOrientation (int orientation) {
	super.setOrientation(orientation);
	for (int row = 0; row < items.length; row++) {
		for (int column = 0; column < items[row].length; column++) {
			CoolItem item = items[row][column];
			if (item.arrowImage != null) {
				item.arrowImage.dispose();
				item.arrowImage = null;
			}
			item.updateChevron();
		}
	}
}
void wrapItems (int maxWidth) {
	int itemCount = originalItems.length;
	if (itemCount < 2) return;
	CoolItem[] itemsVisual = new CoolItem[itemCount];
	int start = 0;
	for (int row = 0; row < items.length; row++) {
		System.arraycopy(items[row], 0, itemsVisual, start, items[row].length);
		start += items[row].length;
	}
	CoolItem[][] newItems = new CoolItem[itemCount][];
	int rowCount = 0, rowWidth =  0;
	start = 0;
	for (int i = 0; i < itemCount; i++) {
		CoolItem item = itemsVisual[i];
		int itemWidth = item.internalGetMinimumWidth();
		if ((i > 0 && item.wrap) || (maxWidth != SWT.DEFAULT && rowWidth + itemWidth > maxWidth)) {
			if (i == start) {
				newItems[rowCount] = new CoolItem[1];
				newItems[rowCount][0] = item;
				start = i + 1;
				rowWidth = 0;
			} else {
				int count = i - start;
				newItems[rowCount] = new CoolItem[count];
				System.arraycopy(itemsVisual, start, newItems[rowCount], 0, count);
				start = i;
				rowWidth = itemWidth;
			}
			rowCount++;			
		} else {
			rowWidth += itemWidth;
		}
	}
	if (start < itemCount) {
		int count = itemCount - start;
		newItems[rowCount] = new CoolItem[count];
		System.arraycopy(itemsVisual, start, newItems[rowCount], 0, count);
		rowCount++;		
	}
	if (newItems.length != rowCount) {
		CoolItem[][] tmp = new CoolItem[rowCount][];
		System.arraycopy(newItems, 0, tmp, 0, rowCount);
		items = tmp;
	} else {
		items = newItems;
	}
}
}
