/*******************************************************************************
 * Copyright (c) 2000, 2009 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 SashForm
 *
 * @see SashForm
 */
class SashFormLayout extends Layout {
@Override
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
	SashForm sashForm = (SashForm)composite;
	Control[] cArray = sashForm.getControls(true);
	int width = 0;
	int height = 0;
	if (cArray.length == 0) {
		if (wHint != SWT.DEFAULT) width = wHint;
		if (hHint != SWT.DEFAULT) height = hHint;
		return new Point(width, height);
	}
	// determine control sizes
	boolean vertical = sashForm.getOrientation() == SWT.VERTICAL;
	int maxIndex = 0;
	int maxValue = 0;
	for (int i = 0; i < cArray.length; i++) {
		if (vertical) {
			Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
			if (size.y > maxValue) {
				maxIndex = i;
				maxValue = size.y;
			}
			width = Math.max(width, size.x);
		} else {
			Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
			if (size.x > maxValue) {
				maxIndex = i;
				maxValue = size.x;
			}
			height = Math.max(height, size.y);
		}
	}
	// get the ratios
	long[] ratios = new long[cArray.length];
	long total = 0;
	for (int i = 0; i < cArray.length; i++) {
		Object data = cArray[i].getLayoutData();
		if (data != null && data instanceof SashFormData) {
			ratios[i] = ((SashFormData)data).weight;
		} else {
			data = new SashFormData();
			cArray[i].setLayoutData(data);
			((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;

		}
		total += ratios[i];
	}
	if (ratios[maxIndex] > 0) {
		int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
		if (vertical) {
			height += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
		} else {
			width += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
		}
	}
	width += sashForm.getBorderWidth()*2;
	height += sashForm.getBorderWidth()*2;
	if (wHint != SWT.DEFAULT) width = wHint;
	if (hHint != SWT.DEFAULT) height = hHint;
	return new Point(width, height);
}

@Override
protected boolean flushCache(Control control) {
	return true;
}

@Override
protected void layout(Composite composite, boolean flushCache) {
	SashForm sashForm = (SashForm)composite;
	Rectangle area = sashForm.getClientArea();
	if (area.width <= 1 || area.height <= 1) return;

	Control[] newControls = sashForm.getControls(true);
	if (sashForm.controls.length == 0 && newControls.length == 0) return;
	sashForm.controls = newControls;

	Control[] controls = sashForm.controls;

	if (sashForm.maxControl != null && !sashForm.maxControl.isDisposed()) {
		for (int i= 0; i < controls.length; i++){
			if (controls[i] != sashForm.maxControl) {
				controls[i].setBounds(-200, -200, 0, 0);
			} else {
				controls[i].setBounds(area);
			}
		}
		return;
	}

	// keep just the right number of sashes
	if (sashForm.sashes.length < controls.length - 1) {
		Sash[] newSashes = new Sash[controls.length - 1];
		System.arraycopy(sashForm.sashes, 0, newSashes, 0, sashForm.sashes.length);
		for (int i = sashForm.sashes.length; i < newSashes.length; i++) {
			newSashes[i] = sashForm.createSash();
		}
		sashForm.sashes = newSashes;
	}
	if (sashForm.sashes.length > controls.length - 1) {
		if (controls.length == 0) {
			for (int i = 0; i < sashForm.sashes.length; i++) {
				sashForm.sashes[i].dispose();
			}
			sashForm.sashes = new Sash[0];
		} else {
			Sash[] newSashes = new Sash[controls.length - 1];
			System.arraycopy(sashForm.sashes, 0, newSashes, 0, newSashes.length);
			for (int i = controls.length - 1; i < sashForm.sashes.length; i++) {
				sashForm.sashes[i].dispose();
			}
			sashForm.sashes = newSashes;
		}
	}
	if (controls.length == 0) return;
	Sash[] sashes = sashForm.sashes;
	// get the ratios
	long[] ratios = new long[controls.length];
	long total = 0;
	for (int i = 0; i < controls.length; i++) {
		Object data = controls[i].getLayoutData();
		if (data != null && data instanceof SashFormData) {
			ratios[i] = ((SashFormData)data).weight;
		} else {
			data = new SashFormData();
			controls[i].setLayoutData(data);
			((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;

		}
		total += ratios[i];
	}

	int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
	if (sashForm.getOrientation() == SWT.HORIZONTAL) {
		int width = (int)(ratios[0] * (area.width - sashes.length * sashwidth) / total);
		int x = area.x;
		controls[0].setBounds(x, area.y, width, area.height);
		x += width;
		for (int i = 1; i < controls.length - 1; i++) {
			sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
			x += sashwidth;
			width = (int)(ratios[i] * (area.width - sashes.length * sashwidth) / total);
			controls[i].setBounds(x, area.y, width, area.height);
			x += width;
		}
		if (controls.length > 1) {
			sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
			x += sashwidth;
			width = area.width - x;
			controls[controls.length - 1].setBounds(x, area.y, width, area.height);
		}
	} else {
		int height = (int)(ratios[0] * (area.height - sashes.length * sashwidth) / total);
		int y = area.y;
		controls[0].setBounds(area.x, y, area.width, height);
		y += height;
		for (int i = 1; i < controls.length - 1; i++) {
			sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
			y += sashwidth;
			height = (int)(ratios[i] * (area.height - sashes.length * sashwidth) / total);
			controls[i].setBounds(area.x, y, area.width, height);
			y += height;
		}
		if (controls.length > 1) {
			sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
			y += sashwidth;
			height = area.height - y;
			controls[controls.length - 1].setBounds(area.x, y, area.width, height);
		}

	}
}
}
