/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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 points 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 points 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 highlightEnabled = true;

	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;
/**
 * 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) {
	if (!highlightEnabled) {
		return;
	}
	this.highlight = false;
	redraw();
}

void onActivate(Event event) {
	if (!highlightEnabled) {
		return;
	}
	this.highlight = true;
	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);
	Color transColor = renderer.parent.getBackground();
	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 ();

	final ImageData imageData = image.getImageData (DPIUtil.getDeviceZoom ());
	imageData.transparentPixel = imageData.palette.getPixel(transColor.getRGB());
	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 --;
	}

	requestLayout();
	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) {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//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) {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//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() {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//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() {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//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() {
	/*
	 * This call is intentionally commented out, to allow this getter method to be
	 * called from a thread which is different from one that created the widget.
	 */
	//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[] {Character.valueOf(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 point 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);
		// Bug 533124 In the case where you have multi line tab text, we force the drop-down menu to have single line entries to ensure consistent behavior across platforms.
		item.setText(tab.getText().replace("\n", " "));
		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 && highlightEnabled;
	}

/**
 * Sets whether the selected tab is rendered as highlighted.
 *
 * @param enabled
 *            {@code true} if the selected tab should be highlighted,
 *            {@code false} otherwise.
 * @exception SWTException
 *                <ul>
 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
 *                disposed</li>
 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
 *                thread that created the receiver</li>
 *                </ul>
 * @since 3.106
 */
public void setHighlightEnabled(boolean enabled) {
	checkWidget();
	if (highlightEnabled == enabled) {
		return;
	}
	highlightEnabled = enabled;
	updateFolder(REDRAW);
}

/**
 * Returns <code>true</code> if the selected tab is rendered as
 * highlighted.
 *
 * @return <code>true</code> if the selected tab is rendered as
 *         highlighted
 *
 * @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.106
 */
public boolean getHighlightEnabled() {
	checkWidget();
	return highlightEnabled;
}
}
