/*******************************************************************************
 * Copyright (c) 2000, 2006 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.*;

/**
 * This class provides the layout for CBanner
 * 
 * @see CBanner
 */
class CBannerLayout extends Layout {

protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
	CBanner banner = (CBanner)composite;
	Control left = banner.left;
	Control right = banner.right;
	Control bottom = banner.bottom;
	boolean showCurve = left != null && right != null;
	int height = hHint;
	int width = wHint;
	
	// Calculate component sizes
	Point bottomSize = new Point(0, 0);
	if (bottom != null) {
		int trim = computeTrim(bottom);
		int w = wHint == SWT.DEFAULT ? SWT.DEFAULT : Math.max(0, width - trim);
		bottomSize = computeChildSize(bottom, w, SWT.DEFAULT, flushCache);
	}
	Point rightSize = new Point(0, 0);
	if (right != null) {
		int trim = computeTrim(right);
		int w = SWT.DEFAULT;
		if (banner.rightWidth != SWT.DEFAULT) {
			w = banner.rightWidth - trim;
			if (left != null) {
				w = Math.min(w, width - banner.curve_width + 2* banner.curve_indent - CBanner.MIN_LEFT - trim);
			}
			w = Math.max(0, w);
		}
		rightSize = computeChildSize(right, w, SWT.DEFAULT, flushCache);
		if (wHint != SWT.DEFAULT) {
			width -= rightSize.x + banner.curve_width - 2* banner.curve_indent;
		}
	}
	Point leftSize = new Point(0, 0);
	if (left != null) {
		int trim = computeTrim(left);
		int w = wHint == SWT.DEFAULT ? SWT.DEFAULT : Math.max(0, width - trim);
		leftSize = computeChildSize(left, w, SWT.DEFAULT, flushCache);
	}
	
	// Add up sizes
	width = leftSize.x + rightSize.x;
	height = bottomSize.y;
	if (bottom != null && (left != null || right != null)) {
		height += CBanner.BORDER_STRIPE + 2;
	}
	if (left != null) {
		if (right == null) {
			height += leftSize.y;
		} else {
			height += Math.max(leftSize.y, banner.rightMinHeight == SWT.DEFAULT ? rightSize.y : banner.rightMinHeight);
		}
	} else {
		height += rightSize.y;
	}
	if (showCurve) {
		width += banner.curve_width - 2*banner.curve_indent;
		height +=  CBanner.BORDER_TOP + CBanner.BORDER_BOTTOM + 2*CBanner.BORDER_STRIPE;
	}
	
	if (wHint != SWT.DEFAULT) width = wHint;
	if (hHint != SWT.DEFAULT) height = hHint;
	
	return new Point(width, height);
}
Point computeChildSize(Control control, int wHint, int hHint, boolean flushCache) {
	Object data = control.getLayoutData();
	if (data == null || !(data instanceof CLayoutData)) {
		data = new CLayoutData();
		control.setLayoutData(data);
	}
	return ((CLayoutData)data).computeSize(control, wHint, hHint, flushCache);
}
int computeTrim(Control c) {
	if (c instanceof Scrollable) {
		Rectangle rect = ((Scrollable) c).computeTrim (0, 0, 0, 0);
		return rect.width;
	}
	return c.getBorderWidth () * 2;
}
protected boolean flushCache(Control control) {
	Object data = control.getLayoutData();
	if (data != null && data instanceof CLayoutData) ((CLayoutData)data).flushCache();
	return true;
}
protected void layout(Composite composite, boolean flushCache) {
	CBanner banner = (CBanner)composite;
	Control left = banner.left;
	Control right = banner.right;
	Control bottom = banner.bottom;
	
	Point size = banner.getSize();
	boolean showCurve = left != null && right != null;
	int width = size.x - 2*banner.getBorderWidth();
	int height = size.y - 2*banner.getBorderWidth();
	
	Point bottomSize = new Point(0, 0);
	if (bottom != null) {
		int trim = computeTrim(bottom);
		int w = Math.max(0, width - trim);
		bottomSize = computeChildSize(bottom, w, SWT.DEFAULT, flushCache);
		height -= bottomSize.y + CBanner.BORDER_STRIPE + 2;
	}
	if (showCurve) height -=  CBanner.BORDER_TOP + CBanner.BORDER_BOTTOM + 2*CBanner.BORDER_STRIPE;
	height = Math.max(0, height);
	Point rightSize = new Point(0,0);
	if (right != null) {
		int trim = computeTrim(right);
		int w = SWT.DEFAULT;
		if (banner.rightWidth != SWT.DEFAULT) {
			w = banner.rightWidth - trim;
			if (left != null) {
				w = Math.min(w, width - banner.curve_width + 2* banner.curve_indent - CBanner.MIN_LEFT - trim);
			}
			w = Math.max(0, w);
		}
		rightSize = computeChildSize(right, w, SWT.DEFAULT, flushCache);
		width = width - (rightSize.x - banner.curve_indent + banner.curve_width - banner.curve_indent); 
	}
	Point leftSize = new Point(0, 0);
	if (left != null) {
		int trim = computeTrim(left);
		int w = Math.max(0, width - trim);
		leftSize = computeChildSize(left, w, SWT.DEFAULT, flushCache);
	}

	int x = 0;
	int y = 0;
	int oldStart = banner.curveStart;
	Rectangle leftRect = null;
	Rectangle rightRect = null;
	Rectangle bottomRect = null;
	if (bottom != null) {
		bottomRect = new Rectangle(x, y+size.y-bottomSize.y, bottomSize.x, bottomSize.y);
	}
	if (showCurve) y += CBanner.BORDER_TOP + CBanner.BORDER_STRIPE;
	if(left != null) {
		leftRect = new Rectangle(x, y, leftSize.x, leftSize.y);
		banner.curveStart = x + leftSize.x - banner.curve_indent;
		x += leftSize.x - banner.curve_indent + banner.curve_width - banner.curve_indent;
	}
	if (right != null) {
		if (left != null) {
			rightSize.y = Math.max(leftSize.y, banner.rightMinHeight == SWT.DEFAULT ? rightSize.y : banner.rightMinHeight);
		}
		rightRect = new Rectangle(x, y, rightSize.x, rightSize.y);
	}
	if (banner.curveStart < oldStart) {
		banner.redraw(banner.curveStart - CBanner.CURVE_TAIL, 0, oldStart + banner.curve_width - banner.curveStart + CBanner.CURVE_TAIL + 5, size.y, false);
	}
	if (banner.curveStart > oldStart) {
		banner.redraw(oldStart - CBanner.CURVE_TAIL, 0, banner.curveStart + banner.curve_width - oldStart + CBanner.CURVE_TAIL + 5, size.y, false);
	}
	/*
	 * The paint events must be flushed in order to make the curve draw smoothly
	 * while the user drags the divider.
	 * On Windows, it is necessary to flush the paints before the children are 
	 * resized because otherwise the children (particularly toolbars) will flash.
	 */
	banner.update();
	banner.curveRect = new Rectangle(banner.curveStart, 0, banner.curve_width, size.y);
	if (bottomRect != null) bottom.setBounds(bottomRect);
	if (rightRect != null) right.setBounds(rightRect);
	if (leftRect != null) left.setBounds(leftRect);
}
}
