/*******************************************************************************
 * 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.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * Instances of this class implement a Composite that positions and sizes
 * children and allows programmatic control of layout and border parameters.
 * ViewForm is used in the workbench to lay out a view's label/menu/toolbar
 * local bar.
 * <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>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>BORDER, FLAT</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(None)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @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 ViewForm 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;
	/**
	 * horizontalSpacing specifies the number of points between the right
	 * edge of one cell and the left edge of its neighbouring cell to
	 * the right.
	 *
	 * The default value is 1.
	 */
	public int horizontalSpacing = 1;
	/**
	 * verticalSpacing specifies the number of points between the bottom
	 * edge of one cell and the top edge of its neighbouring cell underneath.
	 *
	 * The default value is 1.
	 */
	public int verticalSpacing = 1;

	/**
	 * 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
	 */
	@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
	 */
	@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
	 */
	@Deprecated
	public static RGB borderOutsideRGB = new RGB (171, 168, 165);

	// SWT widgets
	Control topLeft;
	Control topCenter;
	Control topRight;
	Control content;

	// Configuration and state info
	boolean separateTopCenter = false;
	boolean showBorder = false;

	int separator = -1;
	int borderTop = 0;
	int borderBottom = 0;
	int borderLeft = 0;
	int borderRight = 0;
	int highlight = 0;
	Point oldSize;

	Color selectionBackground;
	Listener listener;

	static final int OFFSCREEN = -200;
	static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW;
	static final int SELECTION_BACKGROUND = SWT.COLOR_LIST_BACKGROUND;
/**
 * 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#BORDER
 * @see SWT#FLAT
 * @see #getStyle()
 */
public ViewForm(Composite parent, int style) {
	super(parent, checkStyle(style));
	super.setLayout(new ViewFormLayout());

	setBorderVisible((style & SWT.BORDER) != 0);

	listener = e -> {
		switch (e.type) {
			case SWT.Dispose: onDispose(e); break;
			case SWT.Paint: onPaint(e.gc); break;
			case SWT.Resize: onResize(); break;
		}
	};

	int[] events = new int[] {SWT.Dispose, SWT.Paint, SWT.Resize};

	for (int event : events) {
		addListener(event, listener);
	}
}

static int checkStyle (int style) {
	int mask = SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
	return style & mask | SWT.NO_REDRAW_RESIZE;
}

//protected void checkSubclass () {
//	String name = getClass().getName ();
//	String validName = ViewForm.class.getName();
//	if (!validName.equals(name)) {
//		SWT.error (SWT.ERROR_INVALID_SUBCLASS);
//	}
//}

@Override
public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget ();
	int trimX = x - borderLeft - highlight;
	int trimY = y - borderTop - highlight;
	int trimWidth = width + borderLeft + borderRight + 2*highlight;
	int trimHeight = height + borderTop + borderBottom + 2*highlight;
	return new Rectangle(trimX, trimY, trimWidth, trimHeight);
}
@Override
public Rectangle getClientArea() {
	checkWidget();
	Rectangle clientArea = super.getClientArea();
	clientArea.x += borderLeft;
	clientArea.y += borderTop;
	clientArea.width -= borderLeft + borderRight;
	clientArea.height -= borderTop + borderBottom;
	return clientArea;
}
/**
* Returns the content area.
*
* @return the control in the content area of the pane or null
*/
public Control getContent() {
	/*
	 * 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 parent.
	 */
	//checkWidget();
	return content;
}
/**
* Returns Control that appears in the top center of the pane.
* Typically this is a toolbar.
*
* @return the control in the top center of the pane or null
*/
public Control getTopCenter() {
	/*
	 * 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 topCenter;
}
/**
* Returns the Control that appears in the top left corner of the pane.
* Typically this is a label such as CLabel.
*
* @return the control in the top left corner of the pane or null
*/
public Control getTopLeft() {
	/*
	 * 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 topLeft;
}
/**
* Returns the control in the top right corner of the pane.
* 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 pane or null
*/
public Control getTopRight() {
	/*
	 * 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 topRight;
}
void onDispose(Event event) {
	removeListener(SWT.Dispose, listener);
	notifyListeners(SWT.Dispose, event);
	event.type = SWT.None;

	topLeft = null;
	topCenter = null;
	topRight = null;
	content = null;
	oldSize = null;
	selectionBackground = null;
}
void onPaint(GC gc) {
	Color gcForeground = gc.getForeground();
	Point size = getSize();
	Color border = getDisplay().getSystemColor(BORDER1_COLOR);
	if (showBorder) {
		gc.setForeground(border);
		gc.drawRectangle(0, 0, size.x - 1, size.y - 1);
		if (highlight > 0) {
			int x1 = 1;
			int y1 = 1;
			int x2 = size.x - 1;
			int y2 = size.y - 1;
			int[] shape = new int[] {x1,y1, x2,y1, x2,y2, x1,y2, x1,y1+highlight,
							   x1+highlight,y1+highlight, x1+highlight,y2-highlight,
							   x2-highlight,y2-highlight, x2-highlight,y1+highlight, x1,y1+highlight};
			Color highlightColor = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
			gc.setBackground(highlightColor);
			gc.fillPolygon(shape);
		}
	}
	if (separator > -1) {
		gc.setForeground(border);
		gc.drawLine(borderLeft + highlight, separator, size.x - borderLeft - borderRight - highlight, separator);
	}
	gc.setForeground(gcForeground);
}
void onResize() {
	Point size = getSize();
	if (oldSize == null || oldSize.x == 0 || oldSize.y == 0) {
		redraw();
	} else {
		int width = 0;
		if (oldSize.x < size.x) {
			width = size.x - oldSize.x + borderRight + highlight;
		} else if (oldSize.x > size.x) {
			width = borderRight + highlight;
		}
		redraw(size.x - width, 0, width, size.y, false);

		int height = 0;
		if (oldSize.y < size.y) {
			height = size.y - oldSize.y + borderBottom + highlight;
		}
		if (oldSize.y > size.y) {
			height = borderBottom + highlight;
		}
		redraw(0, size.y - height, size.x, height, false);
	}
	oldSize = size;
}
/**
* Sets the content.
* Setting the content to null will remove it from
* the pane - however, the creator of the content must dispose of the content.
*
* @param content the control to be displayed in the content area 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 not a child of this ViewForm</li>
* </ul>
*/
public void setContent(Control content) {
	checkWidget();
	if (content != null && content.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.content != null && !this.content.isDisposed()) {
		this.content.setBounds(OFFSCREEN, OFFSCREEN, 0, 0);
	}
	this.content = content;
	layout(false);
}
/**
 * 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;
}
void setSelectionBackground (Color color) {
	checkWidget();
	if (selectionBackground == color) return;
	if (color == null) color = getDisplay().getSystemColor(SELECTION_BACKGROUND);
	selectionBackground = color;
	redraw();
}
/**
* Set the control that appears in the top center of the pane.
* Typically this is a toolbar.
* The topCenter is optional.  Setting the topCenter to null will remove it from
* the pane - however, the creator of the topCenter must dispose of the topCenter.
*
* @param topCenter the control to be displayed in the top center 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 not a child of this ViewForm</li>
* </ul>
*/
public void setTopCenter(Control topCenter) {
	checkWidget();
	if (topCenter != null && topCenter.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.topCenter != null && !this.topCenter.isDisposed()) {
		Point size = this.topCenter.getSize();
		this.topCenter.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	this.topCenter = topCenter;
	layout(false);
}
/**
* Set the control that appears in the top left corner of the pane.
* Typically this is a label such as CLabel.
* The topLeft is optional.  Setting the top left control to null will remove it from
* the pane - however, the creator of the control must dispose of the control.
*
* @param c the control to be displayed in the top left 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 not a child of this ViewForm</li>
* </ul>
*/
public void setTopLeft(Control c) {
	checkWidget();
	if (c != null && c.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.topLeft != null && !this.topLeft.isDisposed()) {
		Point size = this.topLeft.getSize();
		this.topLeft.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	this.topLeft = c;
	layout(false);
}
/**
* Set the control that appears in the top right corner of the pane.
* Typically this is a Close button or a composite with a Menu and Close button.
* The topRight is optional.  Setting the top right control to null will remove it from
* the pane - however, the creator of the control must dispose of the control.
*
* @param c 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 not a child of this ViewForm</li>
* </ul>
*/
public void setTopRight(Control c) {
	checkWidget();
	if (c != null && c.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (this.topRight != null && !this.topRight.isDisposed()) {
		Point size = this.topRight.getSize();
		this.topRight.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	this.topRight = c;
	layout(false);
}
/**
* Specify whether the border should be displayed or not.
*
* @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 (showBorder == show) return;

	showBorder = show;
	if (showBorder) {
		borderLeft = borderTop = borderRight = borderBottom = 1;
		if ((getStyle() & SWT.FLAT)== 0) highlight = 2;
	} else {
		borderBottom = borderTop = borderLeft = borderRight = 0;
		highlight = 0;
	}
	layout(false);
	redraw();
}
/**
* If true, the topCenter will always appear on a separate line by itself, otherwise the
* topCenter will appear in the top row if there is room and will be moved to the second row if
* required.
*
* @param show true if the topCenter will always appear on a separate line by itself
*
* @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 setTopCenterSeparate(boolean show) {
	checkWidget();
	separateTopCenter = show;
	layout(false);
}
}
