/*******************************************************************************
 * 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.widgets;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;

/**
 * Instances of this class provide an etched border
 * with an optional title.
 * <p>
 * Shadow styles are hints and may not be honoured
 * by the platform.  To create a group with the
 * default shadow style for the platform, do not
 * specify a shadow style.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * Note: Only one of the above styles 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/examples.php">SWT Example: ControlExample</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 Group extends Composite {
	long /*int*/ clientHandle, labelHandle;
	String text = "";
	// We use this to keep track of the foreground color
	GdkRGBA foreground;

/**
 * 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 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#SHADOW_ETCHED_IN
 * @see SWT#SHADOW_ETCHED_OUT
 * @see SWT#SHADOW_IN
 * @see SWT#SHADOW_OUT
 * @see SWT#SHADOW_NONE
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Group (Composite parent, int style) {
	super (parent, checkStyle (style));
}

static int checkStyle (int style) {
	style |= SWT.NO_FOCUS;
	/*
	* Even though it is legal to create this widget
	* with scroll bars, they serve no useful purpose
	* because they do not automatically scroll the
	* widget's client area.  The fix is to clear
	* the SWT style.
	*/
	return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
}

@Override
protected void checkSubclass () {
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}

@Override
long /*int*/ clientHandle () {
	return clientHandle;
}

@Override
Point computeSizeInPixels (int wHint, int hHint, boolean changed) {
	Point size = super.computeSizeInPixels(wHint, hHint, changed);
	int width;
	if(GTK.GTK3){
		width = computeNativeSize (handle, SWT.DEFAULT, SWT.DEFAULT, false).x;
	}
	else{
		int x_thickness = GTK.gtk_style_get_xthickness (GTK.gtk_widget_get_style (handle));
		// GTK adds a LABEL_PAD and LABEL_SIDE_PAD to the label width, we also need to add
          	// the thickness of the frame border
		int minimalSizeAroundLabel = 2 * (GTK.GTK_FRAME_LABEL_PAD + GTK.GTK_FRAME_LABEL_SIDE_PAD + x_thickness);
		width = computeNativeSize (labelHandle, SWT.DEFAULT, SWT.DEFAULT, false) .x + minimalSizeAroundLabel;
	}
	size.x = Math.max (size.x, width);
	return size;
}
@Override
Rectangle computeTrimInPixels (int x, int y, int width, int height) {
	checkWidget();
	forceResize ();
	GtkAllocation allocation = new GtkAllocation();
	GTK.gtk_widget_get_allocation (clientHandle, allocation);
	int clientX = allocation.x;
	int clientY = allocation.y;
	x -= clientX;
	y -= clientY;
	width += clientX + clientX;
	height += clientX + clientY;
	return new Rectangle (x, y, width, height);
}

@Override
Rectangle getClientAreaInPixels () {
	Rectangle clientRectangle = super.getClientAreaInPixels ();
	/*
	* Bug 453827 Child position fix.
	* SWT's calls to gtk_widget_size_allocate and gtk_widget_set_allocation
	* causes GTK+ to move the clientHandle's SwtFixed down by the size of the label.
	* These calls can come up from 'shell' and group has no control over these calls.
	*
	* This is an undesired side-effect. Client handle's x & y positions should never
	* be incremented as this is an internal sub-container.
	*
	* Note: 0 by 0 was chosen as 1 by 1 shifts controls beyond their original pos.
	* The long term fix would be to not use widget_*_allocation from higher containers
	* like shell and to not use	gtkframe in non-group widgets (e.g used in label atm).
	*/
	clientRectangle.x = 0;
	clientRectangle.y = 0;
	return clientRectangle;
}

@Override
GdkRGBA getContextColorGdkRGBA () {
	assert GTK.GTK3 : "GTK3 code was run by GTK2";
	if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) {
		if (foreground != null) {
			return foreground;
		} else {
			return display.COLOR_WIDGET_FOREGROUND_RGBA;
		}
	} else {
		return super.getContextColorGdkRGBA();
	}
}

@Override
GdkRGBA getContextBackgroundGdkRGBA () {
	assert GTK.GTK3 : "GTK3 code was run by GTK2";
	if (GTK.GTK_VERSION >= OS.VERSION(3, 14, 0)) {
		return super.getContextBackgroundGdkRGBA();
	} else {
		long /*int*/ context = GTK.gtk_widget_get_style_context (fixedHandle);
		GdkRGBA rgba = new GdkRGBA ();
		GTK.gtk_style_context_get_background_color (context, GTK.GTK_STATE_FLAG_NORMAL, rgba);
		if ((state & BACKGROUND) == 0) {
			return defaultBackground();
		}
		return rgba;
	}
}

@Override
void createHandle(int index) {
	state |= HANDLE | THEME_BACKGROUND;

	fixedHandle = OS.g_object_new (display.gtk_fixed_get_type (), 0);
	if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
	GTK.gtk_widget_set_has_window (fixedHandle, true);

	handle = GTK.gtk_frame_new (null);
	if (handle == 0) error (SWT.ERROR_NO_HANDLES);

	labelHandle = GTK.gtk_label_new (null);
	if (labelHandle == 0) error (SWT.ERROR_NO_HANDLES);
	OS.g_object_ref (labelHandle);
	OS.g_object_ref_sink (labelHandle);

	clientHandle = OS.g_object_new (display.gtk_fixed_get_type (), 0);
	if (clientHandle == 0) error (SWT.ERROR_NO_HANDLES);
	/*
	 * Bug 453827 - clientHandle now has it's own window so that
	 * it can listen to events (clicking/tooltip etc.) and so that
	 * background can be drawn on it.
	 */
	GTK.gtk_widget_set_has_window (clientHandle, true);

	GTK.gtk_container_add (fixedHandle, handle);
	GTK.gtk_container_add (handle, clientHandle);
	if ((style & SWT.SHADOW_IN) != 0) {
		GTK.gtk_frame_set_shadow_type (handle, GTK.GTK_SHADOW_IN);
	}
	if ((style & SWT.SHADOW_OUT) != 0) {
		GTK.gtk_frame_set_shadow_type (handle, GTK.GTK_SHADOW_OUT);
	}
	if ((style & SWT.SHADOW_ETCHED_IN) != 0) {
		GTK.gtk_frame_set_shadow_type (handle, GTK.GTK_SHADOW_ETCHED_IN);
	}
	if ((style & SWT.SHADOW_ETCHED_OUT) != 0) {
		GTK.gtk_frame_set_shadow_type (handle, GTK.GTK_SHADOW_ETCHED_OUT);
	}
	// In GTK 3 font description is inherited from parent widget which is not how SWT has always worked,
	// reset to default font to get the usual behavior
	if (GTK.GTK3) {
		setFontDescription (defaultFont ().handle);
	}
}

@Override
int applyThemeBackground () {
	return 1;
}

@Override
void deregister () {
	super.deregister ();
	display.removeWidget (clientHandle);
	display.removeWidget (labelHandle);
}

@Override
void enableWidget (boolean enabled) {
	GTK.gtk_widget_set_sensitive (labelHandle, enabled);
}

@Override
long /*int*/ eventHandle () {
	/*
	 * Bug 453827 - Group's events should be handled via it's internal
	 * fixed container (clientHandle) and not via it's top level.
	 * This makes it behave more like composite.
	 */
	return clientHandle;
}

@Override
String getNameText () {
	return getText ();
}

/**
 * Returns the receiver's text, which is the string that the
 * is used as the <em>title</em>. If the text has not previously
 * been set, returns an empty string.
 *
 * @return the 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();
	return text;
}

@Override
void hookEvents () {
	super.hookEvents();
	if (labelHandle != 0) {
		OS.g_signal_connect_closure_by_id (labelHandle, display.signalIds [MNEMONIC_ACTIVATE], 0, display.getClosure (MNEMONIC_ACTIVATE), false);
	}
}

@Override
boolean mnemonicHit (char key) {
	if (labelHandle == 0) return false;
	boolean result = super.mnemonicHit (labelHandle, key);
	if (result) setFocus ();
	return result;
}

@Override
boolean mnemonicMatch (char key) {
	if (labelHandle == 0) return false;
	return mnemonicMatch (labelHandle, key);
}

@Override
long /*int*/ parentingHandle() {
	/*
	 * Bug 453827 - Children should be attached to the internal fixed
	 * subcontainer (clienthandle) and not the top-level fixedHandle.
	 */
	return clientHandle;
}

@Override
void register () {
	super.register ();
	display.addWidget (clientHandle, this);
	display.addWidget (labelHandle, this);
}

@Override
void releaseHandle () {
	super.releaseHandle ();
	clientHandle = labelHandle = 0;
}

@Override
void releaseWidget () {
	super.releaseWidget ();
	if (labelHandle != 0) OS.g_object_unref (labelHandle);
	text = null;
}

@Override
void setBackgroundGdkRGBA(long /*int*/ handle, GdkRGBA rgba) {
	assert GTK.GTK3 : "GTK3 code was run by GTK2";
	super.setBackgroundGdkRGBA(fixedHandle, rgba);
}

@Override
void setBackgroundGdkColor (GdkColor color) {
	assert !GTK.GTK3 : "GTK2 code was run by GTK3";
	super.setBackgroundGdkColor (color);
	setBackgroundGdkColor (fixedHandle, color);
	// Bug 453827 - client handle should also be painted as it's visible to the user now.
	setBackgroundGdkColor (clientHandle, color);
}

@Override
void setFontDescription (long /*int*/ font) {
	super.setFontDescription (font);
	setFontDescription (labelHandle, font);
}

@Override
void setForegroundGdkRGBA (long /*int*/ handle, GdkRGBA rgba) {
	assert GTK.GTK3 : "GTK3 code was run by GTK2";
	if (GTK.GTK_VERSION < OS.VERSION(3, 14, 0)) {
		super.setForegroundGdkRGBA(handle, rgba);
		return;
	}
	/*
	 * When using CSS, setting the foreground color on an empty label
	 * widget prevents the background from being set. If a user wants
	 * to specify a foreground color before the text is set, store the
	 * color and wait until text is specified to apply it.
	 */
	if (text != null && !text.isEmpty()) {
		super.setForegroundGdkRGBA (labelHandle, rgba);
	}
	foreground = rgba;
}

@Override
void setForegroundGdkColor (GdkColor color) {
	assert !GTK.GTK3 : "GTK2 code was run by GTK3";
	super.setForegroundGdkColor (color);
	setForegroundColor(labelHandle, color);
}

@Override
void setForegroundGdkRGBA (GdkRGBA rgba) {
	assert GTK.GTK3 : "GTK3 code was run by GTK2";
	super.setForegroundGdkRGBA(rgba);
	setForegroundGdkRGBA (labelHandle, rgba);
}

@Override
void setOrientation (boolean create) {
	super.setOrientation (create);
	if ((style & SWT.RIGHT_TO_LEFT) != 0 || !create) {
		int dir = (style & SWT.RIGHT_TO_LEFT) != 0 ? GTK.GTK_TEXT_DIR_RTL : GTK.GTK_TEXT_DIR_LTR;
		GTK.gtk_widget_set_direction (labelHandle, dir);
	}
}

/**
 * Sets the receiver's text, which is the string that will
 * be displayed as the receiver's <em>title</em>, to the argument,
 * which may not be null. The string may include the mnemonic character.
 * </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 first child of the group. 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 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);
	text = string;
	char [] chars = fixMnemonic (string);
	byte [] buffer = Converter.wcsToMbcs (chars, true);
	GTK.gtk_label_set_text_with_mnemonic (labelHandle, buffer);
	if (string.length () != 0) {
		if (GTK.gtk_frame_get_label_widget (handle) == 0) {
			GTK.gtk_frame_set_label_widget (handle, labelHandle);
		}
	} else {
		GTK.gtk_frame_set_label_widget (handle, 0);
	}
	// Set the foreground now that the text has been set
	if (GTK.GTK_VERSION >= OS.VERSION (3, 16, 0) && foreground != null) {
		setForegroundGdkRGBA (labelHandle, foreground);
	}
}

@Override
void showWidget () {
	super.showWidget ();
	if (clientHandle != 0) GTK.gtk_widget_show (clientHandle);
	if (labelHandle != 0) GTK.gtk_widget_show (labelHandle);
}

@Override
int setBounds(int x, int y, int width, int height, boolean move, boolean resize) {
		if (GTK.GTK3) {
			// Work around for bug 470129.
			// See also https://bugzilla.gnome.org/show_bug.cgi?id=754976 :
			// GtkFrame: Attempt to allocate size of width 1 (or a small number) fails
			//
			// GtkFrame does not handle well allocating less than its minimum size
			GtkRequisition requisition = new GtkRequisition();
			GTK.gtk_widget_get_preferred_size(handle, requisition, null);
			/*
			 * Feature in GTK3.20+: size calculations take into account GtkCSSNode
			 * elements which we cannot access. If the to-be-allocated size minus
			 * these elements is < 0, allocate the preferred size instead.
			 */
			if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
				width = (width - (requisition.width - width)) < 0 ? requisition.width : width;
				height = (height - (requisition.height - height)) < 0 ? requisition.height : height;
			} else {
				width = Math.max(requisition.width, width);
			}
		}
	return super.setBounds(x, y, width, height, move, resize);
}

@Override
long /*int*/ paintHandle() {
	if (GTK.GTK3) {
		return super.paintHandle();
	}
	else {
		long /*int*/ topHandle = topHandle ();
		/* we draw all our children on the clientHandle*/
		long /*int*/ paintHandle = clientHandle;
		while (paintHandle != topHandle) {
			if (GTK.gtk_widget_get_has_window (paintHandle)) break;
			paintHandle = GTK.gtk_widget_get_parent (paintHandle);
		}
		return paintHandle;
	}
}

@Override
long /*int*/ paintWindow () {
	long /*int*/ paintHandle = clientHandle;
	GTK.gtk_widget_realize (paintHandle);
	return gtk_widget_get_window (paintHandle);
}

}