/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jdt.internal.ui.util;

import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Control;

import org.eclipse.jface.util.Assert;

/**
 * Helper class to layout a number of children if the composite uses a <code>GridLayout</code>. 
 * If the numbers of widgets to be layouted into one row is smaller than the number of columns 
 * defined for the grid layout the helper class assigns a corresponing value to the <code>
 * GridData.horizontalSpan</code> field.
 * 
 * Additionally a row layouter manages a default <code>GridData</code> object for each column.
 * If set this grid data is used for the widget if it doesn't manage its own grid data object.
 * 
 * Call one of the <code>perform</code> methods to assign the correct grid data objects to
 * a set of widgets according to the number of columns passed to the layouter's constructor.
 */
public class RowLayouter {

	public int spanHorizontalAlignment= -1;
	public int spanGrabExcessHorizontalSpace= -1;
	public int spanHorizontalSpan= -1;
	public int spanHorizontalIndent= -1;
	public int spanWidthHint= -1;
		
	public int spanVerticalAlignment= -1;
	public int spanGrabExcessVerticalSpace= -1;
	public int spanVerticalSpan= -1;
	public int spanHeightHint= -1;
	
	private int fNumColumns;
	private boolean fOrder;
	private Control fLastControl;
	private GridData[] fDefaultGridDatas= new GridData[4];
		
	public RowLayouter(int numColumns) {
		this(numColumns, false);
	}

	public RowLayouter(int numColumns, boolean order) {
		fNumColumns= numColumns;
		fOrder= order;
	}
	
	public void setDefaultSpan() {
		spanHorizontalAlignment= GridData.FILL;
		spanGrabExcessHorizontalSpace= 1;
	}
	
	public void perform(Control c1) {
		perform(new Control[] {c1}, 0);
	}
	
	public void perform(Control c1, Control c2, int span) {
		perform(new Control[] {c1, c2}, span);
	}
	
	public void perform(Control c1, Control c2, Control c3, int span) {
		perform(new Control[] {c1, c2, c3}, span);
	}
	
	public void perform(Control[] controls, int spanColumn) {
		int numColumns= numColumns();
		Assert.isTrue(controls.length <= numColumns);
		order(controls);
		int gridIndex= 0;
		for (int i= 0; i < controls.length; i++) {
			Control control= controls[i];
			GridData gd= (GridData)control.getLayoutData();
			if (gd == null)
				gd= getGridData(gridIndex);
				
			if (i == spanColumn) {
				int span= numColumns - (controls.length - 1);
				gridIndex+= span;
				if (gd == null)
					gd= new GridData();
				applyDelta(gd);
				gd.horizontalSpan= span;
			} else {
				gridIndex++;
			}
			control.setLayoutData(gd);
		}
	}
	
	private void applyDelta(GridData gd) {
		if (spanHorizontalAlignment != -1)
			gd.horizontalAlignment= spanHorizontalAlignment;
			
		if (spanGrabExcessHorizontalSpace != -1) {
			if (spanGrabExcessHorizontalSpace == 0)
				gd.grabExcessHorizontalSpace= false;
			else
				gd.grabExcessHorizontalSpace= true;
		}		
				
			
		if (spanHorizontalSpan != -1)
			gd.horizontalSpan= spanHorizontalSpan;
			
		if (spanHorizontalIndent != -1)
			gd.horizontalIndent= spanHorizontalIndent;
		
		if (spanWidthHint != -1)
			gd.widthHint= spanWidthHint;
			
		if (spanVerticalAlignment != -1)
			gd.verticalAlignment= spanVerticalAlignment;
			
		if (spanGrabExcessVerticalSpace != -1) {
			if (spanGrabExcessVerticalSpace == 0)
				gd.grabExcessVerticalSpace= false;
			else
				gd.grabExcessVerticalSpace= true;
		}		
			
		if (spanVerticalSpan != -1)
			gd.verticalSpan= spanVerticalSpan;
			
		if (spanHeightHint != -1)
			gd.heightHint= spanHeightHint;
	}
	public void setDefaultGridData(GridData gd, int index) {
		if (index >= fDefaultGridDatas.length) {
			GridData[] newDatas= new GridData[index + 4];
			System.arraycopy(fDefaultGridDatas, 0, newDatas, 0, fDefaultGridDatas.length);
			fDefaultGridDatas= newDatas;
		}
		fDefaultGridDatas[index]= gd;
	}
	
	public GridData getGridData(int index) {
		if (index > fDefaultGridDatas.length)
			return null;
			
		return cloneGridData(fDefaultGridDatas[index]);
	}
	
	public int numColumns() {
		return fNumColumns;
	}
	
	protected void order(Control[] controls) {
		if (!fOrder)
			return;
			
		for (int i= 0; i < controls.length; i++) {
			Control control= controls[i];
			control.moveBelow(fLastControl);
			fLastControl= control;
		}
	}
	
	protected GridData cloneGridData(GridData gd) {
		if (gd == null)
			return null;
			
		GridData result= new GridData();
		result.horizontalAlignment= gd.horizontalAlignment;
		result.grabExcessHorizontalSpace= gd.grabExcessHorizontalSpace;
		result.horizontalSpan= gd.horizontalSpan;
		result.horizontalIndent= gd.horizontalIndent;
		result.widthHint= gd.widthHint;
		
		result.verticalAlignment= gd.verticalAlignment;
		result.grabExcessVerticalSpace= gd.grabExcessVerticalSpace;
		result.verticalSpan= gd.verticalSpan;
		result.heightHint= gd.heightHint;
		return result;
	}
}
