/*******************************************************************************
 * 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.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><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 pixels 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 pixels 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 pixels 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 pixels 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 i = 0; i < events.length; i++) {
		addListener(events[i], 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() {
	//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() {
	//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() {
	//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() {
	//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);
}
}
