/*******************************************************************************
 * 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;
}
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>
 */
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);
	}
}
}
