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

import org.eclipse.swt.*;
import org.eclipse.swt.accessibility.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.DPIUtil.*;
import org.eclipse.swt.widgets.*;

/**
 *
 * Instances of this class implement the notebook user interface
 * metaphor.  It allows the user to select a notebook page from
 * set of pages.
 * <p>
 * The item children that may be added to instances of this class
 * must be of type <code>CTabItem</code>.
 * <code>Control</code> children are created and then set into a
 * tab item using <code>CTabItem#setControl</code>.
 * </p><p>
 * Note that although this class is a subclass of <code>Composite</code>,
 * it does not make sense to set a layout on it.
 * </p><p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>CLOSE, TOP, BOTTOM, FLAT, BORDER, SINGLE, MULTI</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Selection</dd>
 * <dd>"CTabFolder2"</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles TOP and BOTTOM
 * 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/#ctabfolder">CTabFolder, CTabItem snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: CustomControlExample</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 CTabFolder extends Composite {

	/**
	 * marginWidth specifies the number of pixels of horizontal margin
	 * that will be placed along the left and right edges of the form.
	 *
	 * The default value is 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 form.
	 *
	 * The default value is 0.
	 */
 	public int marginHeight = 0;

 	/**
	 * A multiple of the tab height that specifies the minimum width to which a tab
	 * will be compressed before scrolling arrows are used to navigate the tabs.
	 *
	 * NOTE This field is badly named and can not be fixed for backwards compatibility.
	 * It should not be capitalized.
	 *
	 * @deprecated This field is no longer used.  See setMinimumCharacters(int)
	 */
	@Deprecated
	public int MIN_TAB_WIDTH = 4;

	/**
	 * Color of innermost line of drop shadow border.
	 *
	 * NOTE This field is badly named and can not be fixed for backwards compatibility.
	 * It should be capitalized.
	 *
	 * @deprecated drop shadow border is no longer drawn in 3.0
	 */
	@Deprecated
	public static RGB borderInsideRGB  = new RGB (132, 130, 132);
	/**
	 * Color of middle line of drop shadow border.
	 *
	 * NOTE This field is badly named and can not be fixed for backwards compatibility.
	 * It should be capitalized.
	 *
	 * @deprecated drop shadow border is no longer drawn in 3.0
	 */
	@Deprecated
	public static RGB borderMiddleRGB  = new RGB (143, 141, 138);
	/**
	 * Color of outermost line of drop shadow border.
	 *
	 * NOTE This field is badly named and can not be fixed for backwards compatibility.
	 * It should be capitalized.
	 *
	 * @deprecated drop shadow border is no longer drawn in 3.0
	 */
	@Deprecated
	public static RGB borderOutsideRGB = new RGB (171, 168, 165);

	/* sizing, positioning */
	boolean onBottom = false;
	boolean single = false;
	boolean simple = true;
	int fixedTabHeight = SWT.DEFAULT;
	int tabHeight;
	int minChars = 20;
	boolean borderVisible = false;

	/* item management */
	CTabFolderRenderer renderer;
	CTabItem items[] = new CTabItem[0];
	/** index of the left most visible tab. */
	int firstIndex = -1;
	int selectedIndex = -1;

	/**
	 * Indices of the elements in the {@link #items} array, used to manage tab
	 * visibility and candidates to be hidden/shown next.
	 * <p>
	 * If there is not enough place for all tabs, tabs starting from the end of
	 * the {@link #priority} array will be hidden first (independently from the
	 * {@link #mru} flag!) => the right most elements have the highest priority
	 * to be hidden.
	 * <p>
	 * If there is more place to show previously hidden tabs, tabs starting from
	 * the beginning of the {@link #priority} array will be made visible first
	 * (independently from the {@link #mru} flag!) => the left most elements
	 * have the highest priority to be shown.
	 * <p>
	 * The update strategy of the {@link #priority} array however depends on the
	 * {@link #mru} flag.
	 * <p>
	 * If {@link #mru} flag is set, the first index is always the index of the
	 * currently selected tab, next one is the tab selected before current
	 * etc...
	 * <p>
	 * Example: [4,2,5,1,3,0], just representing the last selection order.
	 * <p>
	 * If {@link #mru} flag is not set, the first index is always the index of
	 * the left most visible tab ({@link #firstIndex} field), next indices are
	 * incremented by one up to <code>priority.length-1</code>, and the rest
	 * filled with indices starting with <code>firstIndex-1</code> and
	 * decremented by one until 0 index is reached.
	 * <p>
	 * The tabs between first index and the index of the currently selected tab
	 * are always visible.
	 * <p>
	 * Example: 6 tabs, 2 and 3 are indices of currently shown tabs:
	 * [2,3,4,5,1,0]. The array consists of two blocks: sorted ascending from
	 * first visible (2) to last available (5), and the rest sorted descending
	 * (1,0). 4 and 5 are the hidden tabs on the right side, 0 and 1 are the
	 * hidden tabs on the left side from the visible tabs 2 and 3.
	 *
	 * @see #updateItems(int)
	 * @see #setItemLocation(GC)
	 */
	int[] priority = new int[0];
	boolean mru = false;
	Listener listener;
	boolean ignoreTraverse;
	boolean useDefaultRenderer;

	/* External Listener management */
	CTabFolder2Listener[] folderListeners = new CTabFolder2Listener[0];
	// support for deprecated listener mechanism
	CTabFolderListener[] tabListeners = new CTabFolderListener[0];

	/* Selected item appearance */
	Image selectionBgImage;
	Color[] selectionGradientColors;
	int[] selectionGradientPercents;
	boolean selectionGradientVertical;
	Color selectionForeground;
	Color selectionBackground;

	/* Unselected item appearance */
	Color[] gradientColors;
	int[] gradientPercents;
	boolean gradientVertical;
	boolean showUnselectedImage = true;

	// close, min/max and chevron buttons
	boolean showClose = false;
	boolean showUnselectedClose = true;

	boolean showMin = false;
	boolean minimized = false;
	boolean showMax = false;
	boolean maximized = false;
	ToolBar minMaxTb;
	ToolItem maxItem;
	ToolItem minItem;
	Image maxImage;
	Image minImage;
	boolean hoverTb;
	Rectangle hoverRect = new Rectangle(0,0,0,0);
	boolean hovering;
	boolean hoverTimerRunning;
	boolean highlight;

	boolean showChevron = false;
	Menu showMenu;
	ToolBar chevronTb;
	ToolItem chevronItem;
	int chevronCount;
	boolean chevronVisible = true;

	Image chevronImage;
	Control topRight;
	int topRightAlignment = SWT.RIGHT;
	boolean ignoreResize;
	Control[] controls;
	int[] controlAlignments;
	Rectangle[] controlRects;
	Image[] controlBkImages;

	int updateFlags;
	final static int REDRAW = 1 << 1;
	final static int REDRAW_TABS = 1 << 2;
	final static int UPDATE_TAB_HEIGHT = 1 << 3;
	Runnable updateRun;

	// when disposing CTabFolder, don't try to layout the items or
	// change the selection as each child is destroyed.
	boolean inDispose = false;

	// keep track of size changes in order to redraw only affected area
	// on Resize
	Point oldSize;
	Font oldFont;

	// internal constants
	static final int DEFAULT_WIDTH = 64;
	static final int DEFAULT_HEIGHT = 64;

	static final int SELECTION_FOREGROUND = SWT.COLOR_LIST_FOREGROUND;
	static final int SELECTION_BACKGROUND = SWT.COLOR_LIST_BACKGROUND;

	static final int FOREGROUND = SWT.COLOR_WIDGET_FOREGROUND;
	static final int BACKGROUND = SWT.COLOR_WIDGET_BACKGROUND;

	//TODO: add setter for spacing?
	static final int SPACING = 3;
	static final boolean IS_GTK;
	static {
		String platform = SWT.getPlatform();
		IS_GTK = "gtk".equals(platform);
	}
/**
 * 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 widget which will be the parent of the new instance (cannot be null)
 * @param style the style of widget 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>
 * </ul>
 *
 * @see SWT#TOP
 * @see SWT#BOTTOM
 * @see SWT#FLAT
 * @see SWT#BORDER
 * @see SWT#SINGLE
 * @see SWT#MULTI
 * @see #getStyle()
 */
public CTabFolder(Composite parent, int style) {
	super(parent, checkStyle (parent, style));
	init(style);
}

void init(int style) {
	super.setLayout(new CTabFolderLayout());
	int style2 = super.getStyle();
	oldFont = getFont();
	onBottom = (style2 & SWT.BOTTOM) != 0;
	showClose = (style2 & SWT.CLOSE) != 0;
//	showMin = (style2 & SWT.MIN) != 0; - conflicts with SWT.TOP
//	showMax = (style2 & SWT.MAX) != 0; - conflicts with SWT.BOTTOM
	single = (style2 & SWT.SINGLE) != 0;
	borderVisible = (style & SWT.BORDER) != 0;
	//set up default colors
	Display display = getDisplay();
	selectionForeground = display.getSystemColor(SELECTION_FOREGROUND);
	selectionBackground = display.getSystemColor(SELECTION_BACKGROUND);
	renderer = new CTabFolderRenderer(this);
	useDefaultRenderer = true;
	controls = new Control[0];
	controlAlignments = new int[0];
	controlRects = new Rectangle[0];
	controlBkImages = new Image[0];
	updateTabHeight(false);

	// Add all listeners
	listener = event -> {
		switch (event.type) {
			case SWT.Dispose:          onDispose(event); break;
			case SWT.DragDetect:       onDragDetect(event); break;
			case SWT.FocusIn:          onFocus(event);	break;
			case SWT.FocusOut:         onFocus(event);	break;
			case SWT.KeyDown:          onKeyDown(event); break;
			case SWT.MenuDetect:       onMenuDetect(event); break;
			case SWT.MouseDoubleClick: onMouseDoubleClick(event); break;
			case SWT.MouseDown:        onMouse(event);	break;
			case SWT.MouseEnter:       onMouse(event);	break;
			case SWT.MouseExit:        onMouse(event);	break;
			case SWT.MouseHover:	   onMouse(event); break;
			case SWT.MouseMove:        onMouse(event); break;
			case SWT.MouseUp:          onMouse(event); break;
			case SWT.Paint:            onPaint(event);	break;
			case SWT.Resize:           onResize(event);	break;
			case SWT.Traverse:         onTraverse(event); break;
			case SWT.Selection:        onSelection(event); break;
			case SWT.Activate:         onActivate(event); break;
			case SWT.Deactivate:       onDeactivate(event); break;
		}
	};

	int[] folderEvents = new int[]{
		SWT.Dispose,
		SWT.DragDetect,
		SWT.FocusIn,
		SWT.FocusOut,
		SWT.KeyDown,
		SWT.MenuDetect,
		SWT.MouseDoubleClick,
		SWT.MouseDown,
		SWT.MouseEnter,
		SWT.MouseExit,
		SWT.MouseHover,
		SWT.MouseMove,
		SWT.MouseUp,
		SWT.Paint,
		SWT.Resize,
		SWT.Traverse,
		SWT.Activate,
		SWT.Deactivate
	};
	for (int i = 0; i < folderEvents.length; i++) {
		addListener(folderEvents[i], listener);
	}

	initAccessible();
}
void onDeactivate(Event event) {
	Composite current = this;
	while (current != null) {
		if (current instanceof CTabFolder) {
			((CTabFolder) current).highlight = false;
		}
		current = current.getParent();
	}
	redraw();
}

void onActivate(Event event) {
	Composite current = this;
	while (current != null) {
		if (current instanceof CTabFolder) {
			((CTabFolder) current).highlight = true;
		}
		current = current.getParent();
	}
	redraw();
}

static int checkStyle (Composite parent, int style) {
	int mask = SWT.CLOSE | SWT.TOP | SWT.BOTTOM | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.SINGLE | SWT.MULTI;
	style = style & mask;
	// TOP and BOTTOM are mutually exclusive.
	// TOP is the default
	if ((style & SWT.TOP) != 0) style = style & ~SWT.BOTTOM;
	// SINGLE and MULTI are mutually exclusive.
	// MULTI is the default
	if ((style & SWT.MULTI) != 0) style = style & ~SWT.SINGLE;
	// reduce the flash by not redrawing the entire area on a Resize event
	style |= SWT.NO_REDRAW_RESIZE;

	//TEMPORARY CODE
	/*
	 * In Right To Left orientation on Windows, all GC calls that use a brush are drawing
	 * offset by one pixel.  This results in some parts of the CTabFolder not drawing correctly.
	 * To alleviate some of the appearance problems, allow the OS to draw the background.
	 * This does not draw correctly but the result is less obviously wrong.
	 */
	if ((style & SWT.RIGHT_TO_LEFT) != 0) return style;
	if ((parent.getStyle() & SWT.MIRRORED) != 0 && (style & SWT.LEFT_TO_RIGHT) == 0) return style;

	return style | SWT.DOUBLE_BUFFERED;
}

/**
 *
 * Adds the listener to the collection of listeners who will
 * be notified when a tab item is closed, minimized, maximized,
 * restored, or to show the list of items that are not
 * currently visible.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 *
 * @see CTabFolder2Listener
 * @see #removeCTabFolder2Listener(CTabFolder2Listener)
 *
 * @since 3.0
 */
public void addCTabFolder2Listener(CTabFolder2Listener listener) {
	checkWidget();
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	// add to array
	CTabFolder2Listener[] newListeners = new CTabFolder2Listener[folderListeners.length + 1];
	System.arraycopy(folderListeners, 0, newListeners, 0, folderListeners.length);
	folderListeners = newListeners;
	folderListeners[folderListeners.length - 1] = listener;
}
/**
 * Adds the listener to the collection of listeners who will
 * be notified when a tab item is closed.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 *
 * @see CTabFolderListener
 * @see #removeCTabFolderListener(CTabFolderListener)
 *
 * @deprecated use addCTabFolder2Listener(CTabFolder2Listener)
 */
@Deprecated
public void addCTabFolderListener(CTabFolderListener listener) {
	checkWidget();
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	// add to array
	CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length + 1];
	System.arraycopy(tabListeners, 0, newTabListeners, 0, tabListeners.length);
	tabListeners = newTabListeners;
	tabListeners[tabListeners.length - 1] = listener;
	// display close button to be backwards compatible
	if (!showClose) {
		showClose = true;
		updateFolder(REDRAW);
	}
}
/**
 * Adds the listener to the collection of listeners who will
 * be notified when the user changes the receiver's selection, by sending
 * it one of the messages defined in the <code>SelectionListener</code>
 * interface.
 * <p>
 * <code>widgetSelected</code> is called when the user changes the selected tab.
 * <code>widgetDefaultSelected</code> is not called.
 * </p>
 *
 * @param listener the listener which should be notified when the user changes the receiver's selection
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</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>
 *
 * @see SelectionListener
 * @see #removeSelectionListener
 * @see SelectionEvent
 */
public void addSelectionListener(SelectionListener listener) {
	checkWidget();
	if (listener == null) {
		SWT.error(SWT.ERROR_NULL_ARGUMENT);
	}
	TypedListener typedListener = new TypedListener(listener);
	addListener(SWT.Selection, typedListener);
	addListener(SWT.DefaultSelection, typedListener);
}

Rectangle[] computeControlBounds (Point size, boolean[][] position) {
	if (controls == null || controls.length == 0) return new Rectangle[0];
	Rectangle[] rects = new Rectangle[controls.length];
	for (int i = 0; i < rects.length; i++) {
		rects[i] = new Rectangle(0, 0, 0, 0);
	}
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
	int borderRight = trim.width + trim.x;
	int borderLeft = -trim.x;
	int borderBottom = trim.height + trim.y;
	int borderTop = -trim.y;

	Point[] tabControlSize = new Point[controls.length];
	boolean[] overflow = new boolean [controls.length];
	//Left Control
	int leftWidth = 0;
	int x = borderLeft + SPACING;
	int rightWidth = 0;
	int allWidth = 0;
	for (int i = 0; i < controls.length; i++) {
		Point ctrlSize = tabControlSize[i] = !controls[i].isDisposed() && controls[i].getVisible() ? controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT) : new Point(0,0);
		int alignment = controlAlignments[i];
		if ((alignment & SWT.LEAD) != 0) {
			rects[i].width = ctrlSize.x;
			rects[i].height = getControlHeight(ctrlSize);
			rects[i].x = x;
			rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
			x += ctrlSize.x;
			leftWidth += ctrlSize.x;
		} else {
			if ((alignment & (SWT.FILL | SWT.WRAP)) == 0) {
				rightWidth += ctrlSize.x;
			}
			allWidth += ctrlSize.x;
		}
	}
	if (leftWidth > 0) leftWidth += SPACING * 2;

	int itemWidth = 0;
	for (int i = 0; i < items.length; i++) {
		if (items[i].showing) itemWidth += items[i].width;
	}

	int maxWidth = size.x - borderLeft - leftWidth - borderRight;
	int availableWidth = Math.max(0, maxWidth - itemWidth - rightWidth);
	if (rightWidth > 0) availableWidth -= SPACING * 2;
	x =  size.x  - borderRight - SPACING;
	if (itemWidth + allWidth <= maxWidth) {
		//Everything fits
		for (int i = 0; i < controls.length; i++) {
			int alignment = controlAlignments[i];
			if ((alignment & SWT.TRAIL) != 0) {
				Point ctrlSize = tabControlSize[i];
				x -= ctrlSize.x;
				rects[i].width = ctrlSize.x;
				rects[i].height = getControlHeight(ctrlSize);
				rects[i].x = x;
				rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
				if ((alignment & (SWT.FILL | SWT.WRAP)) != 0) availableWidth -= ctrlSize.x;
			}
			if (tabControlSize[i].y >= tabHeight && fixedTabHeight == SWT.DEFAULT) {
				overflow[i] = true;
			}
		}
	} else {
		for (int i = 0; i < controls.length; i++) {
			int alignment = controlAlignments[i];
			Point ctrlSize = tabControlSize[i];
			if ((alignment & SWT.TRAIL) != 0) {
				if ((alignment & (SWT.FILL | SWT.WRAP)) == 0) {
					x -= ctrlSize.x;
					rects[i].width = ctrlSize.x;
					rects[i].height = getControlHeight(ctrlSize);
					rects[i].x = x;
					rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
				} else if (((alignment & (SWT.WRAP)) != 0 && ctrlSize.x < availableWidth)) {
					x -= ctrlSize.x;
					rects[i].width = ctrlSize.x;
					rects[i].height = getControlHeight(ctrlSize);
					rects[i].x = x;
					rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
					availableWidth -= ctrlSize.x;
				} else if ((alignment & (SWT.FILL)) != 0 && (alignment & (SWT.WRAP)) == 0) {
					rects[i].width = 0;
					rects[i].height = getControlHeight(ctrlSize);
					rects[i].x = x;
					rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
				} else {
					if ((alignment & (SWT.WRAP)) != 0) {
						overflow[i] = true;
					}
				}
			}
		}
	}

	//Any space, distribute amongst FILL
	if (availableWidth > 0) {
		int fillCount = 0;
		for (int i = 0; i < controls.length; i++) {
			int alignment = controlAlignments[i];
			if ((alignment & SWT.TRAIL) != 0 && (alignment & SWT.FILL) != 0 && !overflow[i]) {
				 fillCount++;
			}
		}
		if (fillCount != 0) {
			int extraSpace = availableWidth/fillCount;
			int addedSpace = 0;
			for (int i = 0; i < controls.length; i++) {
				int alignment = controlAlignments[i];
				if ((alignment & SWT.TRAIL) != 0) {
					if ((alignment & SWT.FILL) != 0 && !overflow[i]) {
						rects[i].width += extraSpace;
						addedSpace += extraSpace;
					}
					if (!overflow[i]) {
						rects[i].x -= addedSpace;
					}
				}
			}
		}
	}

	//Go through overflow laying out all wrapped controls
	Rectangle bodyTrim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
	int bodyRight = bodyTrim.width + bodyTrim.x;
	int bodyLeft = -bodyTrim.x;
	int bodyWidth = size.x - bodyLeft - bodyRight;
	x = size.x - bodyRight;
	int y = onBottom ? this.getSize().y - getTabHeight() + 2*bodyTrim.y : -bodyTrim.y;
	availableWidth = bodyWidth;
	int maxHeight = 0;
	for (int i = 0; i < controls.length; i++) {
		Point ctrlSize = tabControlSize[i];
		if (overflow[i]) {
			if (availableWidth > ctrlSize.x) {
				x -= ctrlSize.x;
				rects[i].width = ctrlSize.x;
				rects[i].y = onBottom ? y - ctrlSize.y : y;
				rects[i].height = ctrlSize.y;
				rects[i].x = x;
				availableWidth -= ctrlSize.x;
				maxHeight = Math.max(maxHeight, ctrlSize.y);
			} else {
				x = size.x - bodyRight;
				y += maxHeight;
				maxHeight = 0;
				availableWidth = bodyWidth;
				if (availableWidth > ctrlSize.x) {
					//Relayout this control in the next line
					i--;
				} else {
					ctrlSize = controls[i].isDisposed() ? new Point(0,0) : controls[i].computeSize(bodyWidth, SWT.DEFAULT);
					rects[i].width = bodyWidth;
					rects[i].y = onBottom ? y - ctrlSize.y : y;
					rects[i].height = ctrlSize.y;
					rects[i].x = size.x - ctrlSize.x - bodyRight;
					y += ctrlSize.y;
				}
			}
		}
	}

	if (showChevron) {
		int i = 0, lastIndex = -1;
		while (i < priority.length && items[priority[i]].showing) {
			lastIndex = Math.max(lastIndex, priority[i++]);
		}
		if (lastIndex == -1) lastIndex = selectedIndex;
		if (lastIndex != -1) {
			CTabItem lastItem = items[lastIndex];
			int w = lastItem.x + lastItem.width + SPACING;
			if (!simple && lastIndex == selectedIndex) w -= (renderer.curveIndent - 7);
			rects[controls.length - 1].x = w;
		}
	}

	if (position != null) position[0] = overflow;
	return rects;
}

int getControlHeight(Point ctrlSize) {
	return fixedTabHeight == SWT.DEFAULT ?  Math.max(tabHeight - 1, ctrlSize.y) : ctrlSize.y;
}
/*
* This class was not intended to be subclassed but this restriction
* cannot be enforced without breaking backward compatibility.
*/
//protected void checkSubclass () {
//	String name = getClass ().getName ();
//	int index = name.lastIndexOf ('.');
//	if (!name.substring (0, index + 1).equals ("org.eclipse.swt.custom.")) {
//		SWT.error (SWT.ERROR_INVALID_SUBCLASS);
//	}
//}
@Override
public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget();
	Rectangle trim =  renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, x, y, width, height);
	Point size = new Point(width, height);
	int wrapHeight = getWrappedHeight(size);
	if (onBottom) {
		trim.height += wrapHeight;
	} else {
		trim.y -= wrapHeight;
		trim.height += wrapHeight;
	}
	return trim;
}
Image createButtonImage(Display display, int button) {
	GC tempGC = new GC (this);
	Point size = renderer.computeSize(button, SWT.NONE, tempGC, SWT.DEFAULT, SWT.DEFAULT);
	tempGC.dispose();
	Rectangle trim = renderer.computeTrim(button, SWT.NONE, 0, 0, 0, 0);
	Image image = new Image (display, size.x - trim.width, size.y - trim.height);
	GC gc = new GC (image);
	RGB transparent;
	if (button == CTabFolderRenderer.PART_CHEVRON_BUTTON) {
		transparent = new RGB(0xFF, 0xFF, 0xFF);
	} else {
		transparent = new RGB(0xFD, 0, 0);
	}
	Color transColor = new Color(display, transparent);
	gc.setBackground(transColor);
	gc.fillRectangle(image.getBounds());
	renderer.draw(button, SWT.NONE, new Rectangle(trim.x, trim.y, size.x, size.y), gc);
	gc.dispose ();
	transColor.dispose();
	final ImageData imageData = image.getImageDataAtCurrentZoom();
	imageData.transparentPixel = imageData.palette.getPixel(transparent);
	image.dispose();
	image = new Image(display, new AutoScaleImageDataProvider(display, imageData, DPIUtil.getDeviceZoom()));
	return image;
}
void createItem (CTabItem item, int index) {
	if (0 > index || index > getItemCount ())SWT.error (SWT.ERROR_INVALID_RANGE);
	item.parent = this;
	CTabItem[] newItems = new CTabItem [items.length + 1];
	System.arraycopy(items, 0, newItems, 0, index);
	newItems[index] = item;
	System.arraycopy(items, index, newItems, index + 1, items.length - index);
	items = newItems;
	if (selectedIndex >= index) selectedIndex ++;
	int[] newPriority = new int[priority.length + 1];
	int next = 0,  priorityIndex = priority.length;
	for (int i = 0; i < priority.length; i++) {
		if (!mru && priority[i] == index) {
			priorityIndex = next++;
		}
		newPriority[next++] = priority[i] >= index ? priority[i] + 1 : priority[i];
	}
	newPriority[priorityIndex] = index;
	priority = newPriority;

	if (items.length == 1) {
		updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
	} else {
		updateFolder(REDRAW_TABS);
	}
}
void destroyItem (CTabItem item) {
	if (inDispose) return;
	int index = indexOf(item);
	if (index == -1) return;

	if (items.length == 1) {
		items = new CTabItem[0];
		priority = new int[0];
		firstIndex = -1;
		selectedIndex = -1;

		Control control = item.control;
		if (control != null && !control.isDisposed()) {
			control.setVisible(false);
		}
		setToolTipText(null);
		GC gc = new GC(this);
		setButtonBounds(gc);
		gc.dispose();
		redraw();
		return;
	}

	CTabItem[] newItems = new CTabItem [items.length - 1];
	System.arraycopy(items, 0, newItems, 0, index);
	System.arraycopy(items, index + 1, newItems, index, items.length - index - 1);
	items = newItems;

	int[] newPriority = new int[priority.length - 1];
	int next = 0;
	for (int i = 0; i < priority.length; i++) {
		if (priority [i] == index) continue;
		newPriority[next++] = priority[i] > index ? priority[i] - 1 : priority [i];
	}
	priority = newPriority;

	// move the selection if this item is selected
	if (selectedIndex == index) {
		Control control = item.getControl();
		selectedIndex = -1;
		int nextSelection = mru ? priority[0] : Math.max(0, index - 1);
		setSelection(nextSelection, true);
		if (control != null && !control.isDisposed()) {
			control.setVisible(false);
		}
	} else if (selectedIndex > index) {
		selectedIndex --;
	}

	updateFolder(UPDATE_TAB_HEIGHT | REDRAW_TABS);
}

/**
 * Returns <code>true</code> if the receiver's border is visible.
 *
 * @return the receiver's border visibility state
 *
 * @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 3.0
 */
public boolean getBorderVisible() {
	checkWidget();
	return borderVisible;
}
ToolBar getChevron() {
	if (chevronTb == null) {
		chevronTb = new ToolBar(this, SWT.FLAT);
		initAccessibleChevronTb();
		addTabControl(chevronTb, SWT.TRAIL, -1, false);
	}
	if (chevronItem == null) {
		chevronItem = new ToolItem(chevronTb, SWT.PUSH);
		chevronItem.setToolTipText(SWT.getMessage("SWT_ShowList"));
		chevronItem.addListener(SWT.Selection, listener);
	}
	return chevronTb;
}
/**
 * Returns <code>true</code> if the chevron button
 * is visible when necessary.
 *
 * @return the visibility of the chevron button
 *
 * @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*/ boolean getChevronVisible() {
	checkWidget();
	return chevronVisible;
}
@Override
public Rectangle getClientArea() {
	checkWidget();
	//TODO: HACK - find a better way to get padding
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.FILL, 0, 0, 0, 0);
	Point size = getSize();
	int wrapHeight = getWrappedHeight(size);
	if (onBottom) {
		trim.height += wrapHeight;
	} else {
		trim.y -= wrapHeight;
		trim.height += wrapHeight;
	}
	if (minimized) return new Rectangle(-trim.x, -trim.y, 0, 0);
	int width = size.x - trim.width;
	int height = size.y - trim.height;
	return new Rectangle(-trim.x, -trim.y, width, height);
}

/**
 * Return the tab that is located at the specified index.
 *
 * @param index the index of the tab item
 * @return the item at the specified index
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is out of range</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 */
public CTabItem getItem (int index) {
	//checkWidget();
	if (index  < 0 || index >= items.length)
		SWT.error(SWT.ERROR_INVALID_RANGE);
	return items [index];
}
/**
 * Gets the item at a point in the widget.
 *
 * @param pt the point in coordinates relative to the CTabFolder
 * @return the item at a point or null
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public CTabItem getItem (Point pt) {
	//checkWidget();
	if (items.length == 0) return null;
	runUpdate();
	Point size = getSize();
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
	if (size.x <= trim.width) return null;
	for (int i = 0; i < priority.length; i++) {
		CTabItem item = items[priority[i]];
		Rectangle rect = item.getBounds();
		if (rect.contains(pt)) return item;
	}
	return null;
}
/**
 * Return the number of tabs in the folder.
 *
 * @return the number of tabs in the folder
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public int getItemCount(){
	//checkWidget();
	return items.length;
}
/**
 * Return the tab items.
 *
 * @return the tab items
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public CTabItem [] getItems() {
	//checkWidget();
	CTabItem[] tabItems = new CTabItem [items.length];
	System.arraycopy(items, 0, tabItems, 0, items.length);
	return tabItems;
}
int getLeftItemEdge (GC gc, int part){
	Rectangle trim = renderer.computeTrim(part, SWT.NONE, 0, 0, 0, 0);
	int x = -trim.x;
	int width = 0;
	for (int i = 0; i < controls.length; i++) {
		if ((controlAlignments[i] & SWT.LEAD) != 0 && !controls[i].isDisposed() && controls[i].getVisible()) {
			width += controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
		}
	}
	if (width != 0) width += SPACING * 2;
	x += width;
	return Math.max(0, x);
}
/*
 * Return the lowercase of the first non-'&' character following
 * an '&' character in the given string. If there are no '&'
 * characters in the given string, return '\0'.
 */
char _findMnemonic (String string) {
	if (string == null) return '\0';
	int index = 0;
	int length = string.length ();
	do {
		while (index < length && string.charAt (index) != '&') index++;
		if (++index >= length) return '\0';
		if (string.charAt (index) != '&') return Character.toLowerCase (string.charAt (index));
		index++;
	} while (index < length);
 	return '\0';
}
String stripMnemonic (String string) {
	int index = 0;
	int length = string.length ();
	do {
		while ((index < length) && (string.charAt (index) != '&')) index++;
		if (++index >= length) return string;
		if (string.charAt (index) != '&') {
			return string.substring(0, index-1) + string.substring(index, length);
		}
		index++;
	} while (index < length);
 	return string;
}
/**
 * Returns <code>true</code> if the receiver is minimized.
 *
 * @return the receiver's minimized state
 *
 * @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 3.0
 */
public boolean getMinimized() {
	checkWidget();
	return minimized;
}
/**
 * Returns <code>true</code> if the minimize button
 * is visible.
 *
 * @return the visibility of the minimized button
 *
 * @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 3.0
 */
public boolean getMinimizeVisible() {
	checkWidget();
	return showMin;
}
/**
 * Returns the number of characters that will
 * appear in a fully compressed tab.
 *
 * @return number of characters that will appear in a fully compressed tab
 *
 * @since 3.0
 */
public int getMinimumCharacters() {
	checkWidget();
	return minChars;
}

/**
 * Returns <code>true</code> if the receiver is maximized.
 * <p>
 *
 * @return the receiver's maximized state
 *
 * @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 3.0
 */
public boolean getMaximized() {
	checkWidget();
	return maximized;
}
/**
 * Returns <code>true</code> if the maximize button
 * is visible.
 *
 * @return the visibility of the maximized button
 *
 * @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 3.0
 */
public boolean getMaximizeVisible() {
	checkWidget();
	return showMax;
}
/**
 * Returns <code>true</code> if the receiver displays most
 * recently used tabs and <code>false</code> otherwise.
 * <p>
 * When there is not enough horizontal space to show all the tabs,
 * by default, tabs are shown sequentially from left to right in
 * order of their index.  When the MRU visibility is turned on,
 * the tabs that are visible will be the tabs most recently selected.
 * Tabs will still maintain their left to right order based on index
 * but only the most recently selected tabs are visible.
 * <p>
 * For example, consider a CTabFolder that contains "Tab 1", "Tab 2",
 * "Tab 3" and "Tab 4" (in order by index).  The user selects
 * "Tab 1" and then "Tab 3".  If the CTabFolder is now
 * compressed so that only two tabs are visible, by default,
 * "Tab 2" and "Tab 3" will be shown ("Tab 3" since it is currently
 * selected and "Tab 2" because it is the previous item in index order).
 * If MRU visibility is enabled, the two visible tabs will be "Tab 1"
 * and "Tab 3" (in that order from left to right).</p>
 *
 * @return the receiver's header's visibility state
 *
 * @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 3.1
 */
public boolean getMRUVisible() {
	checkWidget();
	return mru;
}
/**
 * Returns the receiver's renderer.
 *
 * @return the receiver's renderer
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @see #setRenderer(CTabFolderRenderer)
 * @see CTabFolderRenderer
 *
 * @since 3.6
 */
public CTabFolderRenderer getRenderer() {
	checkWidget();
	return renderer;
}
int getRightItemEdge (GC gc){
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
	int x = getSize().x - (trim.width + trim.x);
	int width = 0;
	for (int i = 0; i < controls.length; i++) {
		int align = controlAlignments[i];
		if ((align & SWT.WRAP) == 0 && (align & SWT.LEAD) == 0 && !controls[i].isDisposed() && controls[i].getVisible()) {
			Point rightSize = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT);
			width += rightSize.x;
		}
	}
	if (width != 0) width += SPACING * 2;
	x -= width;
	return Math.max(0, x);
}
/**
 * Return the selected tab item, or null if there is no selection.
 *
 * @return the selected tab item, or null if none has been selected
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public CTabItem getSelection() {
	//checkWidget();
	if (selectedIndex == -1) return null;
	return items[selectedIndex];
}
/**
 * Returns the receiver's selection background color.
 *
 * @return the selection background color of the receiver
 *
 * @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 3.0
 */
public Color getSelectionBackground() {
	checkWidget();
	return selectionBackground;
}
/**
 * Returns the receiver's selection foreground color.
 *
 * @return the selection foreground color of the receiver
 *
 * @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 3.0
 */
public Color getSelectionForeground() {
	checkWidget();
	return selectionForeground;
}
/**
 * Return the index of the selected tab item, or -1 if there
 * is no selection.
 *
 * @return the index of the selected tab item or -1
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public int getSelectionIndex() {
	//checkWidget();
	return selectedIndex;
}
/**
 * Returns <code>true</code> if the CTabFolder is rendered
 * with a simple, traditional shape.
 *
 * @return <code>true</code> if the CTabFolder is rendered with a simple shape
 *
 * @since 3.0
 */
public boolean getSimple() {
	checkWidget();
	return simple;
}
/**
 * Returns <code>true</code> if the CTabFolder only displays the selected tab
 * and <code>false</code> if the CTabFolder displays multiple tabs.
 *
 * @return <code>true</code> if the CTabFolder only displays the selected tab and <code>false</code> if the CTabFolder displays multiple tabs
 *
 * @since 3.0
 */
public boolean getSingle() {
	checkWidget();
	return single;
}

@Override
public int getStyle() {
	int style = super.getStyle();
	style &= ~(SWT.TOP | SWT.BOTTOM);
	style |= onBottom ? SWT.BOTTOM : SWT.TOP;
	style &= ~(SWT.SINGLE | SWT.MULTI);
	style |= single ? SWT.SINGLE : SWT.MULTI;
	if (borderVisible) style |= SWT.BORDER;
	style &= ~SWT.CLOSE;
	if (showClose) style |= SWT.CLOSE;
	return style;
}
/**
 * Returns the height of the tab
 *
 * @return the height of the tab
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public int getTabHeight(){
	checkWidget();
	if (fixedTabHeight != SWT.DEFAULT) return fixedTabHeight;
	return tabHeight - 1; // -1 for line drawn across top of tab //TODO: replace w/ computeTrim of tab area?
}
/**
 * Returns the position of the tab.  Possible values are SWT.TOP or SWT.BOTTOM.
 *
 * @return the position of the tab
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public int getTabPosition(){
	checkWidget();
	return onBottom ? SWT.BOTTOM : SWT.TOP;
}
/**
 * Returns the control in the top right corner of the tab folder.
 * Typically this is a close button or a composite with a menu and close button.
 *
 * @return the control in the top right corner of the tab folder or null
 *
 * @exception  SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @since 2.1
 */
public Control getTopRight() {
	checkWidget();
	return topRight;
}
/**
 * Returns the alignment of the top right control.
 *
 * @return the alignment of the top right control which is either
 * <code>SWT.RIGHT</code> or <code>SWT.FILL</code>
 *
 * @exception  SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @since 3.6
 */
public int getTopRightAlignment() {
	checkWidget();
	return topRightAlignment;
}
/**
 * Returns <code>true</code> if the close button appears
 * when the user hovers over an unselected tabs.
 *
 * @return <code>true</code> if the close button appears on unselected tabs
 *
 * @since 3.0
 */
public boolean getUnselectedCloseVisible() {
	checkWidget();
	return showUnselectedClose;
}
/**
 * Returns <code>true</code> if an image appears
 * in unselected tabs.
 *
 * @return <code>true</code> if an image appears in unselected tabs
 *
 * @since 3.0
 */
public boolean getUnselectedImageVisible() {
	checkWidget();
	return showUnselectedImage;
}
/**
 * Return the index of the specified tab or -1 if the tab is not
 * in the receiver.
 *
 * @param item the tab item for which the index is required
 *
 * @return the index of the specified tab item or -1
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 */
public int indexOf(CTabItem item) {
	checkWidget();
	if (item == null) {
		SWT.error(SWT.ERROR_NULL_ARGUMENT);
	}
	for (int i = 0; i < items.length; i++) {
		if (items[i] == item) return i;
	}
	return -1;
}
void initAccessible() {
	final Accessible accessible = getAccessible();
	accessible.addAccessibleListener(new AccessibleAdapter() {
		@Override
		public void getName(AccessibleEvent e) {
			CTabItem item = null;
			int childID = e.childID;
			if (childID == ACC.CHILDID_SELF) {
				if (selectedIndex != -1) {
					item = items[selectedIndex];
				}
			} else if (childID >= 0 && childID < items.length) {
				item = items[childID];
			}
			e.result = item == null ? null : stripMnemonic(item.getText());
		}

		@Override
		public void getHelp(AccessibleEvent e) {
			String help = null;
			int childID = e.childID;
			if (childID == ACC.CHILDID_SELF) {
				help = getToolTipText();
			} else if (childID >= 0 && childID < items.length) {
				help = items[childID].getToolTipText();
			}
			e.result = help;
		}

		@Override
		public void getKeyboardShortcut(AccessibleEvent e) {
			String shortcut = null;
			int childID = e.childID;
			if (childID >= 0 && childID < items.length) {
				String text = items[childID].getText();
				if (text != null) {
					char mnemonic = _findMnemonic(text);
					if (mnemonic != '\0') {
						shortcut = SWT.getMessage ("SWT_Page_Mnemonic", new Object[] {new Character(mnemonic)}); //$NON-NLS-1$
					}
				}
			}
			if (childID == ACC.CHILDID_SELF) {
				shortcut = SWT.getMessage ("SWT_SwitchPage_Shortcut"); //$NON-NLS-1$
			}
			e.result = shortcut;
		}
	});

	accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
		@Override
		public void getChildAtPoint(AccessibleControlEvent e) {
			Point testPoint = toControl(e.x, e.y);
			int childID = ACC.CHILDID_NONE;
			for (int i = 0; i < items.length; i++) {
				if (items[i].getBounds().contains(testPoint)) {
					childID = i;
					break;
				}
			}
			if (childID == ACC.CHILDID_NONE) {
				Rectangle location = getBounds();
				location.x = location.y = 0;
				location.height = location.height - getClientArea().height;
				if (location.contains(testPoint)) {
					childID = ACC.CHILDID_SELF;
				}
			}
			e.childID = childID;
		}

		@Override
		public void getLocation(AccessibleControlEvent e) {
			Rectangle location = null;
			Point pt = null;
			int childID = e.childID;
			if (childID == ACC.CHILDID_SELF) {
				location = getBounds();
				pt = getParent().toDisplay(location.x, location.y);
			} else {
				if (childID >= 0 && childID < items.length && items[childID].showing) {
					location = items[childID].getBounds();
				}
				if (location != null) {
					pt = toDisplay(location.x, location.y);
				}
			}
			if (location != null && pt != null) {
				e.x = pt.x;
				e.y = pt.y;
				e.width = location.width;
				e.height = location.height;
			}
		}

		@Override
		public void getChildCount(AccessibleControlEvent e) {
			e.detail = items.length;
		}

		@Override
		public void getDefaultAction(AccessibleControlEvent e) {
			String action = null;
			int childID = e.childID;
			if (childID >= 0 && childID < items.length) {
				action = SWT.getMessage ("SWT_Switch"); //$NON-NLS-1$
			}
			e.result = action;
		}

		@Override
		public void getFocus(AccessibleControlEvent e) {
			int childID = ACC.CHILDID_NONE;
			if (isFocusControl()) {
				if (selectedIndex == -1) {
					childID = ACC.CHILDID_SELF;
				} else {
					childID = selectedIndex;
				}
			}
			e.childID = childID;
		}

		@Override
		public void getRole(AccessibleControlEvent e) {
			int role = 0;
			int childID = e.childID;
			if (childID == ACC.CHILDID_SELF) {
				role = ACC.ROLE_TABFOLDER;
			} else if (childID >= 0 && childID < items.length) {
				role = ACC.ROLE_TABITEM;
			}
			e.detail = role;
		}

		@Override
		public void getSelection(AccessibleControlEvent e) {
			e.childID = (selectedIndex == -1) ? ACC.CHILDID_NONE : selectedIndex;
		}

		@Override
		public void getState(AccessibleControlEvent e) {
			int state = 0;
			int childID = e.childID;
			if (childID == ACC.CHILDID_SELF) {
				state = ACC.STATE_NORMAL;
			} else if (childID >= 0 && childID < items.length) {
				state = ACC.STATE_SELECTABLE;
				if (isFocusControl()) {
					state |= ACC.STATE_FOCUSABLE;
				}
				if (selectedIndex == childID) {
					state |= ACC.STATE_SELECTED;
					if (isFocusControl()) {
						state |= ACC.STATE_FOCUSED;
					}
				}
			}
			e.detail = state;
		}

		@Override
		public void getChildren(AccessibleControlEvent e) {
			int childIdCount = items.length;
			Object[] children = new Object[childIdCount];
			for (int i = 0; i < childIdCount; i++) {
				children[i] = Integer.valueOf(i);
			}
			e.children = children;
		}
	});

	addListener(SWT.Selection, event -> {
		if (isFocusControl()) {
			if (selectedIndex == -1) {
				accessible.setFocus(ACC.CHILDID_SELF);
			} else {
				accessible.setFocus(selectedIndex);
			}
		}
	});

	addListener(SWT.FocusIn, event -> {
		if (selectedIndex == -1) {
			accessible.setFocus(ACC.CHILDID_SELF);
		} else {
			accessible.setFocus(selectedIndex);
		}
	});
}
void initAccessibleMinMaxTb() {
	minMaxTb.getAccessible().addAccessibleListener(new AccessibleAdapter() {
		@Override
		public void getName(AccessibleEvent e) {
			if (e.childID != ACC.CHILDID_SELF) {
				if (minItem != null && e.childID == minMaxTb.indexOf(minItem)) {
					e.result = minItem.getToolTipText();
				} else if (maxItem != null && e.childID == minMaxTb.indexOf(maxItem)) {
					e.result = maxItem.getToolTipText();
				}
			}
		}
	});
}
void initAccessibleChevronTb() {
	chevronTb.getAccessible().addAccessibleListener(new AccessibleAdapter() {
		@Override
		public void getName(AccessibleEvent e) {
			if (e.childID != ACC.CHILDID_SELF) {
				if (chevronItem != null && e.childID == chevronTb.indexOf(chevronItem)) {
					e.result = chevronItem.getToolTipText();
				}
			}
		}
	});
}
void onKeyDown (Event event) {
	runUpdate();
	switch (event.keyCode) {
		case SWT.ARROW_LEFT:
		case SWT.ARROW_RIGHT:
			int count = items.length;
			if (count == 0) return;
			if (selectedIndex  == -1) return;
			int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
			int offset =  event.keyCode == leadKey ? -1 : 1;
			int index;
			if (!mru) {
				index = selectedIndex + offset;
			} else {
				int[] visible = new int[items.length];
				int idx = 0;
				int current = -1;
				for (int i = 0; i < items.length; i++) {
					if (items[i].showing) {
						if (i == selectedIndex) current = idx;
						visible [idx++] = i;
					}
				}
				if (current + offset >= 0 && current + offset < idx){
					index = visible [current + offset];
				} else {
					if (showChevron) {
						Rectangle chevronRect = chevronItem.getBounds();
						chevronRect = event.display.map(chevronTb, this, chevronRect);
						CTabFolderEvent e = new CTabFolderEvent(this);
						e.widget = this;
						e.time = event.time;
						e.x = chevronRect.x;
						e.y = chevronRect.y;
						e.width = chevronRect.width;
						e.height = chevronRect.height;
						e.doit = true;
						for (int i = 0; i < folderListeners.length; i++) {
							folderListeners[i].showList(e);
						}
						if (e.doit && !isDisposed()) {
							showList(chevronRect);
						}
					}
					return;
				}
			}
			if (index < 0 || index >= count) return;
			setSelection (index, true);
			forceFocus();
	}
}
void onDispose(Event event) {
	removeListener(SWT.Dispose, listener);
	notifyListeners(SWT.Dispose, event);
	event.type = SWT.None;
	/*
	 * Usually when an item is disposed, destroyItem will change the size of the items array,
	 * reset the bounds of all the tabs and manage the widget associated with the tab.
	 * Since the whole folder is being disposed, this is not necessary.  For speed
	 * the inDispose flag is used to skip over this part of the item dispose.
	 */
	inDispose = true;

	if (showMenu != null && !showMenu.isDisposed()) {
		showMenu.dispose();
		showMenu = null;
	}
	int length = items.length;
	for (int i = 0; i < length; i++) {
		if (items[i] != null) {
			items[i].dispose();
		}
	}

	gradientColors = null;

	selectionGradientColors = null;
	selectionGradientPercents = null;
	selectionBgImage = null;

	selectionBackground = null;
	selectionForeground = null;

	if (controlBkImages != null) {
		for (int i = 0; i < controlBkImages.length; i++) {
			if (controlBkImages[i] != null) {
				controlBkImages[i].dispose();
				controlBkImages[i] = null;
			}
		}
		controlBkImages = null;
	}
	controls = null;
	controlAlignments = null;
	controlRects = null;

	if (maxImage != null) maxImage.dispose();
	maxImage = null;

	if (minImage != null) minImage.dispose();
	minImage = null;

	if (chevronImage != null) chevronImage.dispose();
	chevronImage = null;

	if (renderer != null) renderer.dispose();
	renderer = null;

	minItem = null;
	maxItem = null;
	minMaxTb = null;

	chevronItem = null;
	chevronTb = null;

	if (folderListeners.length != 0) folderListeners = new CTabFolder2Listener[0];
	if (tabListeners.length != 0) tabListeners = new CTabFolderListener[0];
}
void onDragDetect(Event event) {
	boolean consume = false;
	for (int i = 0; i < items.length; i++) {
		if (items[i].closeRect.contains(event.x, event.y)) {
				consume = true;
				break;
		}
	}
	if (consume) {
		event.type = SWT.None;
	}
}
void onFocus(Event event) {
	checkWidget();
	if (selectedIndex >= 0) {
		redraw();
	} else {
		setSelection(0, true);
	}
}
boolean onMnemonic (Event event, boolean doit) {
	char key = event.character;
	for (int i = 0; i < items.length; i++) {
		if (items[i] != null) {
			char mnemonic = _findMnemonic (items[i].getText ());
			if (mnemonic != '\0') {
				if (Character.toLowerCase (key) == mnemonic) {
					if (doit) {
					    setSelection(i, true);
					    forceFocus();
					}
					return true;
				}
			}
		}
	}
	return false;
}
void onMenuDetect(Event event) {
	if (event.detail == SWT.MENU_KEYBOARD) {
		if (selectedIndex != -1) {
			CTabItem item = items[selectedIndex];
			Rectangle rect = getDisplay().map(this, null, item.getBounds());
			if (!rect.contains(event.x, event.y)) {
				/* If the mouse is not in the currently-selected tab,
				 * then pop up the menu near the top-right corner of the current tab.
				 */
				Rectangle itemTrim = renderer.computeTrim(selectedIndex, SWT.NONE, 0, 0, 0, 0);
				Rectangle closeTrim = renderer.computeTrim(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, 0, 0, 0, 0);
				event.x = rect.x + rect.width - item.closeRect.width + itemTrim.x - closeTrim.width;
				event.y = rect.y - itemTrim.y - closeTrim.y;
			}
		}
	}
}
void onMouseDoubleClick(Event event) {
	if (event.button != 1 ||
		(event.stateMask & SWT.BUTTON2) != 0 ||
		(event.stateMask & SWT.BUTTON3) != 0) return;
	Event e = new Event();
	e.item = getItem(new Point(event.x, event.y));
	if (e.item != null) {
		notifyListeners(SWT.DefaultSelection, e);
	}
}
void onMouse(Event event) {
	if( isDisposed() ) {
		return;
	}
	int x = event.x, y = event.y;
	switch (event.type) {
		case SWT.MouseEnter: {
			setToolTipText(null);
			break;
		}
		case SWT.MouseExit: {
			for (int i=0; i<items.length; i++) {
				CTabItem item = items[i];
				if (i != selectedIndex && item.closeImageState != SWT.BACKGROUND) {
					item.closeImageState = SWT.BACKGROUND;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
				}
				if ((item.state & SWT.HOT) != 0) {
					item.state &= ~SWT.HOT;
					redraw(item.x, item.y, item.width, item.height, false);
				}
				if (i == selectedIndex && item.closeImageState != SWT.NONE) {
					item.closeImageState = SWT.NONE;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
				}
			}
			break;
		}
		case SWT.MouseHover:
		case SWT.MouseDown: {
			if (hoverTb && hoverRect.contains(x, y) && !hovering) {
				hovering = true;
				updateItems();
				hoverTimerRunning = true;
				event.display.timerExec(2000, new Runnable() {
					@Override
					public void run() {
						if (isDisposed()) return;
						if (hovering) {
							Display display = getDisplay();
							Control c = display.getCursorControl();
							boolean reschedule = false;
							if (c != null) {
								for (int i = 0; i < controls.length; i++) {
									Control temp = c;
									do {
										if (temp.equals(controls[i])) {
											reschedule = true;
										} else {
											temp = temp.getParent();
											if (temp == null || temp.equals(CTabFolder.this)) break;
										}
									} while (!reschedule);
									if (reschedule) break;
								}
							}
							if (reschedule && hoverTimerRunning) {
								display.timerExec(2000, this);
							} else {
								hovering = false;
								updateItems();
							}
						}
					}
				});
				return;
			}
			if (event.button != 1) return;
			CTabItem item = null;
			if (single) {
				if (selectedIndex != -1) {
					Rectangle bounds = items[selectedIndex].getBounds();
					if (bounds.contains(x, y)){
						item = items[selectedIndex];
					}
				}
			} else {
				for (int i=0; i<items.length; i++) {
					Rectangle bounds = items[i].getBounds();
					if (bounds.contains(x, y)){
						item = items[i];
					}
				}
			}
			if (item != null) {
				if (item.closeRect.contains(x,y)){
					item.closeImageState = SWT.SELECTED;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
					update();
					return;
				}
				int index = indexOf(item);
				if (item.showing){
				    	int oldSelectedIndex = selectedIndex;
				    	setSelection(index, true);
				    	if (oldSelectedIndex == selectedIndex) {
				    	    /* If the click is on the selected tabitem, then set focus to the tabfolder */
				    	    forceFocus();
				    	}
				}
				return;
			}
			break;
		}
		case SWT.MouseMove: {
			_setToolTipText(event.x, event.y);
			boolean close = false;
			for (int i=0; i<items.length; i++) {
				CTabItem item = items[i];
				close = false;
				if (item.getBounds().contains(x, y)) {
					close = true;
					if (item.closeRect.contains(x, y)) {
						if (item.closeImageState != SWT.SELECTED && item.closeImageState != SWT.HOT) {
							item.closeImageState = SWT.HOT;
							redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
						}
					} else {
						if (item.closeImageState != SWT.NONE) {
							item.closeImageState = SWT.NONE;
							redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
						}
					}
					if ((item.state & SWT.HOT) == 0) {
						item.state |= SWT.HOT;
						redraw(item.x, item.y, item.width, item.height, false);
					}
				}
				if (i != selectedIndex && item.closeImageState != SWT.BACKGROUND && !close) {
					item.closeImageState = SWT.BACKGROUND;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
				}
				if ((item.state & SWT.HOT) != 0 && !close) {
					item.state &= ~SWT.HOT;
					redraw(item.x, item.y, item.width, item.height, false);
				}
				if (i == selectedIndex && item.closeImageState != SWT.NONE && !close) {
					item.closeImageState = SWT.NONE;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
				}
			}
			break;
		}
		case SWT.MouseUp: {
			if (event.button != 1) return;
			CTabItem item = null;
			if (single) {
				if (selectedIndex != -1) {
					Rectangle bounds = items[selectedIndex].getBounds();
					if (bounds.contains(x, y)){
						item = items[selectedIndex];
					}
				}
			} else {
				for (int i=0; i<items.length; i++) {
					Rectangle bounds = items[i].getBounds();
					if (bounds.contains(x, y)){
						item = items[i];
					}
				}
			}
			if (item != null) {
				if (item.closeRect.contains(x,y)) {
					boolean selected = item.closeImageState == SWT.SELECTED;
					item.closeImageState = SWT.HOT;
					redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false);
					if (!selected) return;
					CTabFolderEvent e = new CTabFolderEvent(this);
					e.widget = this;
					e.time = event.time;
					e.item = item;
					e.doit = true;
					for (int j = 0; j < folderListeners.length; j++) {
						CTabFolder2Listener listener = folderListeners[j];
						listener.close(e);
					}
					for (int j = 0; j < tabListeners.length; j++) {
						CTabFolderListener listener = tabListeners[j];
						listener.itemClosed(e);
					}
					if (e.doit) item.dispose();
					if (!isDisposed() && item.isDisposed()) {
						Display display = getDisplay();
						Point pt = display.getCursorLocation();
						pt = display.map(null, this, pt.x, pt.y);
						CTabItem nextItem = getItem(pt);
						if (nextItem != null) {
							if (nextItem.closeRect.contains(pt)) {
								if (nextItem.closeImageState != SWT.SELECTED && nextItem.closeImageState != SWT.HOT) {
									nextItem.closeImageState = SWT.HOT;
									redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false);
								}
							} else {
								if (nextItem.closeImageState != SWT.NONE) {
									nextItem.closeImageState = SWT.NONE;
									redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false);
								}
							}
						}
					}
					return;
				}
			}
		}
	}
}
void onPageTraversal(Event event) {
	int count = items.length;
	if (count == 0) return;
	int index = selectedIndex;
	if (index  == -1) {
		index = 0;
	} else {
		int offset = (event.detail == SWT.TRAVERSE_PAGE_NEXT) ? 1 : -1;
		if (!mru) {
			index = (selectedIndex + offset + count) % count;
		} else {
			int[] visible = new int[items.length];
			int idx = 0;
			int current = -1;
			for (int i = 0; i < items.length; i++) {
				if (items[i].showing) {
					if (i == selectedIndex) current = idx;
					visible [idx++] = i;
				}
			}
			if (current + offset >= 0 && current + offset < idx){
				index = visible [current + offset];
			} else {
				if (showChevron) {
					Rectangle chevronRect = chevronItem.getBounds();
					chevronRect = event.display.map(chevronTb, this, chevronRect);
					CTabFolderEvent e = new CTabFolderEvent(this);
					e.widget = this;
					e.time = event.time;
					e.x = chevronRect.x;
					e.y = chevronRect.y;
					e.width = chevronRect.width;
					e.height = chevronRect.height;
					e.doit = true;
					for (int i = 0; i < folderListeners.length; i++) {
						folderListeners[i].showList(e);
					}
					if (e.doit && !isDisposed()) {
						showList(chevronRect);
					}
				}
			}
		}
	}
	setSelection (index, true);
}
void onPaint(Event event) {
	if (inDispose) return;
	Font font = getFont();
	if (oldFont == null || !oldFont.equals(font)) {
		// handle case where  default font changes
		oldFont = font;
		if (!updateTabHeight(false)) {
			updateItems();
			redraw();
			return;
		}
	}

	GC gc = event.gc;
	Font gcFont = gc.getFont();
	Color gcBackground = gc.getBackground();
	Color gcForeground = gc.getForeground();

// Useful for debugging paint problems
//{
//Point size = getSize();
//gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GREEN));
//gc.fillRectangle(-10, -10, size.x + 20, size.y+20);
//}

	Point size = getSize();
	Rectangle bodyRect = new Rectangle(0, 0, size.x, size.y);
	renderer.draw(CTabFolderRenderer.PART_BODY, SWT.BACKGROUND | SWT.FOREGROUND, bodyRect, gc);

	gc.setFont(gcFont);
	gc.setForeground(gcForeground);
	gc.setBackground(gcBackground);

	renderer.draw(CTabFolderRenderer.PART_HEADER, SWT.BACKGROUND | SWT.FOREGROUND, bodyRect, gc);

	gc.setFont(gcFont);
	gc.setForeground(gcForeground);
	gc.setBackground(gcBackground);

	if (!single) {
		for (int i=0; i < items.length; i++) {
			Rectangle itemBounds = items[i].getBounds();
			if (i != selectedIndex && event.getBounds().intersects(itemBounds)) {
				renderer.draw(i, SWT.BACKGROUND | SWT.FOREGROUND | items[i].state , itemBounds, gc);
			}
		}
	}

	gc.setFont(gcFont);
	gc.setForeground(gcForeground);
	gc.setBackground(gcBackground);

	if (selectedIndex != -1) {
		renderer.draw(selectedIndex, items[selectedIndex].state | SWT.BACKGROUND | SWT.FOREGROUND, items[selectedIndex].getBounds(), gc);
	}

	gc.setFont(gcFont);
	gc.setForeground(gcForeground);
	gc.setBackground(gcBackground);

	if (hoverTb) {
		Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
		int x = getSize().x - (trim.width + trim.x);
		hoverRect = new Rectangle(x - 16 - SPACING, 2, 16, getTabHeight() - 2);
		gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
		x = hoverRect.x;
		int y = hoverRect.y;
		gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
		gc.fillRectangle(x + hoverRect.width - 6, y, 5, 5);
		gc.drawRectangle(x + hoverRect.width - 6, y, 5, 5);
		gc.drawLine(x + hoverRect.width - 6, y+2, x + hoverRect.width - 6 + 5, y + 2);
		gc.fillRectangle(x, y, 5 , 2);
		gc.drawRectangle(x, y, 5 , 2);
	}
	gc.setFont(gcFont);
	gc.setForeground(gcForeground);
	gc.setBackground(gcBackground);
}

void onResize(Event event) {
	if (inDispose) return;
	if (ignoreResize) return;
	if (updateItems()) {
		redrawTabs();
	}
	Point size = getSize();
	if (oldSize == null) {
		redraw();
	} else {
		if (onBottom && size.y != oldSize.y) {
			redraw();
		} else {
			int x1 = Math.min(size.x, oldSize.x);
			Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
			if (size.x != oldSize.x) x1 -= trim.width + trim.x - marginWidth + 2;
			if (!simple) x1 -= 5; // rounded top right corner
			int y1 = Math.min(size.y, oldSize.y);
			if (size.y != oldSize.y) y1 -= trim.height + trim.y - marginHeight;
			int x2 = Math.max(size.x, oldSize.x);
			int y2 = Math.max(size.y, oldSize.y);
			redraw(0, y1, x2, y2 - y1, false);
			redraw(x1, 0, x2 - x1, y2, false);
			if (hoverTb) {
				redraw(hoverRect.x, hoverRect.y, hoverRect.width, hoverRect.height, false);
			}
		}
	}
	oldSize = size;
}
void onSelection(Event event) {
	if (hovering) {
		hovering = false;
		updateItems();
	}
	if (event.widget == maxItem) {
		CTabFolderEvent e = new CTabFolderEvent(this);
		e.widget = CTabFolder.this;
		e.time = event.time;
		for (int i = 0; i < folderListeners.length; i++) {
			if (maximized) {
				folderListeners[i].restore(e);
			} else {
				folderListeners[i].maximize(e);
			}
		}
	} else if (event.widget == minItem) {
		CTabFolderEvent e = new CTabFolderEvent(this);
		e.widget = CTabFolder.this;
		e.time = event.time;
		for (int i = 0; i < folderListeners.length; i++) {
			if (minimized) {
				folderListeners[i].restore(e);
			} else {
				folderListeners[i].minimize(e);
			}
		}
	} else if (event.widget == chevronItem) {
		Rectangle chevronRect = chevronItem.getBounds();
		chevronRect = event.display.map(chevronTb, this, chevronRect);
		CTabFolderEvent e = new CTabFolderEvent(this);
		e.widget = this;
		e.time = event.time;
		e.x = chevronRect.x;
		e.y = chevronRect.y;
		e.width = chevronRect.width;
		e.height = chevronRect.height;
		e.doit = true;
		for (int i = 0; i < folderListeners.length; i++) {
			folderListeners[i].showList(e);
		}
		if (e.doit && !isDisposed()) {
			showList(chevronRect);
		}
	}
}
void onTraverse (Event event) {
	if (ignoreTraverse) return;
	runUpdate();
	switch (event.detail) {
		case SWT.TRAVERSE_ESCAPE:
		case SWT.TRAVERSE_RETURN:
		case SWT.TRAVERSE_TAB_NEXT:
		case SWT.TRAVERSE_TAB_PREVIOUS:
			Control focusControl = getDisplay().getFocusControl();
			if (focusControl == this) event.doit = true;
			break;
		case SWT.TRAVERSE_MNEMONIC:
			event.doit = onMnemonic(event, false);
			break;
		case SWT.TRAVERSE_PAGE_NEXT:
		case SWT.TRAVERSE_PAGE_PREVIOUS:
			event.doit = items.length > 0;
			break;
	}
	ignoreTraverse = true;
	notifyListeners(SWT.Traverse, event);
	ignoreTraverse = false;
	event.type = SWT.None;
	if (isDisposed()) return;
	if (!event.doit) return;
	switch (event.detail) {
		case SWT.TRAVERSE_MNEMONIC:
			onMnemonic(event, true);
			event.detail = SWT.TRAVERSE_NONE;
			break;
		case SWT.TRAVERSE_PAGE_NEXT:
		case SWT.TRAVERSE_PAGE_PREVIOUS:
			onPageTraversal(event);
			event.detail = SWT.TRAVERSE_NONE;
			break;
	}
}
void redrawTabs() {
	Point size = getSize();
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
	if (onBottom) {
		int h = trim.height + trim.y - marginHeight;
		redraw(0, size.y - h - 1, size.x, h + 1, false);
	} else {
		redraw(0, 0, size.x, -trim.y - marginHeight + 1, false);
	}
}
/**
 * Removes the listener.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 *
 * @see #addCTabFolder2Listener(CTabFolder2Listener)
 *
 * @since 3.0
 */
public void removeCTabFolder2Listener(CTabFolder2Listener listener) {
	checkWidget();
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (folderListeners.length == 0) return;
	int index = -1;
	for (int i = 0; i < folderListeners.length; i++) {
		if (listener == folderListeners[i]){
			index = i;
			break;
		}
	}
	if (index == -1) return;
	if (folderListeners.length == 1) {
		folderListeners = new CTabFolder2Listener[0];
		return;
	}
	CTabFolder2Listener[] newTabListeners = new CTabFolder2Listener[folderListeners.length - 1];
	System.arraycopy(folderListeners, 0, newTabListeners, 0, index);
	System.arraycopy(folderListeners, index + 1, newTabListeners, index, folderListeners.length - index - 1);
	folderListeners = newTabListeners;
}
/**
 * Removes the listener.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 *
 * @deprecated see removeCTabFolderCloseListener(CTabFolderListener)
 */
@Deprecated
public void removeCTabFolderListener(CTabFolderListener listener) {
	checkWidget();
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (tabListeners.length == 0) return;
	int index = -1;
	for (int i = 0; i < tabListeners.length; i++) {
		if (listener == tabListeners[i]){
			index = i;
			break;
		}
	}
	if (index == -1) return;
	if (tabListeners.length == 1) {
		tabListeners = new CTabFolderListener[0];
		return;
	}
	CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length - 1];
	System.arraycopy(tabListeners, 0, newTabListeners, 0, index);
	System.arraycopy(tabListeners, index + 1, newTabListeners, index, tabListeners.length - index - 1);
	tabListeners = newTabListeners;
}
/**
 * Removes the listener from the collection of listeners who will
 * be notified when the user changes the receiver's selection.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</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>
 *
 * @see SelectionListener
 * @see #addSelectionListener
 */
public void removeSelectionListener(SelectionListener listener) {
	checkWidget();
	if (listener == null) {
		SWT.error(SWT.ERROR_NULL_ARGUMENT);
	}
	removeListener(SWT.Selection, listener);
	removeListener(SWT.DefaultSelection, listener);
}

@Override
public void reskin(int flags) {
	super.reskin(flags);
	for (int i = 0; i < items.length; i++) {
		items[i].reskin(flags);
	}
}

@Override
public void setBackground (Color color) {
	super.setBackground(color);
	renderer.createAntialiasColors(); //TODO: need better caching strategy
	updateBkImages();
	redraw();
}
/**
 * Specify a gradient of colors to be drawn in the background of the unselected tabs.
 * For example to draw a gradient that varies from dark blue to blue and then to
 * white, use the following call to setBackground:
 * <pre>
 *	cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		               new int[] {25, 50, 100});
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradient
 *               in order of appearance left to right.  The value <code>null</code> clears the
 *               background gradient. The value <code>null</code> can be used inside the array of
 *               Color to specify the background color.
 * @param percents an array of integers between 0 and 100 specifying the percent of the width
 *                 of the widget at which the color should change.  The size of the <code>percents</code>
 *                 array must be one less than the size of the <code>colors</code> array.
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @since 3.6
 */
public void setBackground(Color[] colors, int[] percents) {
	setBackground(colors, percents, false);
}
/**
 * Specify a gradient of colors to be drawn in the background of the unselected tab.
 * For example to draw a vertical gradient that varies from dark blue to blue and then to
 * white, use the following call to setBackground:
 * <pre>
 *	cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		                  new int[] {25, 50, 100}, true);
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradient
 *               in order of appearance left to right.  The value <code>null</code> clears the
 *               background gradient. The value <code>null</code> can be used inside the array of
 *               Color to specify the background color.
 * @param percents an array of integers between 0 and 100 specifying the percent of the width
 *                 of the widget at which the color should change.  The size of the <code>percents</code>
 *                 array must be one less than the size of the <code>colors</code> array.
 *
 * @param vertical indicate the direction of the gradient. <code>True</code> is vertical and <code>false</code> is horizontal.
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @since 3.6
 */
public void setBackground(Color[] colors, int[] percents, boolean vertical) {
	checkWidget();
	if (colors != null) {
		if (percents == null || percents.length != colors.length - 1) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		for (int i = 0; i < percents.length; i++) {
			if (percents[i] < 0 || percents[i] > 100) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
			if (i > 0 && percents[i] < percents[i-1]) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
		}
		if (getDisplay().getDepth() < 15) {
			// Don't use gradients on low color displays
			colors = new Color[] {colors[colors.length - 1]};
			percents = new int[] {};
		}
	}

	// Are these settings the same as before?
	if ((gradientColors != null) && (colors != null) &&
		(gradientColors.length == colors.length)) {
		boolean same = false;
		for (int i = 0; i < gradientColors.length; i++) {
		    if (gradientColors[i] == null) {
			same = colors[i] == null;
		    } else {
			same = gradientColors[i].equals(colors[i]);
		    }
		    if (!same) break;
		}
		if (same) {
		    for (int i = 0; i < gradientPercents.length; i++) {
			same = gradientPercents[i] == percents[i];
			if (!same) break;
		    }
		}
		if (same && this.gradientVertical == vertical) return;
	}
	// Store the new settings
	if (colors == null) {
		gradientColors = null;
		gradientPercents = null;
		gradientVertical = false;
		setBackground((Color)null);
	} else {
		gradientColors = new Color[colors.length];
		for (int i = 0; i < colors.length; ++i) {
			gradientColors[i] = colors[i];
		}
		gradientPercents = new int[percents.length];
		for (int i = 0; i < percents.length; ++i) {
			gradientPercents[i] = percents[i];
		}
		gradientVertical = vertical;
		setBackground(gradientColors[gradientColors.length-1]);
	}

	// Refresh with the new settings
	redraw();
}
@Override
public void setBackgroundImage(Image image) {
    	super.setBackgroundImage(image);
    	renderer.createAntialiasColors(); //TODO: need better caching strategy
    	redraw();
}
/**
 * Toggle the visibility of the border
 *
 * @param show true if the border should be displayed
 *
 * @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 setBorderVisible(boolean show) {
	checkWidget();
	if (borderVisible == show) return;
	this.borderVisible = show;
	updateFolder(REDRAW);
}
void setButtonBounds(GC gc) {
	Point size = getSize();
	// max button
	Display display = getDisplay();
	if (showMax) {
		if (minMaxTb == null) {
			minMaxTb = new ToolBar(this, SWT.FLAT);
			initAccessibleMinMaxTb();
			addTabControl(minMaxTb, SWT.TRAIL, 0, false);
		}
		if (maxItem == null) {
			maxItem = new ToolItem(minMaxTb, SWT.PUSH);
			if (maxImage == null) {
				maxImage = createButtonImage(display, CTabFolderRenderer.PART_MAX_BUTTON);
			}
			maxItem.setImage(maxImage);
			maxItem.setToolTipText(maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize")); //$NON-NLS-1$ //$NON-NLS-2$
			maxItem.addListener(SWT.Selection, listener);
		}
	} else {
		//might need to remove it if already there
		if (maxItem != null) {
			maxItem.dispose();
			maxItem = null;
		}
	}
	// min button
	if (showMin) {
		if (minMaxTb == null) {
			minMaxTb = new ToolBar(this, SWT.FLAT);
			initAccessibleMinMaxTb();
			addTabControl(minMaxTb, SWT.TRAIL, 0, false);
		}
		if (minItem == null) {
			minItem = new ToolItem(minMaxTb, SWT.PUSH, 0);
			if (minImage == null) {
				minImage = createButtonImage(display, CTabFolderRenderer.PART_MIN_BUTTON);
			}
			minItem.setImage(minImage);
			minItem.setToolTipText(minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize")); //$NON-NLS-1$ //$NON-NLS-2$
			minItem.addListener(SWT.Selection, listener);
		}
	} else {
		//might need to remove it if already there
		if (minItem != null) {
			minItem.dispose();
			minItem = null;
		}
	}
	if (minMaxTb != null && minMaxTb.getItemCount() == 0) {
		removeTabControl(minMaxTb, false);
		minMaxTb.dispose();
		minMaxTb = null;
	}
	if (showChevron) {
		int itemCount = items.length;
		int count;
		if (single) {
			count = selectedIndex == -1 ? itemCount : itemCount - 1;
		} else {
			int showCount = 0;
			while (showCount < priority.length && items[priority[showCount]].showing) {
				showCount++;
			}
			count = itemCount - showCount;
		}
		if (count != chevronCount) {
			chevronCount = count;
			if (chevronImage != null) chevronImage.dispose();
			chevronImage = createButtonImage(display, CTabFolderRenderer.PART_CHEVRON_BUTTON);
			chevronItem.setImage(chevronImage);
		}
    }

	boolean[][] overflow = new boolean[1][0];
	Rectangle[] rects = computeControlBounds(size, overflow);
	if (fixedTabHeight != SWT.DEFAULT) {
		int height = fixedTabHeight;
		if (!hovering) {
			hoverTb = false;
			Rectangle tabBounds = this.getBounds();
			for (int i = 0; i < rects.length; i++) {
				if (!(overflow[0][i])) {
					if (rects[i].height > height) {
						hoverTb = true;
						break;
					}
				}
			}
			if (hoverTb) {
				for (int i = 0; i < rects.length; i++) {
					if (!(overflow[0][i])) {
						if (rects[i].height > height) {
							rects[i].x = tabBounds.width + 20;
						}
					}
				}
			}
		}
	}
	int headerHeight = 0;
	for (int i = 0; i < rects.length; i++) {
		if (!overflow[0][i]) headerHeight = Math.max(rects[i].height, headerHeight);
	}
	boolean changed = false;
	ignoreResize = true;
	for (int i = 0; i < controls.length; i++) {
		if (!controls[i].isDisposed()) {
			if (overflow[0][i]) {
				controls[i].setBounds(rects[i]);
			} else {
				controls[i].moveAbove(null);
				controls[i].setBounds(rects[i].x, rects[i].y, rects[i].width, headerHeight);
			}
		}
		if (!changed && !rects[i].equals(controlRects[i])) changed = true;
	}
	ignoreResize = false;
	controlRects = rects;
	if (changed || hovering) updateBkImages();
}
@Override
public boolean setFocus () {
	checkWidget ();

	/*
	* Feature in SWT.  When a new tab item is selected
	* and the previous tab item had focus, removing focus
	* from the previous tab item causes fixFocus() to give
	* focus to the first child, which is usually one of the
	* toolbars. This is unexpected.
	* The fix is to try to set focus on the first tab item
	* if fixFocus() is called.
	*/
	Control focusControl = getDisplay().getFocusControl ();
	boolean fixFocus = isAncestor (focusControl);
	if (fixFocus) {
		CTabItem item = getSelection();
		if (item != null) {
			if (item.setFocus ()) return true;
		}
	}
	return super.setFocus ();
}
/* Copy of isFocusAncestor from Control. */
boolean isAncestor (Control control) {
	while (control != null && control != this && !(control instanceof Shell)) {
		control = control.getParent();
	}
	return control == this;
}
@Override
public void setFont(Font font) {
	checkWidget();
	if (font != null && font.equals(getFont())) return;
	super.setFont(font);
	oldFont = getFont();
	updateFolder(REDRAW);
}
@Override
public void setForeground (Color color) {
	super.setForeground(color);
	redraw();
}
/**
 * Display an insert marker before or after the specified tab item.
 *
 * A value of null will clear the mark.
 *
 * @param item the item with which the mark is associated or null
 *
 * @param after true if the mark should be displayed after the specified item
 *
 * @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 setInsertMark(CTabItem item, boolean after) {
	checkWidget();
}
/**
 * Display an insert marker before or after the specified tab item.
 *
 * A value of -1 will clear the mark.
 *
 * @param index the index of the item with which the mark is associated or -1
 *
 * @param after true if the mark should be displayed after the specified item
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT when the index is invalid</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 void setInsertMark(int index, boolean after) {
	checkWidget();
	if (index < -1 || index >= getItemCount()) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
}
boolean setItemLocation(GC gc) {
	boolean changed = false;
	if (items.length == 0) return false;
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
	int borderBottom = trim.height + trim.y;
	int borderTop = -trim.y;
	Point size = getSize();
	int y = onBottom ? Math.max(borderBottom, size.y - borderBottom - tabHeight) : borderTop;
	Point closeButtonSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, 0, gc, SWT.DEFAULT, SWT.DEFAULT);
	int leftItemEdge = getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER);
	if (single) {
		int defaultX = getDisplay().getBounds().width + 10; // off screen
		for (int i = 0; i < items.length; i++) {
			CTabItem item = items[i];
			if (i == selectedIndex) {
				firstIndex = selectedIndex;
				int oldX = item.x, oldY = item.y;
				item.x = leftItemEdge;
				item.y = y;
				item.showing = true;
				if (showClose || item.showClose) {
					item.closeRect.x = leftItemEdge - renderer.computeTrim(i, SWT.NONE, 0, 0, 0, 0).x;
					item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - closeButtonSize.y)/2: borderTop + (tabHeight - closeButtonSize.y)/2;
				}
				if (item.x != oldX || item.y != oldY) changed = true;
			} else {
				item.x = defaultX;
				item.showing = false;
			}
		}
	} else {
		int rightItemEdge = getRightItemEdge(gc);
		int maxWidth = rightItemEdge - leftItemEdge;
		int width = 0;
		for (int i = 0; i < priority.length; i++) {
			CTabItem item = items[priority[i]];
			width += item.width;
			item.showing = i == 0 ? true : item.width > 0 && width <= maxWidth;
		}
		int x = getLeftItemEdge(gc, CTabFolderRenderer.PART_HEADER);
		int defaultX = getDisplay().getBounds().width + 10; // off screen
		firstIndex = items.length - 1;
		for (int i = 0; i < items.length; i++) {
			CTabItem item = items[i];
			if (!item.showing) {
				if (item.x != defaultX) changed = true;
				item.x = defaultX;
			} else {
				firstIndex = Math.min(firstIndex, i);
				if (item.x != x || item.y != y) changed = true;
				item.x = x;
				item.y = y;
				int state = SWT.NONE;
				if (i == selectedIndex) state |= SWT.SELECTED;
				Rectangle edgeTrim = renderer.computeTrim(i, state, 0, 0, 0, 0);
				item.closeRect.x = item.x + item.width  - (edgeTrim.width + edgeTrim.x) - closeButtonSize.x;
				item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - closeButtonSize.y)/2: borderTop + (tabHeight - closeButtonSize.y)/2;
				x = x + item.width;
				if (!simple && i == selectedIndex) x -= renderer.curveIndent; //TODO: fix next item position
			}
		}
	}
	return changed;
}
/**
 * Reorder the items of the receiver.
 * @param indices an array containing the new indices for all items
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the indices array is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the indices array is not the same length as the number of items,
 *    if there are duplicate indices or an index is out of range.</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*/ void setItemOrder (int[] indices) {
	checkWidget();
	if (indices == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (indices.length != items.length) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	int newSelectedIndex = -1;
	boolean[] seen = new boolean[items.length];
	CTabItem[] temp = new CTabItem[items.length];
	for (int i=0; i<indices.length; i++) {
		int index = indices[i];
		if (!(0 <= index && index < items.length)) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
		if (seen[index]) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
		seen[index] = true;
		if (index == selectedIndex) newSelectedIndex = i;
		temp[i] = items[index];
	}
	items = temp;
	selectedIndex = newSelectedIndex;
	updateFolder(REDRAW);
}
boolean setItemSize(GC gc) {
	boolean changed = false;
	if (isDisposed()) return changed;
	Point size = getSize();
	if (size.x <= 0 || size.y <= 0) return changed;
	ToolBar chevron = getChevron();
	if (chevron != null) chevron.setVisible(false);
	showChevron = false;
	if (single) {
		showChevron = chevronVisible && items.length > 1;
		if (showChevron) {
			chevron.setVisible(true);
		}
		if (selectedIndex != -1) {
			CTabItem tab = items[selectedIndex];
			int width = renderer.computeSize(selectedIndex, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x;
			width = Math.min(width, getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER));
			if (tab.height != tabHeight || tab.width != width) {
				changed = true;
				tab.shortenedText = null;
				tab.shortenedTextWidth = 0;
				tab.height = tabHeight;
				tab.width = width;
				tab.closeRect.width = tab.closeRect.height = 0;
				if (showClose || tab.showClose) {
					Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT);
					tab.closeRect.width = closeSize.x;
					tab.closeRect.height = closeSize.y;
				}
			}
		}
		return changed;
	}

	if (items.length == 0) return changed;
	int[] widths;
	int tabAreaWidth = Math.max(0, getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER));
	// First, try the minimum tab size at full compression.
	int minWidth = 0;
	int[] minWidths = new int[items.length];
	for (int i = 0; i < priority.length; i++) {
		int index = priority[i];
		int state = CTabFolderRenderer.MINIMUM_SIZE;
		if (index == selectedIndex) state |= SWT.SELECTED;
		minWidths[index] = renderer.computeSize(index, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
		minWidth += minWidths[index];
		if (minWidth > tabAreaWidth) break;
	}
	if (minWidth > tabAreaWidth) {
		// full compression required and a chevron
		showChevron = chevronVisible && items.length > 1;
		if (showChevron) {
			tabAreaWidth -= chevron.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
			chevron.setVisible(true);
		}
		widths = minWidths;
		int index = selectedIndex != -1 ? selectedIndex : 0;
		if (tabAreaWidth < widths[index]) {
			widths[index] = Math.max(0, tabAreaWidth);
		}
	} else {
		int maxWidth = 0;
		int[] maxWidths = new int[items.length];
		for (int i = 0; i < items.length; i++) {
			int state = 0;
			if (i == selectedIndex) state |= SWT.SELECTED;
			maxWidths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
			maxWidth += maxWidths[i];
		}
		if (maxWidth <= tabAreaWidth) {
			// no compression required
			widths = maxWidths;
		} else {
			// determine compression for each item
			int extra = (tabAreaWidth - minWidth) / items.length;
			while (true) {
				int large = 0, totalWidth = 0;
				for (int i = 0 ; i < items.length; i++) {
					if (maxWidths[i] > minWidths[i] + extra) {
						totalWidth += minWidths[i] + extra;
						large++;
					} else {
						totalWidth += maxWidths[i];
					}
				}
				if (totalWidth >= tabAreaWidth) {
					extra--;
					break;
				}
				if (large == 0 || tabAreaWidth - totalWidth < large) break;
				extra++;
			}
			widths = new int[items.length];
			for (int i = 0; i < items.length; i++) {
				widths[i] = Math.min(maxWidths[i], minWidths[i] + extra);
			}
		}
	}

	for (int i = 0; i < items.length; i++) {
		CTabItem tab = items[i];
		int width = widths[i];
		if (tab.height != tabHeight || tab.width != width) {
			changed = true;
			tab.shortenedText = null;
			tab.shortenedTextWidth = 0;
			tab.height = tabHeight;
			tab.width = width;
			tab.closeRect.width = tab.closeRect.height = 0;
			if (showClose || tab.showClose) {
				if (i == selectedIndex || showUnselectedClose) {
					Point closeSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
					tab.closeRect.width = closeSize.x;
					tab.closeRect.height = closeSize.y;
				}
			}
		}
	}
	return changed;
}
/**
 * Marks the receiver's maximize button as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise.
 *
 * @param visible the new visibility state
 *
 * @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 3.0
 */
public void setMaximizeVisible(boolean visible) {
	checkWidget();
	if (showMax == visible) return;
	// display maximize button
	showMax = visible;
	updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
}
/**
 * Sets the layout which is associated with the receiver to be
 * the argument which may be null.
 * <p>
 * Note: No Layout can be set on this Control because it already
 * manages the size and position of its children.
 * </p>
 *
 * @param layout the receiver's new layout 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>
 */
@Override
public void setLayout (Layout layout) {
	checkWidget();
	return;
}
/**
 * Sets the maximized state of the receiver.
 *
 * @param maximize the new maximized state
 *
 * @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 3.0
 */
public void setMaximized(boolean maximize) {
	checkWidget ();
	if (this.maximized == maximize) return;
	if (maximize && this.minimized) setMinimized(false);
	this.maximized = maximize;
	if (minMaxTb != null && maxItem != null) {
		if (maxImage != null) maxImage.dispose();
		maxImage = createButtonImage(getDisplay(), CTabFolderRenderer.PART_MAX_BUTTON);
		maxItem.setImage(maxImage);
		maxItem.setToolTipText(maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize")); //$NON-NLS-1$ //$NON-NLS-2$
	}
}
/**
 * Marks the receiver's minimize button as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise.
 *
 * @param visible the new visibility state
 *
 * @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 3.0
 */
public void setMinimizeVisible(boolean visible) {
	checkWidget();
	if (showMin == visible) return;
	// display minimize button
	showMin = visible;
	updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
}
/**
 * Sets the minimized state of the receiver.
 *
 * @param minimize the new minimized state
 *
 * @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 3.0
 */
public void setMinimized(boolean minimize) {
	checkWidget ();
	if (this.minimized == minimize) return;
	if (minimize && this.maximized) setMaximized(false);
	this.minimized = minimize;
	if (minMaxTb != null && minItem != null) {
		if (minImage != null) minImage.dispose();
		minImage = createButtonImage(getDisplay(), CTabFolderRenderer.PART_MIN_BUTTON);
		minItem.setImage(minImage);
		minItem.setToolTipText(minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize")); //$NON-NLS-1$ //$NON-NLS-2$
	}
}

/**
 * Sets the minimum number of characters that will
 * be displayed in a fully compressed tab.
 *
 * @param count the minimum number of characters that will be displayed in a fully compressed tab
 *
 * @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>
 *    <li>ERROR_INVALID_RANGE - if the count is less than zero</li>
 * </ul>
 *
 * @since 3.0
 */
public void setMinimumCharacters(int count) {
	checkWidget ();
	if (count < 0) SWT.error(SWT.ERROR_INVALID_RANGE);
	if (minChars == count) return;
	minChars = count;
	updateFolder(REDRAW_TABS);
}

/**
 * When there is not enough horizontal space to show all the tabs,
 * by default, tabs are shown sequentially from left to right in
 * order of their index.  When the MRU visibility is turned on,
 * the tabs that are visible will be the tabs most recently selected.
 * Tabs will still maintain their left to right order based on index
 * but only the most recently selected tabs are visible.
 * <p>
 * For example, consider a CTabFolder that contains "Tab 1", "Tab 2",
 * "Tab 3" and "Tab 4" (in order by index).  The user selects
 * "Tab 1" and then "Tab 3".  If the CTabFolder is now
 * compressed so that only two tabs are visible, by default,
 * "Tab 2" and "Tab 3" will be shown ("Tab 3" since it is currently
 * selected and "Tab 2" because it is the previous item in index order).
 * If MRU visibility is enabled, the two visible tabs will be "Tab 1"
 * and "Tab 3" (in that order from left to right).</p>
 *
 * @param show the new visibility state
 *
 * @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 3.1
 */
public void setMRUVisible(boolean show) {
	checkWidget();
	if (mru == show) return;
	mru = show;
	if (!mru) {
		if (firstIndex == -1) return;
		int idx = firstIndex;
		int next = 0;
		for (int i = firstIndex; i < items.length; i++) {
			priority[next++] = i;
		}
		for (int i = 0; i < idx; i++) {
			priority[next++] = i;
		}
		updateFolder(REDRAW_TABS);
	}
}
/**
 * Sets the renderer which is associated with the receiver to be
 * the argument which may be null. In the case of null, the default
 * renderer is used.
 *
 * @param renderer a new renderer
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @see CTabFolderRenderer
 *
 * @since 3.6
 */
public void setRenderer(CTabFolderRenderer renderer) {
	checkWidget();
	if (this.renderer == renderer || (useDefaultRenderer && renderer == null)) return;
	if (this.renderer != null) this.renderer.dispose();
	useDefaultRenderer = renderer == null;
	if (useDefaultRenderer) renderer = new CTabFolderRenderer(this);
	this.renderer = renderer;
	updateFolder(REDRAW);
}
/**
 * Set the selection to the tab at the specified item.
 *
 * @param item the tab item to be selected
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 * </ul>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 */
public void setSelection(CTabItem item) {
	checkWidget();
	if (item == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	int index = indexOf(item);
	setSelection(index);
}
/**
 * Set the selection to the tab at the specified index.
 *
 * @param index the index of the tab item to be selected
 *
 * @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 setSelection(int index) {
	checkWidget();
	if (index < 0 || index >= items.length) return;
	CTabItem selection = items[index];
	if (selectedIndex == index) {
		showItem(selection);
		return;
	}

	int oldIndex = selectedIndex;
	selectedIndex = index;
	if (oldIndex != -1) {
		items[oldIndex].closeImageState = SWT.BACKGROUND;
		items[oldIndex].state &= ~SWT.SELECTED;
	}
	selection.closeImageState = SWT.NONE;
	selection.showing = false;
	selection.state |= SWT.SELECTED;

	Control newControl = selection.control;
	Control oldControl = null;
	if (oldIndex != -1) {
		oldControl = items[oldIndex].control;
	}

	if (newControl != oldControl) {
		if (newControl != null && !newControl.isDisposed()) {
			newControl.setBounds(getClientArea());
			newControl.setVisible(true);
		}
		if (oldControl != null && !oldControl.isDisposed()) {
			oldControl.setVisible(false);
		}
	}
	showItem(selection);
	redraw();
}
void setSelection(int index, boolean notify) {
	int oldSelectedIndex = selectedIndex;
	setSelection(index);
	if (notify && selectedIndex != oldSelectedIndex && selectedIndex != -1) {
		Event event = new Event();
		event.item = getItem(selectedIndex);
		notifyListeners(SWT.Selection, event);
	}
}
/**
 * Sets the receiver's selection background color to the color specified
 * by the argument, or to the default system color for the control
 * if the argument is null.
 *
 * @param color the new color (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been 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>
 *
 * @since 3.0
 */
public void setSelectionBackground (Color color) {
	if (inDispose) return;
	checkWidget();
	setSelectionHighlightGradientColor(null);
	if (selectionBackground == color) return;
	if (color == null) color = getDisplay().getSystemColor(SELECTION_BACKGROUND);
	selectionBackground = color;
	renderer.createAntialiasColors(); //TODO:  need better caching strategy
	if (selectedIndex > -1) redraw();
}
/**
 * Specify a gradient of colours to be draw in the background of the selected tab.
 * For example to draw a gradient that varies from dark blue to blue and then to
 * white, use the following call to setBackground:
 * <pre>
 *	cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		               new int[] {25, 50, 100});
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradient
 *               in order of appearance left to right.  The value <code>null</code> clears the
 *               background gradient. The value <code>null</code> can be used inside the array of
 *               Color to specify the background color.
 * @param percents an array of integers between 0 and 100 specifying the percent of the width
 *                 of the widget at which the color should change.  The size of the percents array must be one
 *                 less than the size of the colors array.
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 */
public void setSelectionBackground(Color[] colors, int[] percents) {
	setSelectionBackground(colors, percents, false);
}
/**
 * Specify a gradient of colours to be draw in the background of the selected tab.
 * For example to draw a vertical gradient that varies from dark blue to blue and then to
 * white, use the following call to setBackground:
 * <pre>
 *	cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		                  new int[] {25, 50, 100}, true);
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradient
 *               in order of appearance left to right.  The value <code>null</code> clears the
 *               background gradient. The value <code>null</code> can be used inside the array of
 *               Color to specify the background color.
 * @param percents an array of integers between 0 and 100 specifying the percent of the width
 *                 of the widget at which the color should change.  The size of the percents array must be one
 *                 less than the size of the colors array.
 *
 * @param vertical indicate the direction of the gradient.  True is vertical and false is horizontal.
 *
 * @exception SWTException <ul>
 *		<li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *		<li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 *	</ul>
 *
 * @since 3.0
 */
public void setSelectionBackground(Color[] colors, int[] percents, boolean vertical) {
	checkWidget();
	int colorsLength;
	Color highlightBeginColor = null;  //null == no highlight

	if (colors != null) {
		//The colors array can optionally have an extra entry which describes the highlight top color
		//Thus its either one or two larger than the percents array
		if (percents == null ||
				! ((percents.length == colors.length - 1) || (percents.length == colors.length - 2))){
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		for (int i = 0; i < percents.length; i++) {
			if (percents[i] < 0 || percents[i] > 100) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
			if (i > 0 && percents[i] < percents[i-1]) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
		}
		//If the colors is exactly two more than percents then last is highlight
		//Keep track of *real* colorsLength (minus the highlight)
		if(percents.length == colors.length - 2) {
			highlightBeginColor = colors[colors.length - 1];
			colorsLength = colors.length - 1;
		} else {
			colorsLength = colors.length;
		}
		if (getDisplay().getDepth() < 15) {
			// Don't use gradients on low color displays
			colors = new Color[] {colors[colorsLength - 1]};
			colorsLength = colors.length;
			percents = new int[] {};
		}
	} else {
		colorsLength = 0;
	}

	// Are these settings the same as before?
	if (selectionBgImage == null) {
		if ((selectionGradientColors != null) && (colors != null) &&
			(selectionGradientColors.length == colorsLength)) {
			boolean same = false;
			for (int i = 0; i < selectionGradientColors.length; i++) {
				if (selectionGradientColors[i] == null) {
					same = colors[i] == null;
				} else {
					same = selectionGradientColors[i].equals(colors[i]);
				}
				if (!same) break;
			}
			if (same) {
				for (int i = 0; i < selectionGradientPercents.length; i++) {
					same = selectionGradientPercents[i] == percents[i];
					if (!same) break;
				}
			}
			if (same && this.selectionGradientVertical == vertical) return;
		}
	} else {
		selectionBgImage = null;
	}
	// Store the new settings
	if (colors == null) {
		selectionGradientColors = null;
		selectionGradientPercents = null;
		selectionGradientVertical = false;
		setSelectionBackground((Color)null);
		setSelectionHighlightGradientColor(null);
	} else {
		selectionGradientColors = new Color[colorsLength];
		for (int i = 0; i < colorsLength; ++i) {
			selectionGradientColors[i] = colors[i];
		}
		selectionGradientPercents = new int[percents.length];
		for (int i = 0; i < percents.length; ++i) {
			selectionGradientPercents[i] = percents[i];
		}
		selectionGradientVertical = vertical;
		setSelectionBackground(selectionGradientColors[selectionGradientColors.length-1]);
		setSelectionHighlightGradientColor(highlightBeginColor);
	}

	// Refresh with the new settings
	if (selectedIndex > -1) redraw();
}

/*
 * Set the color for the highlight start for selected tabs.
 * Update the cache of highlight gradient colors if required.
 */
void setSelectionHighlightGradientColor(Color start) {
	if (inDispose) return;
	renderer.setSelectionHighlightGradientColor(start);  //TODO: need better caching strategy
}

/**
 * Set the image to be drawn in the background of the selected tab.  Image
 * is stretched or compressed to cover entire selection tab area.
 *
 * @param image the image to be drawn in the background
 *
 * @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 setSelectionBackground(Image image) {
	checkWidget();
	setSelectionHighlightGradientColor(null);
	if (image == selectionBgImage) return;
	if (image != null) {
		selectionGradientColors = null;
		selectionGradientPercents = null;
		renderer.disposeSelectionHighlightGradientColors(); //TODO: need better caching strategy
	}
	selectionBgImage = image;
	renderer.createAntialiasColors(); //TODO:  need better caching strategy
	if (selectedIndex > -1) redraw();
}
/**
 * Set the foreground color of the selected tab.
 *
 * @param color the color of the text displayed in the selected tab
 *
 * @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 setSelectionForeground (Color color) {
	checkWidget();
	if (selectionForeground == color) return;
	if (color == null) color = getDisplay().getSystemColor(SELECTION_FOREGROUND);
	selectionForeground = color;
	if (selectedIndex > -1) redraw();
}

/**
 * Sets the shape that the CTabFolder will use to render itself.
 *
 * @param simple <code>true</code> if the CTabFolder should render itself in a simple, traditional style
 *
 * @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 3.0
 */
public void setSimple(boolean simple) {
	checkWidget();
	if (this.simple != simple) {
		this.simple = simple;
		updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
	}
}
/**
 * Sets the number of tabs that the CTabFolder should display
 *
 * @param single <code>true</code> if only the selected tab should be displayed otherwise, multiple tabs will be shown.
 *
 * @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 3.0
 */
public void setSingle(boolean single) {
	checkWidget();
	if (this.single != single) {
		this.single = single;
		if (!single) {
			for (int i = 0; i < items.length; i++) {
				if (i != selectedIndex && items[i].closeImageState == SWT.NONE) {
					items[i].closeImageState = SWT.BACKGROUND;
				}
			}
		}
		updateFolder(REDRAW);
	}
}

int getControlY(Point size, Rectangle[] rects, int borderBottom, int borderTop, int i) {
	int center = fixedTabHeight != SWT.DEFAULT ? 0 : (tabHeight - rects[i].height)/2;
	return onBottom ? size.y - borderBottom - tabHeight + center : 1 + borderTop + center;
}

/**
 * Specify a fixed height for the tab items.  If no height is specified,
 * the default height is the height of the text or the image, whichever
 * is greater. Specifying a height of -1 will revert to the default height.
 *
 * @param height the pixel value of the height or -1
 *
 * @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>
 *    <li>ERROR_INVALID_ARGUMENT - if called with a height of less than 0</li>
 * </ul>
 */
public void setTabHeight(int height) {
	checkWidget();
	if (height < -1) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	fixedTabHeight = height;
	updateFolder(UPDATE_TAB_HEIGHT);
}
/**
 * Specify whether the tabs should appear along the top of the folder
 * or along the bottom of the folder.
 *
 * @param position <code>SWT.TOP</code> for tabs along the top or <code>SWT.BOTTOM</code> for tabs along the bottom
 *
 * @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>
 *    <li>ERROR_INVALID_ARGUMENT - if the position value is not either SWT.TOP or SWT.BOTTOM</li>
 * </ul>
 *
 * @since 3.0
 */
public void setTabPosition(int position) {
	checkWidget();
	if (position != SWT.TOP && position != SWT.BOTTOM) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (onBottom != (position == SWT.BOTTOM)) {
		onBottom = position == SWT.BOTTOM;
		updateFolder(REDRAW);
	}
}
/**
 * Set the control that appears in the top right corner of the tab folder.
 * Typically this is a close button or a composite with a Menu and close button.
 * The topRight control is optional.  Setting the top right control to null will
 * remove it from the tab folder.
 *
 * @param control the control to be displayed in the top right corner 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>
 *    <li>ERROR_INVALID_ARGUMENT - if the control is disposed, or not a child of this CTabFolder</li>
 * </ul>
 *
 * @since 2.1
 */
public void setTopRight(Control control) {
	setTopRight(control, SWT.RIGHT);
}
/**
 * Set the control that appears in the top right corner of the tab folder.
 * Typically this is a close button or a composite with a Menu and close button.
 * The topRight control is optional.  Setting the top right control to null
 * will remove it from the tab folder.
 * <p>
 * The alignment parameter sets the layout of the control in the tab area.
 * <code>SWT.RIGHT</code> will cause the control to be positioned on the far
 * right of the folder and it will have its default size.  <code>SWT.FILL</code>
 * will size the control to fill all the available space to the right of the
 * last tab.  If there is no available space, the control will not be visible.
 * <code>SWT.RIGHT | SWT.WRAP</code> will allow the control to wrap below the
 * tabs if there is not enough available space to the right of the last tab.
 * </p>
 *
 * @param control the control to be displayed in the top right corner or null
 * @param alignment <code>SWT.RIGHT</code> or <code>SWT.FILL</code> or <code>SWT.RIGHT | SWT.WRAP</code>
 *
 * @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>
 *    <li>ERROR_INVALID_ARGUMENT - if the control is disposed, or not a child of this CTabFolder</li>
 * </ul>
 *
 * @since 3.0
 */
public void setTopRight(Control control, int alignment) {
	checkWidget();
	if (alignment != SWT.RIGHT && alignment != SWT.FILL && alignment != (SWT.RIGHT | SWT.WRAP)) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (control != null && (control.isDisposed() || control.getParent() != this)) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (topRight == control && topRightAlignment == alignment) return;
	if (topRight != null && !topRight.isDisposed()) removeTabControl(topRight, false);
	topRight = control;
	topRightAlignment = alignment;
	alignment &= ~SWT.RIGHT;
	if (control != null) addTabControl(control, SWT.TRAIL | alignment, -1, false);
	updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
}


/**
 * Specify whether the close button appears
 * when the user hovers over an unselected tabs.
 *
 * @param visible <code>true</code> makes the close button appear
 *
 * @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 3.0
 */
public void setUnselectedCloseVisible(boolean visible) {
	checkWidget();
	if (showUnselectedClose == visible) return;
	// display close button when mouse hovers
	showUnselectedClose = visible;
	updateFolder(REDRAW);
}
/**
 * Specify whether the image appears on unselected tabs.
 *
 * @param visible <code>true</code> makes the image appear
 *
 * @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 3.0
 */
public void setUnselectedImageVisible(boolean visible) {
	checkWidget();
	if (showUnselectedImage == visible) return;
	// display image on unselected items
	showUnselectedImage = visible;
	updateFolder(REDRAW);
}
/**
 * Shows the item.  If the item is already showing in the receiver,
 * this method simply returns.  Otherwise, the items are scrolled until
 * the item is visible.
 *
 * @param item the item to be shown
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the item has been 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>
 *
 * @see CTabFolder#showSelection()
 *
 * @since 2.0
 */
public void showItem (CTabItem item) {
	checkWidget();
	if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	int index = indexOf(item);
	if (index == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	int idx = -1;
	for (int i = 0; i < priority.length; i++) {
		if (priority[i] == index) {
			idx = i;
			break;
		}
	}
	if (mru) {
		// move to front of mru order
		int[] newPriority = new int[priority.length];
		System.arraycopy(priority, 0, newPriority, 1, idx);
		System.arraycopy(priority, idx+1, newPriority, idx+1, priority.length - idx - 1);
		newPriority[0] = index;
		priority = newPriority;
	}
	if (item.showing) return;
	updateFolder(REDRAW_TABS);
}
void showList (Rectangle rect) {
	if (items.length == 0 || !showChevron) return;
	if (showMenu == null || showMenu.isDisposed()) {
		showMenu = new Menu(getShell(), getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT));
	} else {
		MenuItem[] items = showMenu.getItems();
		for (int i = 0; i < items.length; i++) {
			items[i].dispose();
		}
	}
	final String id = "CTabFolder_showList_Index"; //$NON-NLS-1$
	for (int i = 0; i < items.length; i++) {
		CTabItem tab = items[i];
		if (tab.showing) continue;
		MenuItem item = new MenuItem(showMenu, SWT.NONE);
		item.setText(tab.getText());
		item.setImage(tab.getImage());
		item.setData(id, tab);
		item.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				MenuItem menuItem = (MenuItem)e.widget;
				int index = indexOf((CTabItem)menuItem.getData(id));
				CTabFolder.this.setSelection(index, true);
			}
		});
	}
	int x = rect.x;
	int y = rect.y + rect.height;
	Point location = getDisplay().map(this, null, x, y);
	showMenu.setLocation(location.x, location.y);
	showMenu.setVisible(true);
}
/**
 * Shows the selection.  If the selection is already showing in the receiver,
 * this method simply returns.  Otherwise, the items are scrolled until
 * the selection is visible.
 *
 * @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>
 *
 * @see CTabFolder#showItem(CTabItem)
 *
 * @since 2.0
 */
public void showSelection () {
	checkWidget ();
	if (selectedIndex != -1) {
		showItem(getSelection());
	}
}

void _setToolTipText (int x, int y) {
	String oldTip = getToolTipText();
	String newTip = _getToolTip(x, y);
	if (newTip == null || !newTip.equals(oldTip)) {
		setToolTipText(newTip);
	}
}

boolean updateItems() {
	return updateItems(selectedIndex);
}

boolean updateItems (int showIndex) {
	GC gc = new GC(this);
	if (!single && !mru && showIndex != -1) {
		// make sure selected item will be showing
		int firstIndex = showIndex;
		if (priority[0] < showIndex) {
			int maxWidth = getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER);
			int width = 0;
			int[] widths = new int[items.length];
			for (int i = priority[0]; i <= showIndex; i++) {
				int state = CTabFolderRenderer.MINIMUM_SIZE;
				if (i == selectedIndex) state |= SWT.SELECTED;
				widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
				width += widths[i];
				if (width > maxWidth) break;
			}
			if (width > maxWidth) {
				width = 0;
				for (int i = showIndex; i >= 0; i--) {
					int state = CTabFolderRenderer.MINIMUM_SIZE;
					if (i == selectedIndex) state |= SWT.SELECTED;
					if (widths[i] == 0) widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
					width += widths[i];
					if (width > maxWidth) break;
					firstIndex = i;
				}
			} else {
				firstIndex = priority[0];
				for (int i = showIndex + 1; i < items.length; i++) {
					int state = CTabFolderRenderer.MINIMUM_SIZE;
					if (i == selectedIndex) state |= SWT.SELECTED;
					widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
					width += widths[i];
					if (width >= maxWidth) break;
				}
				if (width < maxWidth) {
					for (int i = priority[0] - 1; i >= 0; i--) {
						int state = CTabFolderRenderer.MINIMUM_SIZE;
						if (i == selectedIndex) state |= SWT.SELECTED;
						if (widths[i] == 0) widths[i] = renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
						width += widths[i];
						if (width > maxWidth) break;
						firstIndex = i;
					}
				}
			}

		}
		if (firstIndex != priority[0]) {
			int index = 0;
			// enumerate tabs from first visible to the last existing one (sorted ascending)
			for (int i = firstIndex; i < items.length; i++) {
				priority[index++] = i;
			}
			// enumerate hidden tabs on the left hand from first visible one
			// in the inverse order (sorted descending) so that the originally
			// first opened tab is always at the end of the list
			for (int i = firstIndex - 1; i >= 0; i--) {
				priority[index++] = i;
			}
		}
	}

	boolean oldShowChevron = showChevron;
	boolean changed = setItemSize(gc);
	changed |= setItemLocation(gc);
	setButtonBounds(gc);
	changed |= showChevron != oldShowChevron;
	if (changed && getToolTipText() != null) {
		Point pt = getDisplay().getCursorLocation();
		pt = toControl(pt);
		_setToolTipText(pt.x, pt.y);
	}
	gc.dispose();
	return changed;
}
boolean updateTabHeight(boolean force){
	int oldHeight = tabHeight;
	GC gc = new GC(this);
	tabHeight = renderer.computeSize(CTabFolderRenderer.PART_HEADER, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).y;
	gc.dispose();
	if (fixedTabHeight == SWT.DEFAULT && controls != null && controls.length > 0) {
		for (int i = 0; i < controls.length; i++) {
			if ((controlAlignments[i] & SWT.WRAP) == 0 && !controls[i].isDisposed() && controls[i].getVisible()) {
				int topHeight = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
				topHeight +=  renderer.computeTrim(CTabFolderRenderer.PART_HEADER, SWT.NONE, 0,0,0,0).height + 1;
				tabHeight = Math.max(topHeight, tabHeight);
			}
		}
	}
	if (!force && tabHeight == oldHeight) return false;
	oldSize = null;
	return true;
}

void updateFolder (int flags) {
	updateFlags |= flags;
	if (updateRun != null) return;
	updateRun = () -> {
		updateRun = null;
		if (isDisposed()) return;
		runUpdate();
	};
	getDisplay().asyncExec(updateRun);
}

void runUpdate() {
	if (updateFlags == 0) return;
	int flags = updateFlags;
	updateFlags = 0;
	Rectangle rectBefore = getClientArea();
	updateTabHeight(false);
	updateItems(selectedIndex);
	if ((flags & REDRAW) != 0) {
		redraw();
	} else if ((flags & REDRAW_TABS) != 0) {
		redrawTabs();
	}
	Rectangle rectAfter = getClientArea();
	if (!rectBefore.equals(rectAfter)) {
		notifyListeners(SWT.Resize, new Event());
		layout();
	}
}

void updateBkImages() {
	if (controls != null && controls.length > 0) {
		for (int i = 0; i < controls.length; i++) {
			Control control = controls[i];
			if (!control.isDisposed()) {
				if (hovering) {
					if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_NONE);
					control.setBackgroundImage(null);
					control.setBackground(getBackground());
				} else {
					if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_DEFAULT);
					Rectangle bounds = control.getBounds();
					int tabHeight = getTabHeight();
					int height = this.getSize().y;
					boolean wrapped = onBottom ? bounds.y + bounds.height < height - tabHeight : bounds.y > tabHeight;
					if (wrapped || gradientColors == null) {
						control.setBackgroundImage(null);
						control.setBackground(getBackground());
					} else {
						bounds.width = 10;
						if (!onBottom) {
							bounds.y = -bounds.y;
							bounds.height -= 2*bounds.y - 1;
						} else {
							bounds.height += height - (bounds.y + bounds.height);
							bounds.y = -1;
						}
						bounds.x = 0;
						if (controlBkImages[i] != null) controlBkImages[i].dispose();
						controlBkImages[i] = new Image(control.getDisplay(), bounds);
						GC gc = new GC(controlBkImages[i]);
						renderer.draw(CTabFolderRenderer.PART_BACKGROUND, 0, bounds, gc);
						gc.dispose();
						control.setBackground(null);
						control.setBackgroundImage(controlBkImages[i]);
					}
				}
			}
		}

	}
}
String _getToolTip(int x, int y) {
	CTabItem item = getItem(new Point (x, y));
	if (item == null) return null;
	if (!item.showing) return null;
	if ((showClose || item.showClose) && item.closeRect.contains(x, y)) {
		return SWT.getMessage("SWT_Close"); //$NON-NLS-1$
	}
	return item.getToolTipText();
}
/**
* Set a control that can appear to the left or to the right of the folder tabs.
* This method can also be used instead of #setTopRight(Control). To remove a tab
* control, see#removeTabControl(Control);
* <p>
* The flags parameter sets the layout of the control in the tab area.
* <code>SWT.LEAD</code> will cause the control to be positioned on the left
* of the tabs. <code>SWT.TRAIL</code> will cause the control to be positioned on
* the far right of the folder and it will have its default size. <code>SWT.TRAIL</code>
* can be combined with <code>SWT.FILL</code>to fill all the available space to the
* right of the last tab. <code>SWT.WRAP</code> can also be added to <code>SWT.TRAIL</code>
* only to cause a control to wrap if there is not enough space to display it in its
* entirety.
* </p>
* @param control the control to be displayed in the top right corner or null
*
* @param flags valid combinations are:
* <ul><li>SWT.LEAD
* <li> SWT.TRAIL (| SWT.FILL | SWT.WRAP)
* </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>
*    <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder</li>
* </ul>
*/
/*public*/ void addTabControl(Control control, int flags) {
	checkWidget();
	addTabControl(control, flags, -1, true);
}

void addTabControl(Control control, int flags, int index, boolean update) {
	switch (flags) {
		case SWT.TRAIL:
		case SWT.TRAIL | SWT.WRAP:
		case SWT.TRAIL | SWT.FILL:
		case SWT.TRAIL | SWT.FILL | SWT.WRAP:
		case SWT.LEAD:
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			break;
	}
	if (control != null && control.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	//check for duplicates
	for (int i = 0; i < controls.length; i++) {
		if (controls[i] == control) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	int length = controls.length;

	control.addListener(SWT.Resize, listener);

	//Grow all 4 arrays
	Control[] newControls = new Control [length + 1];
	System.arraycopy(controls, 0, newControls, 0, length);
	controls = newControls;
	int[] newAlignment = new int [length + 1];
	System.arraycopy(controlAlignments, 0, newAlignment, 0, length);
	controlAlignments = newAlignment;
	Rectangle[] newRect = new Rectangle [length + 1];
	System.arraycopy(controlRects, 0, newRect, 0, length);
	controlRects = newRect;
	Image[] newImage = new Image [length + 1];
	System.arraycopy(controlBkImages, 0, newImage, 0, length);
	controlBkImages = newImage;
	if (index == -1) {
		index = length;
		if (chevronTb != null && control != chevronTb) index--;
	}
	System.arraycopy (controls, index, controls, index + 1, length - index);
	System.arraycopy (controlAlignments, index, controlAlignments, index + 1, length - index);
	System.arraycopy (controlRects, index, controlRects, index + 1, length - index);
	System.arraycopy (controlBkImages, index, controlBkImages, index + 1, length - index);
	controls[index] = control;
	controlAlignments[index] = flags;
	controlRects[index] = new Rectangle(0, 0, 0, 0);
	if (update) {
		updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
	}
}

/**
* Removes the control from the list of tab controls.
*
* @param control the control to be removed
*
* @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>
*    <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder</li>
* </ul>
*/
/*public*/ void removeTabControl (Control control) {
	checkWidget();
	removeTabControl (control, true);
}

void removeTabControl (Control control, boolean update) {
	if (control != null && control.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	int index = -1;
	for (int i = 0; i < controls.length; i++) {
		if (controls[i] == control){
			index = i;
			break;
		}
	}
	if (index == -1) return;

	if (!control.isDisposed()) {
		control.removeListener(SWT.Resize, listener);
		control.setBackground (null);
		control.setBackgroundImage (null);
		if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_NONE);
	}

	if (controlBkImages[index] != null && !controlBkImages[index].isDisposed()) controlBkImages[index].dispose();
	if (controls.length == 1) {
		controls = new Control[0];
		controlAlignments = new int[0];
		controlRects = new Rectangle[0];
		controlBkImages = new Image[0];
	} else {
		Control[] newControls = new Control [controls.length - 1];
		System.arraycopy(controls, 0, newControls, 0, index);
		System.arraycopy(controls, index + 1, newControls, index, controls.length - index - 1);
		controls = newControls;

		int[] newAlignments = new int [controls.length];
		System.arraycopy(controlAlignments, 0, newAlignments, 0, index);
		System.arraycopy(controlAlignments, index + 1, newAlignments, index, controls.length - index);
		controlAlignments = newAlignments;

		Rectangle[] newRects = new Rectangle [controls.length];
		System.arraycopy(controlRects, 0, newRects, 0, index);
		System.arraycopy(controlRects, index + 1, newRects, index, controls.length - index);
		controlRects = newRects;

		Image[] newBkImages = new Image [controls.length];
		System.arraycopy(controlBkImages, 0, newBkImages, 0, index);
		System.arraycopy(controlBkImages, index + 1, newBkImages, index, controls.length - index);
		controlBkImages = newBkImages;
	}
	if (update) {
		updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
	}
}

int getWrappedHeight (Point size) {
	boolean[][] positions = new boolean[1][];
	Rectangle[] rects = computeControlBounds(size, positions);
	int minY = Integer.MAX_VALUE, maxY = 0, wrapHeight = 0;
	for (int i = 0; i < rects.length; i++) {
		if (positions[0][i]) {
			minY = Math.min(minY, rects[i].y);
			maxY = Math.max(maxY, rects[i].y + rects[i].height);
			wrapHeight = maxY - minY;
		}
	}
	return wrapHeight;
}

/**
 * Sets whether a chevron is shown when there are more items to be displayed.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is out of range</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
 * </ul>
 *
 */
/*public*/ void setChevronVisible(boolean visible) {
	checkWidget();
	if (chevronVisible == visible) return;
	chevronVisible = visible;
	updateFolder(UPDATE_TAB_HEIGHT | REDRAW);
}

boolean shouldHighlight() {
	return this.highlight;
}
}
