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 are controls which are capable
 * of containing other controls.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS, NO_REDRAW_RESIZE</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * This class may be subclassed by custom control implementors
 * who are building controls that are constructed from aggregates
 * of other controls.
 * </p>
 *
 * @see Canvas
 */

public class Composite extends Scrollable {
	
	Layout layout;
	int font, hdwp;
	
/**
 * Prevents uninitialized instances from being created outside the package.
 */
Composite () {
}

/**
 * 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 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>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Composite (Composite parent, int style) {
	super (parent, style);
}
Control [] _getChildren () {
	int count = 0;
	int hwndChild = OS.GetWindow (handle, OS.GW_CHILD);
	if (hwndChild == 0) return new Control [0];
	while (hwndChild != 0) {
		count++;
		hwndChild = OS.GetWindow (hwndChild, OS.GW_HWNDNEXT);
	}
	Control [] children = new Control [count];
	int index = 0;
	hwndChild = OS.GetWindow (handle, OS.GW_CHILD);
	while (hwndChild != 0) {
		Control control = WidgetTable.get (hwndChild);
		if (control != null && control != this) {
			children [index++] = control;
		}
		hwndChild = OS.GetWindow (hwndChild, OS.GW_HWNDNEXT);
	}
	if (count == index) return children;
	Control [] newChildren = new Control [index];
	System.arraycopy (children, 0, newChildren, 0, index);
	return newChildren;
}

protected void checkSubclass () {
	/* Do nothing - Subclassing is allowed */
}

public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	Point size;
	if (layout != null) {
		if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
			size = layout.computeSize (this, wHint, hHint, changed);
		} else {
			size = new Point (wHint, hHint);
		}
	} else {
		size = minimumSize ();
	}
	if (size.x == 0) size.x = DEFAULT_WIDTH;
	if (size.y == 0) size.y = DEFAULT_HEIGHT;
	if (wHint != SWT.DEFAULT) size.x = wHint;
	if (hHint != SWT.DEFAULT) size.y = hHint;
	Rectangle trim = computeTrim (0, 0, size.x, size.y);
	return new Point (trim.width, trim.height);
}

void createHandle () {
	super.createHandle ();
	state |= CANVAS;
}
void drawBackground (int hdc, RECT rect) {
	if ((state & CANVAS) != 0) {
		if ((style & SWT.NO_BACKGROUND) != 0) return;
	}
	int pixel = getBackgroundPixel ();
	int hBrush = findBrush (pixel);
	OS.FillRect (hdc, rect, hBrush);
}

/**
 * Returns an array containing the receiver's children.
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of children, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return an array of children
 *
 * @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 Control [] getChildren () {
	checkWidget ();
	return _getChildren ();
}

int getChildrenCount () {
	/*
	* NOTE: The current implementation will count
	* non-registered children.
	*/
	int count = 0;
	int hwndChild = OS.GetWindow (handle, OS.GW_CHILD);
	while (hwndChild != 0) {
		count++;
		hwndChild = OS.GetWindow (hwndChild, OS.GW_HWNDNEXT);
	}
	return count;
}

/**
 * Returns layout which is associated with the receiver, or
 * null if one has not been set.
 *
 * @return the receiver's 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>
 */
public Layout getLayout () {
	checkWidget ();
	return layout;
}

Control [] getTabList () {
	Control result [] = super.getTabList ();
	Control [] children = _getChildren ();
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		Control [] list = child.getTabList ();
		if (list.length != 0) {
			Control [] newResult = new Control [result.length + list.length];
			System.arraycopy (result, 0, newResult, 0, result.length);
			System.arraycopy (list, 0, newResult, result.length, list.length);
			result = newResult;
		}
	}
	return result;
}

/**
 * If the receiver has a layout, asks the layout to <em>lay out</em>
 * (that is, set the size and location of) the receiver's children. 
 * If the receiver does not have a layout, do nothing.
 * <p>
 * This is equivalent to calling <code>layout(true)</code>.
 * </p>
 *
 * @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 layout () {
	checkWidget ();
	layout (true);
}

/**
 * If the receiver has a layout, asks the layout to <em>lay out</em>
 * (that is, set the size and location of) the receiver's children. 
 * If the the argument is <code>true</code> the layout must not rely
 * on any cached information it is keeping about the children. If it
 * is <code>false</code> the layout may (potentially) simplify the
 * work it is doing by assuming that the state of the none of the
 * receiver's children has changed since the last layout.
 * If the receiver does not have a layout, do nothing.
 *
 * @param changed <code>true</code> if the layout must flush its caches, and <code>false</code> 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>
 */
public void layout (boolean changed) {
	checkWidget ();
	if (layout == null) return;
	int count = getChildrenCount ();
	if (count == 0) return;
	if (count > 1 && hdwp == 0) {
		hdwp = OS.BeginDeferWindowPos (count);
	}
	layout.layout (this, changed);
	int oldHdwp = hdwp;
	hdwp = 0;
	if (oldHdwp != 0) OS.EndDeferWindowPos (oldHdwp);
}

Point minimumSize () {
	Control [] children = _getChildren ();
	int width = 0, height = 0;
	for (int i=0; i<children.length; i++) {
		Rectangle rect = children [i].getBounds ();
		width = Math.max (width, rect.x + rect.width);
		height = Math.max (height, rect.y + rect.height);
	}
	return new Point (width, height);
}

void releaseChildren () {
	Control [] children = _getChildren ();
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (!child.isDisposed ()) {
			child.releaseWidget ();
			child.releaseHandle ();
		}
	}
}

void releaseWidget () {
	releaseChildren ();
	super.releaseWidget ();
	layout = null;
	int oldHdwp = hdwp;
	hdwp = 0;
	if (oldHdwp != 0) OS.EndDeferWindowPos (oldHdwp);
}

public boolean setFocus () {
	checkWidget ();
	if ((state & CANVAS) != 0) {
		if ((style & SWT.NO_FOCUS) != 0) return false;
	}
	Control [] children = _getChildren ();
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.setRadioFocus ()) return true;
	}
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.setFocus ()) return true;
	}
	return super.setFocus ();
}

/**
 * Sets the layout which is associated with the receiver to be
 * the argument which may be null.
 *
 * @param 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>
 */
public void setLayout (Layout layout) {
	checkWidget ();
	this.layout = layout;
}

boolean setTabGroupFocus () {
	if (!isVisible ()) return false;
	if (isTabItem ()) return setTabItemFocus ();
	Control [] children = _getChildren ();
	if (children.length == 0) {
		return (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) && setTabItemFocus ();
	}
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.isVisible () && child.setRadioFocus ()) return true;
	}
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.isTabItem () && child.setTabItemFocus ()) return true;
	}
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.isTabGroup () && child.setTabGroupFocus ()) return true;
	}
	return false;
}

String toolTipText (NMTTDISPINFO hdr) {
	if ((hdr.uFlags & OS.TTF_IDISHWND) == 0) {
		return null;
	}
	int hwnd = hdr.idFrom;
	if (hwnd == 0) return null;
	Control control = WidgetTable.get (hwnd);
	if (control == null) return null;
	return control.toolTipText;
}

boolean traverseMnemonic (char key) {
	if (super.traverseMnemonic (key)) return true;
	Control [] children = _getChildren ();
	for (int i=0; i<children.length; i++) {
		Control child = children [i];
		if (child.traverseMnemonic (key)) return true;
	}
	return false;
}

int widgetStyle () {
	/* Temporary code to force SWT.CLIP_SIBLINGS */
	return super.widgetStyle () | OS.WS_CLIPCHILDREN;
}

LRESULT WM_ERASEBKGND (int wParam, int lParam) {
	if ((state & CANVAS) != 0) {
		return super.WM_ERASEBKGND (wParam, lParam);
	}
	RECT rect = new RECT ();
	OS.GetClientRect (handle, rect);
	drawBackground (wParam, rect);
	return LRESULT.ONE;
}

LRESULT WM_GETDLGCODE (int wParam, int lParam) {
	LRESULT result = super.WM_GETDLGCODE (wParam, lParam);
	if (result != null) return result;
	if ((state & CANVAS) != 0) {
		if ((style & SWT.NO_FOCUS) != 0) return new LRESULT (OS.DLGC_STATIC);
		if (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) {
			int flags = OS.DLGC_WANTALLKEYS | OS.DLGC_WANTARROWS | OS.DLGC_WANTTAB;
			return new LRESULT (flags);
		}
		int count = getChildrenCount ();
		if (count != 0) return new LRESULT (OS.DLGC_STATIC);
	}
	return result;
}

LRESULT WM_GETFONT (int wParam, int lParam) {
	LRESULT result = super.WM_GETFONT (wParam, lParam);
	if (result != null) return result;
	int code = callWindowProc (OS.WM_GETFONT, wParam, lParam);
	if (code != 0) return new LRESULT (code);
	if (font == 0) font = defaultFont ();
	return new LRESULT (font);
}

LRESULT WM_LBUTTONDOWN (int wParam, int lParam) {
	LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);

	/* Set focus for a canvas with no children */
	if ((state & CANVAS) != 0) {
		if ((style & SWT.NO_FOCUS) != 0) return result;
		if (OS.GetWindow (handle, OS.GW_CHILD) == 0) setFocus ();
	}
	return result;
}

LRESULT WM_NOTIFY (int wParam, int lParam) {
	NMHDR hdr = new NMHDR ();
	OS.MoveMemory (hdr, lParam, NMHDR.sizeof);
	switch (hdr.code) {
		case OS.TTN_GETDISPINFO:
			NMTTDISPINFO lpnmtdi = new NMTTDISPINFO ();
			OS.MoveMemory (lpnmtdi, lParam, NMTTDISPINFO.sizeof);
			String string = toolTipText (lpnmtdi);
			if (string != null && string.length () != 0) {
				string = Display.withCrLf (string);
				/* Use the character encoding for the default locale */
				byte [] buffer = Converter.wcsToMbcs (0, string, true);
				getShell ().setToolTipText (lpnmtdi, buffer);
				OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
			}
			return LRESULT.ZERO;
	}
	return super.WM_NOTIFY (wParam, lParam);
}

LRESULT WM_PAINT (int wParam, int lParam) {
	if ((state & CANVAS) == 0) {
		return super.WM_PAINT (wParam, lParam);
	}
	
	/*
	* This code is intentionally commented.  Don't exit
	* early because the background must still be painted,
	* even though no application code will be painting
	* the widget.
	*
	* Do not uncomment this code.
	*/
//	if (!hooks (SWT.Paint)) return null;

	/* Get the damage */
	int [] lpRgnData = null;
	boolean isComplex = false;
	boolean exposeRegion = false;
	if ((style & SWT.NO_MERGE_PAINTS) != 0) {
		int rgn = OS.CreateRectRgn (0, 0, 0, 0);
		isComplex = OS.GetUpdateRgn (handle, rgn, false) == OS.COMPLEXREGION;
		if (isComplex) {
			int nBytes = OS.GetRegionData (rgn, 0, null);
			lpRgnData = new int [nBytes / 4];
			exposeRegion = OS.GetRegionData (rgn, nBytes, lpRgnData) != 0;
		}
		OS.DeleteObject (rgn);
	}

	/* Set the clipping bits */
	int oldBits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	int newBits = oldBits | OS.WS_CLIPSIBLINGS | OS.WS_CLIPCHILDREN;
	OS.SetWindowLong (handle, OS.GWL_STYLE, newBits);

	/* Create the paint GC */
	PAINTSTRUCT ps = new PAINTSTRUCT ();
	GCData data = new GCData ();
	data.ps = ps;
	GC gc = GC.win32_new (this, data);
	int hDC = gc.handle;
	
	/* Send the paint event */
	Event event = new Event ();
	event.gc = gc;
	if (isComplex && exposeRegion) {
		RECT rect = new RECT ();
		int nCount = lpRgnData [2];
		for (int i=0; i<nCount; i++) {
			OS.SetRect (rect,
				lpRgnData [8 + (i << 2)],
				lpRgnData [8 + (i << 2) + 1],
				lpRgnData [8 + (i << 2) + 2],
				lpRgnData [8 + (i << 2) + 3]);
			drawBackground (hDC, rect);	
			event.x = rect.left;
			event.y = rect.top;
			event.width = rect.right - rect.left;
			event.height = rect.bottom - rect.top;
			event.count = nCount - 1 - i;
			/*
			* It is possible (but unlikely), that application
			* code could have disposed the widget in the paint
			* event.  If this happens, attempt to give back the
			* paint GC anyways because this is a scarce Windows
			* resource.
			*/
			sendEvent (SWT.Paint, event);
			if (isDisposed ()) break;
		}
	} else {
		RECT rect = new RECT ();
		OS.SetRect (rect, ps.left, ps.top, ps.right, ps.bottom);
		drawBackground (hDC, rect);
		event.x = ps.left;
		event.y = ps.top;
		event.width = ps.right - ps.left;
		event.height = ps.bottom - ps.top;
		sendEvent (SWT.Paint, event);
	}
	// widget could be disposed at this point

	/* Dispose the paint GC */
	event.gc = null;
	gc.dispose ();

	/*
	* It is possible (but unlikely), that application
	* code could have disposed the widget in the paint
	* event.  If this happens, don't attempt to restore
	* the style.
	*/
	if (!isDisposed ()) {
		OS.SetWindowLong (handle, OS.GWL_STYLE, oldBits);
	}
	return LRESULT.ZERO;
}

LRESULT WM_SETFONT (int wParam, int lParam) {
	return super.WM_SETFONT (font = wParam, lParam);
}

LRESULT WM_SIZE (int wParam, int lParam) {
	/*
	* Begin deferred window positioning
	*/
	int count = getChildrenCount ();
	if (count > 1 && hdwp == 0) {
		hdwp = OS.BeginDeferWindowPos (count);
	}
	
	/* Layout and resize */
	if (layout != null) layout.layout (this, false);
	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;
	
	/* End deferred window positioning */
	int oldHdwp = hdwp;
	hdwp = 0;
	if (oldHdwp != 0) OS.EndDeferWindowPos (oldHdwp);
	
	/* Damage the widget to cause a repaint */
	if ((state & CANVAS) != 0) {
		if ((style & SWT.NO_REDRAW_RESIZE) == 0) {
			if (hooks (SWT.Paint)) {
				OS.InvalidateRect (handle, null, true);
			}
		}
	}
	return result;
}

LRESULT WM_SYSCOLORCHANGE (int wParam, int lParam) {
	Control [] children = _getChildren ();
	for (int i=0; i<children.length; i++) {
		int hwndChild = children [i].handle;
		OS.SendMessage (hwndChild, OS.WM_SYSCOLORCHANGE, 0, 0);
	}
	return null;
}

LRESULT WM_SYSCOMMAND (int wParam, int lParam) {
	LRESULT result = super.WM_SYSCOMMAND (wParam, lParam);
	if (result != null) return result;
		
	/*
	* Check to see if the command is a system command or
	* a user menu item that was added to the system menu.
	*/
	if ((wParam & 0xF000) == 0) return result;

	/*
	* Bug in Windows.  When a vertical or horizontal scroll bar is
	* hidden or shown while the opposite scroll bar is being scrolled
	* by the user (with WM_HSCROLL code SB_LINEDOWN), the scroll bar
	* does not redraw properly.  The fix is to detect this case and
	* redraw the non-client area.
	*/
	int cmd = wParam & 0xFFF0;
	switch (cmd) {
		case OS.SC_HSCROLL:
		case OS.SC_VSCROLL:
			boolean showHBar = horizontalBar != null && horizontalBar.getVisible ();
			boolean showVBar = verticalBar != null && verticalBar.getVisible ();
			int code = callWindowProc (OS.WM_SYSCOMMAND, wParam, lParam);
			if ((showHBar != (horizontalBar != null && horizontalBar.getVisible ())) ||
				(showVBar != (verticalBar != null && verticalBar.getVisible ()))) {
					int flags = OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_UPDATENOW;
					OS.RedrawWindow (handle, null, 0, flags);
				}		
			if (code == 0) return LRESULT.ZERO;
			return new LRESULT (code);
	}

	/* Return the result */
	return result;
}

}
