/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.custom;

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

/**
 * A Label which supports aligned text and/or an image and different border styles.
 * <p>
 * If there is not enough space a CLabel uses the following strategy to fit the
 * information into the available space:
 * <pre>
 * 		ignores the indent in left align mode
 * 		ignores the image and the gap
 * 		shortens the text by replacing the center portion of the label with an ellipsis
 * 		shortens the text by removing the center portion of the label
 * </pre>
 * <p>
 * <dl>
 * <dt><b>Styles:</b>
 * <dd>LEFT, RIGHT, CENTER, SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
 * <dt><b>Events:</b>
 * <dd></dd>
 * </dl>
 *
 * </p><p>
 * This class may be subclassed for the purpose of overriding the default string
 * shortening algorithm that is implemented in method <code>shortenText()</code>.
 * </p>
 *
 * @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>
 * @see CLabel#shortenText(GC, String, int)
 */
public class CLabel extends Canvas {

	/** Gap between icon and text */
	private static final int GAP = 5;
	/** Left and right margins */
	private static final int DEFAULT_MARGIN = 3;
	/** a string inserted in the middle of text that has been shortened */
	private static final String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026"
	/** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
	private int align = SWT.LEFT;
	private int leftMargin = DEFAULT_MARGIN;
	private int topMargin = DEFAULT_MARGIN;
	private int rightMargin = DEFAULT_MARGIN;
	private int bottomMargin = DEFAULT_MARGIN;
	/** the current text */
	private String text;
	/** the current icon */
	private Image image;
	// The tooltip is used for two purposes - the application can set
	// a tooltip or the tooltip can be used to display the full text when the
	// the text has been truncated due to the label being too short.
	// The appToolTip stores the tooltip set by the application.  Control.tooltiptext
	// contains whatever tooltip is currently being displayed.
	private String appToolTipText;
	private boolean ignoreDispose;

	private Image backgroundImage;
	private Color[] gradientColors;
	private int[] gradientPercents;
	private boolean gradientVertical;
	private Color background;

	private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;

/**
 * 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#LEFT
 * @see SWT#RIGHT
 * @see SWT#CENTER
 * @see SWT#SHADOW_IN
 * @see SWT#SHADOW_OUT
 * @see SWT#SHADOW_NONE
 * @see #getStyle()
 */
public CLabel(Composite parent, int style) {
	super(parent, checkStyle(style));
	if ((style & (SWT.CENTER | SWT.RIGHT)) == 0) style |= SWT.LEFT;
	if ((style & SWT.CENTER) != 0) align = SWT.CENTER;
	if ((style & SWT.RIGHT) != 0)  align = SWT.RIGHT;
	if ((style & SWT.LEFT) != 0)   align = SWT.LEFT;

	addPaintListener(event -> onPaint(event));

	addTraverseListener(event -> {
		if (event.detail == SWT.TRAVERSE_MNEMONIC) {
			onMnemonic(event);
		}
	});

	addListener(SWT.Dispose, event -> onDispose(event));

	initAccessible();

}
/**
 * Check the style bits to ensure that no invalid styles are applied.
 */
private static int checkStyle (int style) {
	if ((style & SWT.BORDER) != 0) style |= SWT.SHADOW_IN;
	int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
	style = style & mask;
	return style |= SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED;
}

@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
	checkWidget();
	Point e = getTotalSize(image, text);
	if (wHint == SWT.DEFAULT){
		e.x += leftMargin + rightMargin;
	} else {
		e.x = wHint;
	}
	if (hHint == SWT.DEFAULT) {
		e.y += topMargin + bottomMargin;
	} else {
		e.y = hHint;
	}
	return e;
}
/**
 * Draw a rectangle in the given colors.
 */
private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
	gc.setForeground(bottomright);
	gc.drawLine(x+w, y,   x+w, y+h);
	gc.drawLine(x,   y+h, x+w, y+h);

	gc.setForeground(topleft);
	gc.drawLine(x, y, x+w-1, y);
	gc.drawLine(x, y, x,     y+h-1);
}
/*
 * 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';
}
/**
 * Returns the horizontal alignment.
 * The alignment style (LEFT, CENTER or RIGHT) is returned.
 *
 * @return SWT.LEFT, SWT.RIGHT or SWT.CENTER
 */
public int getAlignment() {
	//checkWidget();
	return align;
}
/**
 * Return the CLabel's bottom margin.
 *
 * @return the bottom margin of the label
 *
 * @since 3.6
 */
public int getBottomMargin() {
	//checkWidget();
	return bottomMargin;
}
/**
 * Return the CLabel's image or <code>null</code>.
 *
 * @return the image of the label or null
 */
public Image getImage() {
	//checkWidget();
	return image;
}
/**
 * Return the CLabel's left margin.
 *
 * @return the left margin of the label
 *
 * @since 3.6
 */
public int getLeftMargin() {
	//checkWidget();
	return leftMargin;
}
/**
 * Return the CLabel's right margin.
 *
 * @return the right margin of the label
 *
 * @since 3.6
 */
public int getRightMargin() {
	//checkWidget();
	return rightMargin;
}
/**
 * Compute the minimum size.
 */
private Point getTotalSize(Image image, String text) {
	Point size = new Point(0, 0);

	if (image != null) {
		Rectangle r = image.getBounds();
		size.x += r.width;
		size.y += r.height;
	}

	GC gc = new GC(this);
	if (text != null && text.length() > 0) {
		Point e = gc.textExtent(text, DRAW_FLAGS);
		size.x += e.x;
		size.y = Math.max(size.y, e.y);
		if (image != null) size.x += GAP;
	} else {
		size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
	}
	gc.dispose();

	return size;
}
@Override
public int getStyle () {
	int style = super.getStyle();
	switch (align) {
		case SWT.RIGHT: style |= SWT.RIGHT; break;
		case SWT.CENTER: style |= SWT.CENTER; break;
		case SWT.LEFT: style |= SWT.LEFT; break;
	}
	return style;
}

/**
 * Return the Label's text.
 *
 * @return the text of the label or null
 */
public String getText() {
	//checkWidget();
	return text;
}
@Override
public String getToolTipText () {
	checkWidget();
	return appToolTipText;
}
/**
 * Return the CLabel's top margin.
 *
 * @return the top margin of the label
 *
 * @since 3.6
 */
public int getTopMargin() {
	//checkWidget();
	return topMargin;
}
private void initAccessible() {
	Accessible accessible = getAccessible();
	accessible.addAccessibleListener(new AccessibleAdapter() {
		@Override
		public void getName(AccessibleEvent e) {
			e.result = getText();
		}

		@Override
		public void getHelp(AccessibleEvent e) {
			e.result = getToolTipText();
		}

		@Override
		public void getKeyboardShortcut(AccessibleEvent e) {
			char mnemonic = _findMnemonic(CLabel.this.text);
			if (mnemonic != '\0') {
				e.result = "Alt+"+mnemonic; //$NON-NLS-1$
			}
		}
	});

	accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
		@Override
		public void getChildAtPoint(AccessibleControlEvent e) {
			e.childID = ACC.CHILDID_SELF;
		}

		@Override
		public void getLocation(AccessibleControlEvent e) {
			Rectangle rect = getDisplay().map(getParent(), null, getBounds());
			e.x = rect.x;
			e.y = rect.y;
			e.width = rect.width;
			e.height = rect.height;
		}

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

		@Override
		public void getRole(AccessibleControlEvent e) {
			e.detail = ACC.ROLE_LABEL;
		}

		@Override
		public void getState(AccessibleControlEvent e) {
			e.detail = ACC.STATE_READONLY;
		}
	});
}
void onDispose(Event event) {
	/* make this handler run after other dispose listeners */
	if (ignoreDispose) {
		ignoreDispose = false;
		return;
	}
	ignoreDispose = true;
	notifyListeners (event.type, event);
	event.type = SWT.NONE;

	gradientColors = null;
	gradientPercents = null;
	backgroundImage = null;
	text = null;
	image = null;
	appToolTipText = null;
}
void onMnemonic(TraverseEvent event) {
	char mnemonic = _findMnemonic(text);
	if (mnemonic == '\0') return;
	if (Character.toLowerCase(event.character) != mnemonic) return;
	Composite control = this.getParent();
	while (control != null) {
		Control [] children = control.getChildren();
		int index = 0;
		while (index < children.length) {
			if (children [index] == this) break;
			index++;
		}
		index++;
		if (index < children.length) {
			if (children [index].setFocus ()) {
				event.doit = true;
				event.detail = SWT.TRAVERSE_NONE;
			}
		}
		control = control.getParent();
	}
}

void onPaint(PaintEvent event) {
	Rectangle rect = getClientArea();
	if (rect.width == 0 || rect.height == 0) return;

	boolean shortenText = false;
	String t = text;
	Image img = image;
	int availableWidth = Math.max(0, rect.width - (leftMargin + rightMargin));
	Point extent = getTotalSize(img, t);
	if (extent.x > availableWidth) {
		img = null;
		extent = getTotalSize(img, t);
		if (extent.x > availableWidth) {
			shortenText = true;
		}
	}

	GC gc = event.gc;
	String[] lines = text == null ? null : splitString(text);

	// shorten the text
	if (shortenText) {
		extent.x = 0;
	    for(int i = 0; i < lines.length; i++) {
	    	Point e = gc.textExtent(lines[i], DRAW_FLAGS);
	    	if (e.x > availableWidth) {
	    		lines[i] = shortenText(gc, lines[i], availableWidth);
	    		extent.x = Math.max(extent.x, getTotalSize(null, lines[i]).x);
	    	} else {
	    		extent.x = Math.max(extent.x, e.x);
	    	}
	    }
		if (appToolTipText == null) {
			super.setToolTipText(text);
		}
	} else {
		super.setToolTipText(appToolTipText);
	}

	// determine horizontal position
	int x = rect.x + leftMargin;
	if (align == SWT.CENTER) {
		x = (rect.width - extent.x)/2;
	}
	if (align == SWT.RIGHT) {
		x = rect.width - rightMargin - extent.x;
	}

	// draw a background image behind the text
	try {
		if (backgroundImage != null) {
			// draw a background image behind the text
			Rectangle imageRect = backgroundImage.getBounds();
			// tile image to fill space
			gc.setBackground(getBackground());
			gc.fillRectangle(rect);
			int xPos = 0;
			while (xPos < rect.width) {
				int yPos = 0;
				while (yPos < rect.height) {
					gc.drawImage(backgroundImage, xPos, yPos);
					yPos += imageRect.height;
				}
				xPos += imageRect.width;
			}
		} else if (gradientColors != null) {
			// draw a gradient behind the text
			final Color oldBackground = gc.getBackground();
			if (gradientColors.length == 1) {
				if (gradientColors[0] != null) gc.setBackground(gradientColors[0]);
				gc.fillRectangle(0, 0, rect.width, rect.height);
			} else {
				final Color oldForeground = gc.getForeground();
				Color lastColor = gradientColors[0];
				if (lastColor == null) lastColor = oldBackground;
				int pos = 0;
				for (int i = 0; i < gradientPercents.length; ++i) {
					gc.setForeground(lastColor);
					lastColor = gradientColors[i + 1];
					if (lastColor == null) lastColor = oldBackground;
					gc.setBackground(lastColor);
					if (gradientVertical) {
						final int gradientHeight = (gradientPercents[i] * rect.height / 100) - pos;
						gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, true);
						pos += gradientHeight;
					} else {
						final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
						gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false);
						pos += gradientWidth;
					}
				}
				if (gradientVertical && pos < rect.height) {
					gc.setBackground(getBackground());
					gc.fillRectangle(0, pos, rect.width, rect.height - pos);
				}
				if (!gradientVertical && pos < rect.width) {
					gc.setBackground(getBackground());
					gc.fillRectangle(pos, 0, rect.width - pos, rect.height);
				}
				gc.setForeground(oldForeground);
			}
			gc.setBackground(oldBackground);
		} else {
			if ((background != null || (getStyle() & SWT.DOUBLE_BUFFERED) == 0) && background.getAlpha() > 0) {
				gc.setBackground(getBackground());
				gc.fillRectangle(rect);
			}
		}
	} catch (SWTException e) {
		if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0) {
			gc.setBackground(getBackground());
			gc.fillRectangle(rect);
		}
	}

	// draw border
	int style = getStyle();
	if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0) {
		paintBorder(gc, rect);
	}

	/*
	 * Compute text height and image height. If image height is more than
	 * the text height, draw image starting from top margin. Else draw text
	 * starting from top margin.
	 */
	Rectangle imageRect = null;
	int lineHeight = 0, textHeight = 0, imageHeight = 0;

	if (img != null) {
	    imageRect = img.getBounds();
	    imageHeight = imageRect.height;
	}
	if (lines != null) {
	    lineHeight = gc.getFontMetrics().getHeight();
	    textHeight = lines.length * lineHeight;
	}

	int imageY = 0, midPoint = 0, lineY = 0;
	if (imageHeight > textHeight ) {
	    if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) imageY = rect.y + (rect.height - imageHeight) / 2;
	    else imageY = topMargin;
	    midPoint = imageY + imageHeight/2;
	    lineY = midPoint - textHeight / 2;
	}
	else {
	    if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) lineY = rect.y + (rect.height - textHeight) / 2;
	    else lineY = topMargin;
	    midPoint = lineY + textHeight/2;
	    imageY = midPoint - imageHeight / 2;
	}

	// draw the image
	if (img != null) {
		gc.drawImage(img, 0, 0, imageRect.width, imageHeight,
		                x, imageY, imageRect.width, imageHeight);
		x +=  imageRect.width + GAP;
		extent.x -= imageRect.width + GAP;
	}

	// draw the text
	if (lines != null) {
		gc.setForeground(getForeground());
		for (int i = 0; i < lines.length; i++) {
			int lineX = x;
			if (lines.length > 1) {
				if (align == SWT.CENTER) {
					int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
					lineX = x + Math.max(0, (extent.x - lineWidth) / 2);
				}
				if (align == SWT.RIGHT) {
					int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
					lineX = Math.max(x, rect.x + rect.width - rightMargin - lineWidth);
				}
			}
			gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
			lineY += lineHeight;
		}
	}
}
/**
 * Paint the Label's border.
 */
private void paintBorder(GC gc, Rectangle r) {
	Display disp= getDisplay();

	Color c1 = null;
	Color c2 = null;

	int style = getStyle();
	if ((style & SWT.SHADOW_IN) != 0) {
		c1 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
		c2 = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
	}
	if ((style & SWT.SHADOW_OUT) != 0) {
		c1 = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
		c2 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
	}

	if (c1 != null && c2 != null) {
		gc.setLineWidth(1);
		drawBevelRect(gc, r.x, r.y, r.width-1, r.height-1, c1, c2);
	}
}
/**
 * Set the horizontal alignment of the CLabel.
 * Use the values LEFT, CENTER and RIGHT to align image and text within the available space.
 *
 * @param align the alignment style of LEFT, RIGHT or CENTER
 *
 * @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 value of align is not one of SWT.LEFT, SWT.RIGHT or SWT.CENTER</li>
 * </ul>
 */
public void setAlignment(int align) {
	checkWidget();
	if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.align != align) {
		this.align = align;
		redraw();
	}
}

@Override
public void setBackground (Color color) {
	super.setBackground (color);
	// Are these settings the same as before?
	if (backgroundImage == null &&
		gradientColors == null &&
		gradientPercents == null) {
		if (color == null) {
			if (background == null) return;
		} else {
			if (color.equals(background)) return;
		}
	}
	background = color;
	backgroundImage = null;
	gradientColors = null;
	gradientPercents = null;
	redraw ();
}

/**
 * Specify a gradient of colours to be drawn in the background of the CLabel.
 * <p>For example, to draw a gradient that varies from dark blue to blue and then to
 * white and stays white for the right half of the label, use the following call
 * to setBackground:</p>
 * <pre>
 *	clabel.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 from 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_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 values of colors and percents are not consistent</li>
 * </ul>
 */
public void setBackground(Color[] colors, int[] percents) {
	setBackground(colors, percents, false);
}
/**
 * Specify a gradient of colours to be drawn in the background of the CLabel.
 * <p>For example, to draw a gradient that varies from dark blue to white in the vertical,
 * direction use the following call
 * to setBackground:</p>
 * <pre>
 *	clabel.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
 *		                           display.getSystemColor(SWT.COLOR_WHITE)},
 *		                 new int[] {100}, true);
 * </pre>
 *
 * @param colors an array of Color that specifies the colors to appear in the gradient
 *               in order of appearance from left/top to right/bottom;  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/height
 *                 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_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 values of colors and percents are not consistent</li>
 * </ul>
 *
 * @since 3.0
 */
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);
		}
		if (getDisplay().getDepth() < 15) {
			// Don't use gradients on low color displays
			colors = new Color[] {colors[colors.length - 1]};
			percents = new int[] { };
		}
		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);
			}
		}
	}

	// Are these settings the same as before?
	final Color background = getBackground();
	if (backgroundImage == null) {
		if ((gradientColors != null) && (colors != null) &&
			(gradientColors.length == colors.length)) {
			boolean same = false;
			for (int i = 0; i < gradientColors.length; i++) {
				same = (gradientColors[i] == colors[i]) ||
					((gradientColors[i] == null) && (colors[i] == background)) ||
					((gradientColors[i] == background) && (colors[i] == null));
				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;
		}
	} else {
		backgroundImage = null;
	}
	// Store the new settings
	if (colors == null) {
		gradientColors = null;
		gradientPercents = null;
		gradientVertical = false;
	} else {
		gradientColors = new Color[colors.length];
		for (int i = 0; i < colors.length; ++i)
			gradientColors[i] = (colors[i] != null) ? colors[i] : background;
		gradientPercents = new int[percents.length];
		for (int i = 0; i < percents.length; ++i)
			gradientPercents[i] = percents[i];
		gradientVertical = vertical;
	}
	// Refresh with the new settings
	redraw();
}
/**
 * Set the image to be drawn in the background of the label.
 *
 * @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 setBackground(Image image) {
	checkWidget();
	if (image == backgroundImage) return;
	if (image != null) {
		gradientColors = null;
		gradientPercents = null;
	}
	backgroundImage = image;
	redraw();

}
/**
 * Set the label's bottom margin, in pixels.
 *
 * @param bottomMargin the bottom margin of the label, which must be equal to or greater than zero
 *
 * @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.6
 */
public void setBottomMargin(int bottomMargin) {
    checkWidget();
    if (this.bottomMargin == bottomMargin || bottomMargin < 0) return;
    this.bottomMargin = bottomMargin;
    redraw();
}
@Override
public void setFont(Font font) {
	super.setFont(font);
	redraw();
}
/**
 * Set the label's Image.
 * The value <code>null</code> clears it.
 *
 * @param image the image to be displayed in the label or null
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setImage(Image image) {
	checkWidget();
	if (image != this.image) {
		this.image = image;
		redraw();
	}
}
/**
 * Set the label's horizontal left margin, in pixels.
 *
 * @param leftMargin the left margin of the label, which must be equal to or greater than zero
 *
 * @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.6
 */
public void setLeftMargin(int leftMargin) {
    checkWidget();
    if (this.leftMargin == leftMargin || leftMargin < 0) return;
    this.leftMargin = leftMargin;
    redraw();
}
/**
 * Set the label's margins, in pixels.
 *
 * @param leftMargin the left margin.
 * @param topMargin the top margin.
 * @param rightMargin the right margin.
 * @param bottomMargin the bottom margin.
 * @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.6
 */
public void setMargins (int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
	checkWidget();
	this.leftMargin = Math.max(0, leftMargin);
	this.topMargin = Math.max(0, topMargin);
	this.rightMargin = Math.max(0, rightMargin);
	this.bottomMargin = Math.max(0, bottomMargin);
	redraw();
}
/**
 * Set the label's right margin, in pixels.
 *
 * @param rightMargin the right margin of the label, which must be equal to or greater than zero
 *
 * @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.6
 */
public void setRightMargin(int rightMargin) {
    checkWidget();
    if (this.rightMargin == rightMargin || rightMargin < 0) return;
    this.rightMargin = rightMargin;
    redraw();
}
/**
 * Set the label's text.
 * The value <code>null</code> clears it.
 * <p>
 * Mnemonics are indicated by an '&amp;' that causes the next
 * character to be the mnemonic.  When the user presses a
 * key sequence that matches the mnemonic, focus is assigned
 * to the control that follows the label. On most platforms,
 * the mnemonic appears underlined but may be emphasised in a
 * platform specific manner.  The mnemonic indicator character
 * '&amp;' can be escaped by doubling it in the string, causing
 * a single '&amp;' to be displayed.
 * </p><p>
 * Note: If control characters like '\n', '\t' etc. are used
 * in the string, then the behavior is platform dependent.
 * </p>
 *
 * @param text the text to be displayed in the label or null
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setText(String text) {
	checkWidget();
	if (text == null) text = ""; //$NON-NLS-1$
	if (! text.equals(this.text)) {
		this.text = text;
		redraw();
	}
}
@Override
public void setToolTipText (String string) {
	super.setToolTipText (string);
	appToolTipText = super.getToolTipText();
}
/**
 * Set the label's top margin, in pixels.
 *
 * @param topMargin the top margin of the label, which must be equal to or greater than zero
 *
 * @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.6
 */
public void setTopMargin(int topMargin) {
    checkWidget();
    if (this.topMargin == topMargin || topMargin < 0) return;
    this.topMargin = topMargin;
    redraw();
}
/**
 * Shorten the given text <code>t</code> so that its length doesn't exceed
 * the given width. The default implementation replaces characters in the
 * center of the original string with an ellipsis ("...").
 * Override if you need a different strategy.
 *
 * @param gc the gc to use for text measurement
 * @param t the text to shorten
 * @param width the width to shorten the text to, in pixels
 * @return the shortened text
 */
protected String shortenText(GC gc, String t, int width) {
	if (t == null) return null;
	int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x;
	if (width<=w) return t;
	int l = t.length();
	int max = l/2;
	int min = 0;
	int mid = (max+min)/2 - 1;
	if (mid <= 0) return t;
	TextLayout layout = new TextLayout (getDisplay());
	layout.setText(t);
	mid = validateOffset(layout, mid);
	while (min < mid && mid < max) {
		String s1 = t.substring(0, mid);
		String s2 = t.substring(validateOffset(layout, l-mid), l);
		int l1 = gc.textExtent(s1, DRAW_FLAGS).x;
		int l2 = gc.textExtent(s2, DRAW_FLAGS).x;
		if (l1+w+l2 > width) {
			max = mid;
			mid = validateOffset(layout, (max+min)/2);
		} else if (l1+w+l2 < width) {
			min = mid;
			mid = validateOffset(layout, (max+min)/2);
		} else {
			min = max;
		}
	}
	String result = mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l-mid), l);
	layout.dispose();
 	return result;
}
int validateOffset(TextLayout layout, int offset) {
	int nextOffset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER);
	if (nextOffset != offset) return layout.getPreviousOffset(nextOffset, SWT.MOVEMENT_CLUSTER);
	return offset;
}
private String[] splitString(String text) {
    String[] lines = new String[1];
    int start = 0, pos;
    do {
        pos = text.indexOf('\n', start);
        if (pos == -1) {
        	lines[lines.length - 1] = text.substring(start);
        } else {
            boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r');
            lines[lines.length - 1] = text.substring(start, pos - (crlf ? 1 : 0));
            start = pos + 1;
            String[] newLines = new String[lines.length+1];
            System.arraycopy(lines, 0, newLines, 0, lines.length);
       		lines = newLines;
        }
    } while (pos != -1);
    return lines;
}
}
