/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.ui.forms.internal;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import java.util.*;
import org.eclipse.swt.SWT;

/**
 * This implementation of the layout algorithm
 * attempts to position controls in the composite
 * using a two-pass autolayout HTML table altorithm
 * recommeded by HTML 4.01 W3C specification.
 * The main differences with GridLayout is that
 * it has two passes and that width and height
 * are not calculated in the same pass.
 * <p>
 * The advantage of the algorithm over GridLayout
 * is that it is capable of flowing text controls
 * capable of line wrap. These controls do not
 * have natural 'preferred size'. Instead, 
 * they are capable of providing the required
 * height if the width is set. Consequently,
 * this algorithm first calculates the widths
 * that will be assigned to columns, and then
 * passes those widths to the controls to
 * calculate the height. When a composite
 * with this layout is a child of the scrolling
 * composite, they should interact in such
 * a way that reduction in the scrolling composite
 * width results in the reflow and increase of
 * the overall height.
 * <p>
 * If none of the columns contain expandable
 * and wrappable controls, the end-result
 * will be similar to the one provided
 * by GridLayout. The difference will
 * show up for layouts that contain
 * controls whose minimum and maximum
 * widths are not the same.
 */

public class HTMLTableLayout extends Layout implements ILayoutExtension {
	public int numColumns = 1;
	public int leftMargin = 5;
	public int rightMargin = 5;
	public int topMargin = 5;
	public int bottomMargin = 5;
	public int horizontalSpacing = 5;
	public int verticalSpacing = 5;
	public boolean makeColumnsEqualWidth = false;
	
	private boolean initialLayout=true;
	private Vector grid = null;
	private int [] minColumnWidths, maxColumnWidths;
	private int widestColumnWidth;
	private int [] growingColumns;
	
	public int getMinimumWidth(Composite parent, boolean changed) {
		changed = true;
		initializeIfNeeded(parent, changed);
		if (initialLayout) {
		   changed = true;
		   initialLayout = false;
		}
		if (grid==null || changed) {
		   changed = true;
		   grid = new Vector();
		   createGrid(parent);
		}
		if (minColumnWidths==null)
		   minColumnWidths = new int [numColumns];
		for (int i=0; i<numColumns; i++) {
			minColumnWidths[i] = 0;
		}
		return internalGetMinimumWidth(parent, changed);
	}
	
	public int getMaximumWidth(Composite parent, boolean changed) {
		changed = true;
		initializeIfNeeded(parent, changed);
		if (initialLayout) {
		   changed = true;
		   initialLayout = false;
		}
		if (grid==null || changed) {
		   changed = true;
		   grid = new Vector();
		   createGrid(parent);
		}
		if (maxColumnWidths==null)
		   maxColumnWidths = new int[numColumns];
		for (int i=0; i<numColumns; i++) {
			maxColumnWidths[i] = 0;
		}
		return internalGetMaximumWidth(parent, changed);
	}
	
	/**
	 * @see Layout#layout(Composite, boolean)
	 */
	protected void layout(Composite parent, boolean changed) {
		Rectangle clientArea = parent.getClientArea();
		Control [] children = parent.getChildren();
		if (children.length ==0) return;
		int parentWidth = clientArea.width;
		changed = true;
		initializeIfNeeded(parent, changed);
		if (initialLayout) {
		   changed = true;
		   initialLayout = false;
		}
		if (grid==null || changed) {
		   changed = true;
		   grid = new Vector();
		   createGrid(parent);
		}
		resetColumnWidths();
		int minWidth = internalGetMinimumWidth(parent, changed);
		int maxWidth = internalGetMaximumWidth(parent, changed);
		
		int tableWidth = parentWidth;
		
		int [] columnWidths;
		
		if (parentWidth < minWidth) {
		   tableWidth = minWidth;
		   if (makeColumnsEqualWidth) {
		      columnWidths = new int[numColumns];
		      for (int i=0; i<numColumns; i++) {
		      	columnWidths[i] = widestColumnWidth;
		      }
		   }
		   else
		      columnWidths = minColumnWidths;
		}
		else if (parentWidth > maxWidth) {
			if (growingColumns.length==0) {
		   		tableWidth = maxWidth;
		   		columnWidths = maxColumnWidths;
			}
			else {
				columnWidths = new int [numColumns];
				int colSpace = tableWidth - leftMargin - rightMargin;
				colSpace -= (numColumns-1)*horizontalSpacing;
				int extra = parentWidth - maxWidth;
				int colExtra = extra / growingColumns.length;
				for (int i=0; i<numColumns; i++) {
					columnWidths[i] = maxColumnWidths[i];
				
					if (isGrowingColumn(i)) {
						columnWidths[i] += colExtra;
					}
				}
			}
		}
		else {
			columnWidths = new int [numColumns];
			if (makeColumnsEqualWidth) {
				int colSpace = tableWidth - leftMargin - rightMargin;
				colSpace -= (numColumns-1)*horizontalSpacing;
				int col = colSpace/numColumns;
				for (int i=0; i<numColumns; i++) {
					columnWidths[i] = col;
				}
			}
			else {
			   int [] extraSpace = calculateExtraSpace(tableWidth, maxWidth, minWidth);
			   for (int i=0; i<numColumns; i++) {
				  int minCWidth = minColumnWidths[i];
		   		  columnWidths[i] = minCWidth + extraSpace[i];
			   }
			}
		}
		int x = 0;
		int y = topMargin;
		// assign widths 
		for (int i=0; i<grid.size(); i++) {
			TableData [] row = (TableData [])grid.elementAt(i);
			// assign widths, calculate heights
			int rowHeight = 0;
			x = leftMargin;
			for (int j=0; j<numColumns; j++) {
				TableData td = row[j];
				if (td.isItemData==false) {
					continue;
				}
				Control child = children[td.childIndex];
				int span = td.colspan;
				int cwidth = 0;
				for (int k=j; k<j+span; k++) {
					cwidth += columnWidths[k];
					if (k<j+span-1) cwidth += horizontalSpacing;
				}
				Point size = computeSize(child, cwidth, changed);
				td.compWidth = cwidth;
				if (td.heightHint!=SWT.DEFAULT) {
					size = new Point(size.x, td.heightHint);
				}
				td.compSize = size;
				rowHeight = Math.max(rowHeight, size.y);
			}
			for (int j=0; j<numColumns; j++) {
				TableData td = row[j];
				if (td.isItemData==false) {
					continue;
				}
				Control child = children[td.childIndex];
				placeControl(child, td, x, y, rowHeight);
				x += td.compWidth;
				if (j<numColumns-1) x+= horizontalSpacing;		
			}
			y += rowHeight + verticalSpacing;
		}
	}
	
boolean isGrowingColumn(int col) {
	if (growingColumns==null) return false;
	for (int i=0; i<growingColumns.length; i++) {
		if (col == growingColumns[i]) return true;
	}
	return false;
}	
	
int [] calculateExtraSpace(int tableWidth, int maxWidth, int minWidth) {
	int fixedPart = leftMargin + rightMargin + (numColumns-1)*horizontalSpacing;
	int D = maxWidth - minWidth;
	
	int W = tableWidth -fixedPart - minWidth;
	
	int extraSpace [] = new int [numColumns];

	int rem = 0;
	for (int i=0; i<numColumns; i++) { 
		int cmin = minColumnWidths[i];
		int cmax = maxColumnWidths[i];
		int d = cmax - cmin;
		int extra = D!=0 ? (d * W)/D : 0;
		if (i<numColumns-1) {
			extraSpace [i] = extra;
			rem += extra;
		}
		else {
			extraSpace[i] = W - rem;
		}
	}
	return extraSpace;
}
	
Point computeSize(Control child, int width, boolean changed) {
	int widthArg = width;
	if (!isWrap(child))
	   widthArg = SWT.DEFAULT;
	Point size = child.computeSize(widthArg, SWT.DEFAULT, changed);
	return size;
}

void placeControl(Control control, TableData td, int x, int y, int rowHeight) {
	int xloc = x + td.indent;
	int yloc = y;
	int width = td.compSize.x;
	int height = td.compSize.y;
	int colWidth = td.compWidth;
	
	// align horizontally
	if (td.align==TableData.CENTER) {
		xloc = x + colWidth/2 - width/2;
	}
	else if (td.align==TableData.RIGHT) {
		xloc = x + colWidth - width;
	}
	else if (td.align==TableData.FILL) {
		width = colWidth;
	}
	// align vertically
	if (td.valign == TableData.MIDDLE) {
		yloc = y + rowHeight/2 - height/2;
	}
	else if (td.valign==TableData.BOTTOM) {
		yloc = y + rowHeight - height;
	}
	else if (td.valign==TableData.FILL) {
		height = rowHeight;	
	}
	control.setBounds(xloc, yloc, width, height);
}

void createGrid(Composite composite) {
	int row, column, rowFill, columnFill;
	Control[] children;
	TableData spacerSpec;
	Vector growingCols = new Vector();

	// 
	children = composite.getChildren();
	if (children.length==0) return;

	// 
	grid.addElement(createEmptyRow());
	row = 0;
	column = 0;

	// Loop through the children and place their associated layout specs in the
	// grid.  Placement occurs left to right, top to bottom (i.e., by row).
	for (int i = 0; i < children.length; i++) {
		// Find the first available spot in the grid.
		Control child = children[i];
		TableData spec = (TableData) child.getLayoutData();
		while (((TableData[]) grid.elementAt(row))[column] != null) {
			column = column + 1;
			if (column >= numColumns) {
				row = row + 1;
				column = 0;
				if (row >= grid.size()) {
					grid.addElement(createEmptyRow());
				}
			}
		}
		// See if the place will support the widget's horizontal span.  If not, go to the
		// next row.
		if (column + spec.colspan - 1 >= numColumns) {
			grid.addElement(createEmptyRow());
			row = row + 1;
			column = 0;
		}

		// The vertical span for the item will be at least 1.  If it is > 1,
		// add other rows to the grid.
		for (int j = 2; j <= spec.rowspan; j++) {
			if (row + j > grid.size()) {
				grid.addElement(createEmptyRow());
			}
		}

		// Store the layout spec.  Also cache the childIndex.  NOTE: That we assume the children of a
		// composite are maintained in the order in which they are created and added to the composite.
		((TableData[]) grid.elementAt(row))[column] = spec;
		spec.childIndex = i;
		
		if (spec.grabHorizontal) {
			updateGrowingColumns(growingCols, spec, column);
		}

		// Put spacers in the grid to account for the item's vertical and horizontal
		// span.
		rowFill = spec.rowspan - 1;
		columnFill = spec.colspan - 1;
		for (int r = 1; r <= rowFill; r++) {
			for (int c = 0; c < spec.colspan; c++) {
				spacerSpec = new TableData();
				spacerSpec.isItemData = false;
				((TableData[]) grid.elementAt(row + r))[column + c] = spacerSpec;
			}
		}
		for (int c = 1; c <= columnFill; c++) {
			for (int r = 0; r < spec.rowspan; r++) {
				spacerSpec = new TableData();
				spacerSpec.isItemData = false;
				((TableData[]) grid.elementAt(row + r))[column + c] = spacerSpec;
			}
		}
		column = column + spec.colspan - 1;
	}

	// Fill out empty grid cells with spacers.
	for (int k = column + 1; k < numColumns; k++) {
		spacerSpec = new TableData();
		spacerSpec.isItemData = false;
		((TableData[]) grid.elementAt(row))[k] = spacerSpec;
	}
	for (int k = row + 1; k < grid.size(); k++) {
		spacerSpec = new TableData();
		spacerSpec.isItemData = false;
		((TableData[]) grid.elementAt(k))[column] = spacerSpec;
	}
	growingColumns = new int [growingCols.size()];
	for (int i=0; i<growingCols.size(); i++) {
		growingColumns[i] = ((Integer)growingCols.get(i)).intValue();
	}
}

private void updateGrowingColumns(Vector growingColumns, TableData spec, int column) {
	int affectedColumn = column + spec.colspan -1;
	for (int i=0; i<growingColumns.size(); i++) {
		Integer col = (Integer)growingColumns.get(i);
		if (col.intValue()==affectedColumn)
		   return;
	}
	growingColumns.add(new Integer(affectedColumn));
}

private TableData [] createEmptyRow() {
	TableData [] row = new TableData[numColumns];
	for (int i=0; i<numColumns; i++) 
	   row[i] = null;
	return row;
}

	/**
	 * @see Layout#computeSize(Composite, int, int, boolean)
	 */
	protected Point computeSize(Composite parent, int wHint, int hHint, boolean changed) {
		Control [] children = parent.getChildren();
		if (children.length == 0) {
			return new Point(0, 0);
		}
		int parentWidth = wHint;
		changed = true;
		initializeIfNeeded(parent, changed);
		if (initialLayout) {
		   changed = true;
		   initialLayout = false;
		}
		if (grid==null || changed) {
		   changed = true;
		   grid = new Vector();
		   createGrid(parent);
		}
		resetColumnWidths();
		int minWidth = internalGetMinimumWidth(parent, changed);
		int maxWidth = internalGetMaximumWidth(parent, changed);
		
		int tableWidth = parentWidth;
		
		int [] columnWidths;
		
		if (parentWidth < minWidth) {
		   tableWidth = minWidth;
		   if (makeColumnsEqualWidth) {
		      columnWidths = new int[numColumns];
		      for (int i=0; i<numColumns; i++) {
		      	columnWidths[i] = widestColumnWidth;
		      }
		   }
		   else
		      columnWidths = minColumnWidths;
		}
		else if (parentWidth > maxWidth) {
			if (makeColumnsEqualWidth) {
				columnWidths = new int [numColumns];
				int colSpace = parentWidth - leftMargin - rightMargin;
				colSpace -= (numColumns-1)*horizontalSpacing;
				int col = colSpace/numColumns;
				for (int i=0; i<numColumns; i++) {
					columnWidths[i] = col;
				}
			}
			else {
		   		tableWidth = maxWidth;
		   		columnWidths = maxColumnWidths;
			}
		}
		else {
			columnWidths = new int [numColumns];
			if (makeColumnsEqualWidth) {
				int colSpace = tableWidth - leftMargin - rightMargin;
				colSpace -= (numColumns-1)*horizontalSpacing;
				int col = colSpace/numColumns;
				for (int i=0; i<numColumns; i++) {
					columnWidths[i] = col;
				}
			}
			else {
			   int [] extraSpace = calculateExtraSpace(tableWidth, maxWidth, minWidth);
			   for (int i=0; i<numColumns; i++) {
				  int minCWidth = minColumnWidths[i];
		   		  columnWidths[i] = minCWidth + extraSpace[i];
			   }
			}
		}
		int totalHeight=0;
		int y = topMargin;
		// compute widths 
		for (int i=0; i<grid.size(); i++) {
			TableData [] row = (TableData [])grid.elementAt(i);
			// assign widths, calculate heights
			int rowHeight = 0;
			for (int j=0; j<numColumns; j++) {
				TableData td = row[j];
				if (td.isItemData==false) {
					continue;
				}
				Control child = children[td.childIndex];
				int span = td.colspan;
				int cwidth = 0;
				for (int k=j; k<j+span; k++) {
					if (k>j) cwidth += horizontalSpacing;
					cwidth += columnWidths[k];
				}
				int cy = td.heightHint;
				if (cy == SWT.DEFAULT) {
				   Point size = computeSize(child, cwidth, changed);
				   cy = size.y;
				}
				rowHeight = Math.max(rowHeight, cy);
			}
			y += rowHeight + verticalSpacing;
		}
		totalHeight = y + bottomMargin;
		return new Point(tableWidth, totalHeight);
	}

	int internalGetMinimumWidth(Composite parent, boolean changed) {
		if (changed)
		   calculateMinimumColumnWidths(parent, true);
		int minimumWidth = 0;
		
		widestColumnWidth = 0;
		
		if (makeColumnsEqualWidth) {
			for (int i=0; i<numColumns; i++) {
				widestColumnWidth = Math.max(widestColumnWidth, minColumnWidths[i]);
			}
		}
		for (int i=0; i<numColumns; i++) {
			if (i>0) minimumWidth += horizontalSpacing;
			if (makeColumnsEqualWidth)
			   minimumWidth += widestColumnWidth;
			else
			   minimumWidth += minColumnWidths[i];
		}
		// add margins
		minimumWidth += leftMargin + rightMargin;
		return minimumWidth;
	}
	
	int internalGetMaximumWidth(Composite parent, boolean changed) {
		if (changed)
		   calculateMaximumColumnWidths(parent, true);
		int maximumWidth = 0;
		for (int i=0; i<numColumns; i++) {
			if (i>0) maximumWidth += horizontalSpacing;
			maximumWidth += maxColumnWidths[i];
		}
		// add margins
		maximumWidth += leftMargin + rightMargin;
		return maximumWidth;
	}
	
	void resetColumnWidths() {
		if (minColumnWidths == null)
		   minColumnWidths = new int [numColumns];
		if (maxColumnWidths == null)
		   maxColumnWidths = new int [numColumns];
		for (int i=0; i<numColumns; i++) {
			minColumnWidths [i] = 0;
		}
		for (int i=0; i<numColumns; i++) {
			maxColumnWidths [i] = 0;
		}
	}

	void calculateMinimumColumnWidths(Composite parent, boolean changed) {
		Control [] children = parent.getChildren();
		
		for (int i=0; i<grid.size(); i++) {
			TableData [] row = (TableData [])grid.elementAt(i);
			for (int j=0; j<numColumns; j++) {
				TableData td = row[j];
				if (td.isItemData==false) continue;
				Control child = children[td.childIndex];
				int minWidth = -1;
				if (child instanceof Composite) {
					Composite cc = (Composite)child;
					Layout l = cc.getLayout();
					if (l instanceof ILayoutExtension) {
						minWidth = ((ILayoutExtension)l).getMinimumWidth(cc, changed);
					}
				}
				if (minWidth == -1) {
					if (isWrap(child)) {
						// Should be the width of the
						// longest word, we'll pick
						// some small number instead
						minWidth = 30;
					}
					else {
					   Point size = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
					   minWidth = size.x;
					}
				}
				minWidth += td.indent;
				minColumnWidths[j] = Math.max(minColumnWidths[j], minWidth);
			}
		}
	}
	
	boolean isWrap(Control control) {
		if (control instanceof Composite &&
		   ((Composite)control).getLayout() instanceof ILayoutExtension)
		   return true;
		return (control.getStyle() & SWT.WRAP)!=0;
	}
	
	void calculateMaximumColumnWidths(Composite parent, boolean changed) {
		Control [] children = parent.getChildren();
		
		for (int i=0; i<numColumns; i++) {
			maxColumnWidths [i] = 0;
		}
		for (int i=0; i<grid.size(); i++) {
			TableData [] row = (TableData [])grid.elementAt(i);
			for (int j=0; j<numColumns; j++) {
				TableData td = row[j];
				if (td.isItemData==false) continue;
				Control child = children[td.childIndex];
				int maxWidth = -1;
				if (child instanceof Composite) {
					Composite cc = (Composite)child;
					Layout l = cc.getLayout();
					if (l instanceof ILayoutExtension) {
						maxWidth = ((ILayoutExtension)l).getMaximumWidth(cc, changed);
					}
				}
				if (maxWidth == -1) {
					Point size = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
					maxWidth = size.x;
				}
				maxWidth += td.indent;
				if (td.colspan==1)
				   maxColumnWidths[j] = Math.max(maxColumnWidths[j], maxWidth);
				else {
					// grow the last column
					int last = j + td.colspan -1;
					int rem = 0;
					for (int k=j; k<j+td.colspan-1; k++) {
						rem += maxColumnWidths[k];
					}
					int reduced = maxWidth - rem;
					maxColumnWidths[last] = Math.max(maxColumnWidths[last], reduced);
				}
			}
		}
	}
	
private void initializeIfNeeded(Composite parent, boolean changed) {
	if (changed)
	   	initialLayout = true;
	if (initialLayout) {
		initializeLayoutData(parent);
		initialLayout = false;
	}
}
	
void initializeLayoutData(Composite composite) {
	Control[] children = composite.getChildren();
	for (int i = 0; i < children.length; i++) {
		Control child = children[i];
		if (child.getLayoutData() == null) {
			child.setLayoutData(new TableData());
		}
	}
}
}
