/*******************************************************************************
 * Copyright (c) 2000, 2010 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.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;

/**
 * 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 = new Listener() {
		public void handleEvent(Event 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);
	}
}
}
