package org.eclipse.swt.widgets;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

/**
 * Instances of this class represent a non-selectable
 * user interface object that displays a string or image.
 * When SEPARATOR is specified, displays a single
 * vertical or horizontal line.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SEPARATOR, HORIZONTAL, SHADOW_IN, SHADOW_OUT, VERTICAL</dd>
 * <dd>CENTER, LEFT, RIGHT, WRAP</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is intended to be subclassed <em>only</em>
 * within the SWT implementation.
 * </p>
 */
public class Label extends Control {
	Image image;
	int font;
	static final int LabelProc;
	static final TCHAR LabelClass = new TCHAR (0, "STATIC", true);
	static {
		WNDCLASS lpWndClass = new WNDCLASS ();
		OS.GetClassInfo (0, LabelClass, lpWndClass);
		LabelProc = lpWndClass.lpfnWndProc;
	}

/**
 * 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
 * for all SWT widget classes should include a comment which
 * describes the style constants which are applicable to the class.
 * </p>
 *
 * @param parent a composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Label (Composite parent, int style) {
	super (parent, checkStyle (style));
}

int callWindowProc (int msg, int wParam, int lParam) {
	if (handle == 0) return 0;
	return OS.CallWindowProc (LabelProc, handle, msg, wParam, lParam);
}

static int checkStyle (int style) {
	if ((style & SWT.SEPARATOR) != 0) return style;
	return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
}

public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	int width = 0, height = 0;
	int border = getBorderWidth ();
	if ((style & SWT.SEPARATOR) != 0) {
		int lineWidth = OS.GetSystemMetrics (OS.SM_CXBORDER);
		if ((style & SWT.HORIZONTAL) != 0) {
			width = DEFAULT_WIDTH;  height = lineWidth * 2;
		} else {
			width = lineWidth * 2; height = DEFAULT_HEIGHT;
		}
		if (wHint != SWT.DEFAULT) width = wHint;
		if (hHint != SWT.DEFAULT) height = hHint;
		width += border * 2; height += border * 2;
		return new Point (width, height);
	}
	/*
	* NOTE: SS_BITMAP and SS_ICON are not single bit
	* masks so it is necessary to test for all of the
	* bits in these masks.
	*/
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	boolean isBitmap = (bits & OS.SS_BITMAP) == OS.SS_BITMAP;
	boolean isIcon = (bits & OS.SS_ICON) == OS.SS_ICON;
	if (isBitmap || isIcon) {
		if (image != null) {
			Rectangle rect = image.getBounds();
			width = rect.width;
			height = rect.height;
		}
	} else {
		int hDC = OS.GetDC (handle);
		int newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
		int oldFont = OS.SelectObject (hDC, newFont);
		RECT rect = new RECT ();
		int flags = OS.DT_CALCRECT;
		if ((style & SWT.WRAP) != 0 && wHint != SWT.DEFAULT) {
			flags |= OS.DT_WORDBREAK;
			rect.right = wHint;
		}
		int length = OS.GetWindowTextLength (handle);
		TCHAR buffer = new TCHAR (getCodePage (), length + 1);
		OS.GetWindowText (handle, buffer, length + 1);
		OS.DrawText (hDC, buffer, length, rect, flags);
		width = rect.right - rect.left;
		height = rect.bottom - rect.top;
		if (height == 0) {
			TEXTMETRIC tm = new TEXTMETRIC ();
			OS.GetTextMetrics (hDC, tm);
			height = tm.tmHeight;
		}
		if (newFont != 0) OS.SelectObject (hDC, oldFont);
		OS.ReleaseDC (handle, hDC);
	}
	if (wHint != SWT.DEFAULT) width = wHint;
	if (hHint != SWT.DEFAULT) height = hHint;
	width += border * 2; height += border * 2;
	/* 
	* Feature in WinCE PPC.  Text labels have a trim
	* of one pixel wide on the right and left side.
	* The fix is to increase the size.
	*/
	if (OS.IsWinCE) {
		if (!isBitmap && !isIcon) width += 2;
	}
	return new Point (width, height);
}

/**
 * Returns a value which describes the position of the
 * text or image in the receiver. The value will be one of
 * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>
 * unless the receiver is a <code>SEPARATOR</code> label, in 
 * which case, <code>NONE</code> is returned.
 *
 * @return the alignment 
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getAlignment () {
	checkWidget ();
	if ((style & SWT.SEPARATOR) != 0) return 0;
	if ((style & SWT.LEFT) != 0) return SWT.LEFT;
	if ((style & SWT.CENTER) != 0) return SWT.CENTER;
	if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
	return SWT.LEFT;
}

/**
 * Returns the receiver's image if it has one, or null
 * if it does not.
 *
 * @return the receiver's image
 *
 * @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 Image getImage () {
	checkWidget ();
	return image;
}

String getNameText () {
	return getText ();
}

/**
 * Returns the receiver's text, which will be an empty
 * string if it has never been set or if the receiver is
 * a <code>SEPARATOR</code> label.
 *
 * @return the receiver's text
 *
 * @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 String getText () {
	checkWidget ();
	if ((style & SWT.SEPARATOR) != 0) return "";
	int length = OS.GetWindowTextLength (handle);
	if (length == 0) return "";
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
	OS.GetWindowText (handle, buffer, length + 1);
	return buffer.toString (0, length);
}

/*
* Not currently used.
*/
boolean getWrap () {
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	if ((bits & (OS.SS_RIGHT | OS.SS_CENTER)) != 0) return true;
	if ((bits & OS.SS_LEFTNOWORDWRAP) != 0) return false;
	return true;
}

boolean mnemonicHit (char key) {
	Composite control = this.parent;
	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 ()) return true;
		}
		control = control.parent;
	}
	return false;
}

boolean mnemonicMatch (char key) {
	char mnemonic = findMnemonic (getText ());
	if (mnemonic == '\0') return false;
	return Character.toUpperCase (key) == Character.toUpperCase (mnemonic);
}

void releaseWidget () {
	super.releaseWidget ();
	image = null;
}

/**
 * Controls how text and images will be displayed in the receiver.
 * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
 * or <code>CENTER</code>.  If the receiver is a <code>SEPARATOR</code>
 * label, the argument is ignored and the alignment is not changed.
 *
 * @param alignment the new alignment 
 *
 * @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 setAlignment (int alignment) {
	checkWidget ();
	if ((style & SWT.SEPARATOR) != 0) return;
	if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
	style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
	style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	/*
	* Feature in Windows.  The windows label does not align
	* the bitmap or icon.  Any attempt to set alignment bits
	* such as SS_CENTER cause the label to display text.  The
	* fix is to disallow alignment.
	*
	* NOTE: SS_BITMAP and SS_ICON are not single bit
	* masks so it is necessary to test for all of the
	* bits in these masks.
	*/
	if ((bits & OS.SS_BITMAP) == OS.SS_BITMAP) return;
	if ((bits & OS.SS_ICON) == OS.SS_ICON) return;
	bits &= ~(OS.SS_LEFTNOWORDWRAP | OS.SS_CENTER | OS.SS_RIGHT);
	if ((style & SWT.LEFT) != 0 && (style & SWT.WRAP) == 0) {
		bits |= OS.SS_LEFTNOWORDWRAP;
	}
	if ((style & SWT.CENTER) != 0) bits |= OS.SS_CENTER;
	if ((style & SWT.RIGHT) != 0) bits |= OS.SS_RIGHT;
	OS.SetWindowLong (handle, OS.GWL_STYLE, bits);
	OS.InvalidateRect (handle, null, true);
}

public boolean setFocus () {
	checkWidget();
	return false;
}

/**
 * Sets the receiver's image to the argument, which may be
 * null indicating that no image should be displayed.
 *
 * @param image the image to display on the receiver (may be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the image 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>
 */
public void setImage (Image image) {
	checkWidget ();
	if ((style & SWT.SEPARATOR) != 0) return;
	int hImage = 0, imageBits = 0, fImageType = 0;
	if (image != null) {
		if (image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
		hImage = image.handle;
		switch (image.type) {
			case SWT.BITMAP:
				imageBits = OS.SS_BITMAP;
				fImageType = OS.IMAGE_BITMAP;
				break;
			case SWT.ICON:
				imageBits = OS.SS_ICON;
				fImageType = OS.IMAGE_ICON;
				break;
			default:
				return;
		}
	}
	this.image = image;
	RECT rect = new RECT ();
	OS.GetWindowRect (handle, rect);
	int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	int oldBits = newBits;
	newBits &= ~(OS.SS_BITMAP | OS.SS_ICON);
	newBits |= imageBits | OS.SS_REALSIZEIMAGE | OS.SS_CENTERIMAGE;
	if (newBits != oldBits) {
		OS.SetWindowLong (handle, OS.GWL_STYLE, newBits);
	}
	OS.SendMessage (handle, OS.STM_SETIMAGE, fImageType, hImage);
	/*
	* Feature in Windows.  When STM_SETIMAGE is used to set the
	* image for a static control, Windows either streches the image
	* to fit the control or shrinks the control to fit the image.
	* While not stricly wrong, neither of these is desirable.
	* The fix is to stop Windows from stretching the image by
	* using SS_REALSIZEIMAGE and SS_CENTERIMAGE, allow Windows
	* to shrink the control, and then restore the control to the
	* original size.
	*/
	int flags = OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE | OS.SWP_NOMOVE;
	OS.SetWindowPos (handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags);
	OS.InvalidateRect (handle, null, true);
}

/**
 * Sets the receiver's text.
 * <p>
 * This method sets the widget label.  The label may include
 * the mnemonic characters and line delimiters.
 * </p>
 * 
 * @param string the new text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the text 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>
 */
public void setText (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	if ((style & SWT.SEPARATOR) != 0) return;
	int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE), oldBits = newBits;
	newBits &= ~(OS.SS_BITMAP | OS.SS_ICON | OS.SS_REALSIZEIMAGE | OS.SS_CENTERIMAGE);
	if ((style & SWT.LEFT) != 0 && (style & SWT.WRAP) == 0) newBits |= OS.SS_LEFTNOWORDWRAP;
	if ((style & SWT.CENTER) != 0) newBits |= OS.SS_CENTER;
	if ((style & SWT.RIGHT) != 0) newBits |= OS.SS_RIGHT;
	if (newBits != oldBits) {
		/*
		* Bug in Windows.  When the style of a label is SS_BITMAP
		* or SS_ICON, the label does not remember the font that is
		* set in WM_SETFONT.  The fix is to remember the font and
		* return the font in WM_GETFONT and to reset the font when
		* the style is changed from SS_BITMAP or SS_ICON to a style
		* that displays text.
		*/
		int hFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
		OS.SetWindowLong (handle, OS.GWL_STYLE, newBits);
		if (hFont != 0) OS.SendMessage (handle, OS.WM_SETFONT, hFont, 0);
	}
	string = Display.withCrLf (string);
	TCHAR buffer = new TCHAR (getCodePage (), string, true);
	OS.SetWindowText (handle, buffer);
}

/*
* Not currently used.
*/
void setWrap (boolean wrap) {
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	if ((bits & (OS.SS_RIGHT | OS.SS_CENTER)) != 0) return;
	bits &= ~OS.SS_LEFTNOWORDWRAP;
	if (!wrap) bits |= OS.SS_LEFTNOWORDWRAP;
	OS.SetWindowLong (handle, OS.GWL_STYLE, bits);
	OS.InvalidateRect (handle, null, true);
}

int widgetExtStyle () {
	if ((style & SWT.BORDER) != 0) return OS.WS_EX_STATICEDGE;
	return super.widgetExtStyle ();
}

int widgetStyle () {
	int bits = super.widgetStyle () | OS.SS_NOTIFY;
	if ((style & SWT.SEPARATOR) != 0) return bits | OS.SS_OWNERDRAW;
	if ((style & SWT.CENTER) != 0) return bits | OS.SS_CENTER;
	if ((style & SWT.RIGHT) != 0) return bits | OS.SS_RIGHT;
	if ((style & SWT.WRAP) != 0) return bits | OS.SS_LEFT;
	return bits | OS.SS_LEFTNOWORDWRAP;
}

TCHAR windowClass () {
	return LabelClass;
}

int windowProc () {
	return LabelProc;
}

LRESULT WM_ERASEBKGND (int wParam, int lParam) {
	LRESULT result = super.WM_ERASEBKGND (wParam, lParam);
	if (result != null) return result;
	if ((style & SWT.SEPARATOR) == 0) {
		/*
		* Bug in Windows.  When a label has the SS_BITMAP
		* or SS_ICON style, the label does not draw the
		* background.  The fix is to draw the background
		* when the label is showing a bitmap or icon.
		*
		* NOTE: SS_BITMAP and SS_ICON are not single bit
		* masks so it is necessary to test for all of the
		* bits in these masks.
		*/
		int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
		if ((bits & OS.SS_BITMAP) != OS.SS_BITMAP &&
			(bits & OS.SS_ICON) != OS.SS_ICON) return result;
	}
	drawBackground (wParam);
	return LRESULT.ONE;
}

LRESULT WM_GETFONT (int wParam, int lParam) {
	LRESULT result = super.WM_GETFONT (wParam, lParam);
	if (result != null) return result;
	/*
	* Bug in Windows.  When the style of a label is SS_BITMAP
	* or SS_ICON, the label does not remember the font that is
	* set in WM_SETFONT.  The fix is to remember the font and
	* return the font in WM_GETFONT.
	*/
	if (font == 0) font = defaultFont ();
	return new LRESULT (font);
}

LRESULT WM_SETFONT (int wParam, int lParam) {
	/*
	* Bug in Windows.  When the style of a label is SS_BITMAP
	* or SS_ICON, the label does not remember the font that is
	* set in WM_SETFONT.  The fix is to remember the font and
	* return the font in WM_GETFONT.
	*/
	return super.WM_SETFONT (font = wParam, lParam);
}

LRESULT WM_SIZE (int wParam, int lParam) {
	LRESULT result = super.WM_SIZE (wParam, lParam);
	/*
	* It is possible (but unlikely), that application
	* code could have disposed the widget in the resize
	* event.  If this happens, end the processing of the
	* Windows message by returning the result of the
	* WM_SIZE message.
	*/
	if (isDisposed ()) return result;
	
	/*
	* Bug in Windows.  For some reason, a label with
	* style SS_LEFT, SS_CENTER or SS_RIGHT does not
	* redraw the text in the new position when resized.
	* Note that SS_LEFTNOWORDWRAP does no have the problem.
	* The fix is to force the redraw.
	*/
	if ((style & SWT.SEPARATOR) == 0) {
		if ((style & (SWT.WRAP | SWT.CENTER | SWT.RIGHT)) != 0) {
			OS.InvalidateRect (handle, null, true);
		}
	}
	return result;
}

LRESULT wmDrawChild (int wParam, int lParam) {
	if ((style & SWT.SHADOW_NONE) != 0) return null;
	DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT ();
	OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof);
	RECT rect = new RECT ();
	int lineWidth = OS.GetSystemMetrics (OS.SM_CXBORDER);
	int flags = OS.EDGE_ETCHED;
	if ((style & SWT.SHADOW_IN) != 0) flags = OS.EDGE_SUNKEN;
	if ((style & SWT.HORIZONTAL) != 0) {
		int bottom = struct.top + Math.max (lineWidth * 2, (struct.bottom - struct.top) / 2);
		OS.SetRect (rect, struct.left, struct.top, struct.right, bottom);
		OS.DrawEdge (struct.hDC, rect, flags, OS.BF_BOTTOM);
		return null;
	}
	int right = struct.left + Math.max (lineWidth * 2, (struct.right - struct.left) / 2);
	OS.SetRect (rect, struct.left, struct.top, right, struct.bottom);
	OS.DrawEdge (struct.hDC, rect, flags, OS.BF_RIGHT);
	return null;
}

}
