/*******************************************************************************
 * 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 lays out its
 * children and allows programmatic control of the layout. It draws
 * a separator between the left and right children which can be dragged
 * to resize the right control.
 * CBanner is used in the workbench to layout the toolbar area and
 * perspective switching toolbar.
 * <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>NONE</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>
 *
 * @since 3.0
 * @noextend This class is not intended to be subclassed by clients.
 */

public class CBanner extends Composite {

	Control left;
	Control right;
	Control bottom;

	boolean simple = true;

	int[] curve = new int[0];
	int curveStart = 0;
	Rectangle curveRect = new Rectangle(0, 0, 0, 0);
	int curve_width = 5;
	int curve_indent = -2;

	int rightWidth = SWT.DEFAULT;
	int rightMinWidth = 0;
	int rightMinHeight = 0;
	Cursor resizeCursor;
	boolean dragging = false;
	int rightDragDisplacement = 0;
	Listener listener;

	static final int OFFSCREEN = -200;
	static final int BORDER_BOTTOM = 2;
	static final int BORDER_TOP = 3;
	static final int BORDER_STRIPE = 1;
	static final int CURVE_TAIL = 200;
	static final int BEZIER_RIGHT = 30;
	static final int BEZIER_LEFT = 30;
	static final int MIN_LEFT = 10;
	static int BORDER1 = SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW;


/**
 * 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>
 *
 */
public CBanner(Composite parent, int style) {
	super(parent, checkStyle(style));
	super.setLayout(new CBannerLayout());
	resizeCursor = getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE);

	listener = e -> {
		switch (e.type) {
			case SWT.Dispose:
				onDispose(e); break;
			case SWT.MouseDown:
				onMouseDown (e.x, e.y); break;
			case SWT.MouseExit:
				onMouseExit(); break;
			case SWT.MouseMove:
				onMouseMove(e.x, e.y); break;
			case SWT.MouseUp:
				onMouseUp(); break;
			case SWT.Paint:
				onPaint(e.gc); break;
			case SWT.Resize:
				onResize(); break;
		}
	};
	int[] events = new int[] {SWT.Dispose, SWT.MouseDown, SWT.MouseExit, SWT.MouseMove, SWT.MouseUp, SWT.Paint, SWT.Resize};
	for (int i = 0; i < events.length; i++) {
		addListener(events[i], listener);
	}
}
static int[] bezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int count) {
	// The parametric equations for a Bezier curve for x[t] and y[t] where  0 <= t <=1 are:
	// x[t] = x0+3(x1-x0)t+3(x0+x2-2x1)t^2+(x3-x0+3x1-3x2)t^3
	// y[t] = y0+3(y1-y0)t+3(y0+y2-2y1)t^2+(y3-y0+3y1-3y2)t^3
	double a0 = x0;
	double a1 = 3*(x1 - x0);
	double a2 = 3*(x0 + x2 - 2*x1);
	double a3 = x3 - x0 + 3*x1 - 3*x2;
	double b0 = y0;
	double b1 = 3*(y1 - y0);
	double b2 = 3*(y0 + y2 - 2*y1);
	double b3 = y3 - y0 + 3*y1 - 3*y2;

	int[] polygon = new int[2*count + 2];
	for (int i = 0; i <= count; i++) {
		double t = (double)i / (double)count;
		polygon[2*i] = (int)(a0 + a1*t + a2*t*t + a3*t*t*t);
		polygon[2*i + 1] = (int)(b0 + b1*t + b2*t*t + b3*t*t*t);
	}
	return polygon;
}
static int checkStyle (int style) {
	return SWT.NONE;
}
/*
* This class was not intended to be subclassed but this restriction
* cannot be enforced without breaking backward compatibility.
*/
//protected void checkSubclass () {
//	String name = getClass ().getName ();
//	int index = name.lastIndexOf ('.');
//	if (!name.substring (0, index + 1).equals ("org.eclipse.swt.custom.")) {
//		SWT.error (SWT.ERROR_INVALID_SUBCLASS);
//	}
//}
/**
* Returns the Control that appears on the bottom side of the banner.
*
* @return the control that appears on the bottom side of the banner 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>
*
* @since 3.0
*/
public Control getBottom() {
	checkWidget();
	return bottom;
}
@Override
public Rectangle getClientArea() {
	return new Rectangle(0, 0, 0, 0);
}

/**
* Returns the Control that appears on the left side of the banner.
*
* @return the control that appears on the left side of the banner 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>
*
* @since 3.0
*/
public Control getLeft() {
	checkWidget();
	return left;
}

/**
* Returns the Control that appears on the right side of the banner.
*
* @return the control that appears on the right side of the banner 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>
*
* @since 3.0
*/
public Control getRight() {
	checkWidget();
	return right;
}
/**
 * Returns the minimum size of the control that appears on the right of the banner.
 *
 * @return the minimum size of the control that appears on the right of the banner
 *
 * @since 3.1
 */
public Point getRightMinimumSize() {
	checkWidget();
	return new Point(rightMinWidth, rightMinHeight);
}
/**
 * Returns the width of the control that appears on the right of the banner.
 *
 * @return the width of the control that appears on the right of the banner
 *
 * @since 3.0
 */
public int getRightWidth() {
	checkWidget();
	if (right == null) return 0;
	if (rightWidth == SWT.DEFAULT) {
		Point size = right.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
		return size.x;
	}
	return rightWidth;
}
/**
 * Returns <code>true</code> if the CBanner is rendered
 * with a simple, traditional shape.
 *
 * @return <code>true</code> if the CBanner is rendered with a simple shape
 *
 * @since 3.0
 */
public boolean getSimple() {
	checkWidget();
	return simple;
}
void onDispose(Event event) {
	removeListener(SWT.Dispose, listener);
	notifyListeners(SWT.Dispose, event);
	event.type = SWT.None;

	resizeCursor = null;
	left = null;
	right = null;
	bottom = null;
}
void onMouseDown (int x, int y) {
	if (curveRect.contains(x, y)) {
		dragging = true;
		rightDragDisplacement = curveStart - x + curve_width - curve_indent;
	}
}
void onMouseExit() {
	if (!dragging) setCursor(null);
}
void onMouseMove(int x, int y) {
	if (dragging) {
		Point size = getSize();
		if (!(0 < x && x < size.x)) return;
		rightWidth = Math.max(0, size.x - x - rightDragDisplacement);
		if (rightMinWidth == SWT.DEFAULT) {
			Point minSize = right.computeSize(rightMinWidth, rightMinHeight);
			rightWidth = Math.max(minSize.x, rightWidth);
		} else {
			rightWidth = Math.max(rightMinWidth, rightWidth);
		}
		layout(false);
		return;
	}
	if (curveRect.contains(x, y)) {
		setCursor(resizeCursor);
	} else {
		setCursor(null);
	}
}
void onMouseUp () {
	dragging = false;
}
void onPaint(GC gc) {
//	 Useful for debugging paint problems
//	{
//	Point size = getSize();
//	gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GREEN));
//	gc.fillRectangle(-10, -10, size.x+20, size.y+20);
//	}
	if (left == null && right == null) return;
	Point size = getSize();
	Color border1 = getDisplay().getSystemColor(BORDER1);
	if (bottom != null) {
		int y = bottom.getBounds().y - BORDER_STRIPE - 1;
		gc.setForeground(border1);
		gc.drawLine(0, y, size.x, y);
	}
	if (left == null || right == null) return;
	int[] line1 = new int[curve.length+6];
	int index = 0;
	int x = curveStart;
	line1[index++] = x + 1;
	line1[index++] = size.y - BORDER_STRIPE;
	for (int i = 0; i < curve.length/2; i++) {
		line1[index++]=x+curve[2*i];
		line1[index++]=curve[2*i+1];
	}
	line1[index++] = x + curve_width;
	line1[index++] = 0;
	line1[index++] = size.x;
	line1[index++] = 0;

	Color background = getBackground();

	if (getDisplay().getDepth() >= 15) {
		// Anti- aliasing
		int[] line2 = new int[line1.length];
		index = 0;
		for (int i = 0; i < line1.length/2; i++) {
			line2[index] = line1[index++]  - 1;
			line2[index] = line1[index++];
		}
		int[] line3 = new int[line1.length];
		index = 0;
		for (int i = 0; i < line1.length/2; i++) {
			line3[index] = line1[index++] + 1;
			line3[index] = line1[index++];
		}
		RGB from = border1.getRGB();
		RGB to = background.getRGB();
		int red = from.red + 3*(to.red - from.red)/4;
		int green = from.green + 3*(to.green - from.green)/4;
		int blue = from.blue + 3*(to.blue - from.blue)/4;
		Color color = new Color(getDisplay(), red, green, blue);
		gc.setForeground(color);
		gc.drawPolyline(line2);
		gc.drawPolyline(line3);
		color.dispose();

		// draw tail fading to background
		int x1 = Math.max(0, curveStart - CURVE_TAIL);
		gc.setForeground(background);
		gc.setBackground(border1);
		gc.fillGradientRectangle(x1, size.y - BORDER_STRIPE, curveStart-x1+1, 1, false);
	} else {
		// draw solid tail
		int x1 = Math.max(0, curveStart - CURVE_TAIL);
		gc.setForeground(border1);
		gc.drawLine(x1, size.y - BORDER_STRIPE, curveStart+1, size.y - BORDER_STRIPE);
	}

	// draw border
	gc.setForeground(border1);
	gc.drawPolyline(line1);
}

void onResize() {
	updateCurve(getSize().y);
}
/**
* Set the control that appears on the bottom side of the banner.
* The bottom control is optional.  Setting the bottom control to null will remove it from
* the banner - however, the creator of the control must dispose of the control.
*
* @param control the control to be displayed on the bottom 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 bottom control was not created as a child of the receiver</li>
* </ul>
*
* @since 3.0
*/
public void setBottom(Control control) {
	checkWidget();
	if (control != null && control.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (bottom != null && !bottom.isDisposed()) {
		Point size = bottom.getSize();
		bottom.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	bottom = control;
	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;
}

/**
* Set the control that appears on the left side of the banner.
* The left control is optional.  Setting the left control to null will remove it from
* the banner - however, the creator of the control must dispose of the control.
*
* @param control the control to be displayed on the left 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 left control was not created as a child of the receiver</li>
* </ul>
*
* @since 3.0
*/
public void setLeft(Control control) {
	checkWidget();
	if (control != null && control.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (left != null && !left.isDisposed()) {
		Point size = left.getSize();
		left.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	left = control;
	layout(false);
}
/**
* Set the control that appears on the right side of the banner.
* The right control is optional.  Setting the right control to null will remove it from
* the banner - however, the creator of the control must dispose of the control.
*
* @param control the control to be displayed on the right 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 right control was not created as a child of the receiver</li>
* </ul>
*
* @since 3.0
*/
public void setRight(Control control) {
	checkWidget();
	if (control != null && control.getParent() != this) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (right != null && !right.isDisposed()) {
		Point size = right.getSize();
		right.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
	}
	right = control;
	layout(false);
}
/**
 * Set the minimum height of the control that appears on the right side of the banner.
 *
 * @param size the minimum size of the control on the right
 *
 * @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 size is null or the values of size are less than SWT.DEFAULT</li>
 * </ul>
 *
 * @since 3.1
 */
public void setRightMinimumSize(Point size) {
	checkWidget();
	if (size == null || size.x < SWT.DEFAULT || size.y < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	rightMinWidth = size.x;
	rightMinHeight = size.y;
	layout(false);
}
/**
 * Set the width of the control that appears on the right side of the banner.
 *
 * @param width the width of the control on the right
 *
 * @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 width is less than SWT.DEFAULT</li>
 * </ul>
 *
 * @since 3.0
 */
public void setRightWidth(int width) {
	checkWidget();
	if (width < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	rightWidth = width;
	layout(false);
}
/**
 * Sets the shape that the CBanner will use to render itself.
 *
 * @param simple <code>true</code> if the CBanner should render itself in a simple, traditional style
 *
 * @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>
 *
 * @since 3.0
 */
public void setSimple(boolean simple) {
	checkWidget();
	if (this.simple != simple) {
		this.simple = simple;
		if (simple) {
			curve_width = 5;
			curve_indent = -2;
		} else {
			curve_width = 50;
			curve_indent = 5;
		}
		updateCurve(getSize().y);
		layout(false);
		redraw();
	}
}
void updateCurve(int height) {
	int h = height - BORDER_STRIPE;
	if (simple) {
		curve = new int[] {0,h, 1,h, 2,h-1, 3,h-2,
			                       3,2, 4,1, 5,0,};
	} else {
		curve = bezier(0, h+1, BEZIER_LEFT, h+1,
				             curve_width-BEZIER_RIGHT, 0, curve_width, 0,
		                     curve_width);
	}
}
}
