/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout.table;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
import org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
import org.eclipse.swt.SWT;

/**
 * see also http://www.w3.org/TR/REC-CSS2/tables.html
 * 
 * @author mengbo
 * @version 1.5
 */
public class CSSTableLayout2 extends CSSBlockFlowLayout implements ICSSPainter {
	static Logger _log = PDPlugin.getLogger(CSSTableLayout2.class);

	int _hspacing;

	int _vspacing;

	int[] _columnWidths;

	int[] _rowHeights;

	Dimension _captionSize;

	// _tableInfo will be initialized in preLayout
	TableInfo _tableInfo;

	private int _internalTableWidth;

	private int _internalTableHeight;

	private int _rowx;

	private int _rowwidth;

	/**
	 * @param flowfigure
	 */
	public CSSTableLayout2(CSSFigure flowfigure) {
		super(flowfigure);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#preLayout()
	 */
	protected void preLayout() {
		// super.preLayout will setup the block box.
		super.preLayout();

		ICSSStyle style = this.getCSSStyle();

		_hspacing = _vspacing = 3; // default value

		if (style != null) {
			Object borderspacing = style
					.getStyleProperty(ICSSPropertyID.ATTR_BORDER_SPACING);
			if (borderspacing instanceof int[]) {
				int[] intvalues = (int[]) borderspacing;
				_hspacing = intvalues[0];
				_vspacing = intvalues[1];
			} else {
				ITagEditInfo info = (ITagEditInfo) style
						.getAdapter(ITagEditInfo.class);
				if (info != null && info.needTableDecorator()) {
					// default decorating value. to make things look more
					// separated.
					if (_hspacing < 5) {
						_hspacing = 5;
					}
					if (_vspacing < 5) {
						_vspacing = 5;
					}
				}
			}
		}

		// TODO: support caption
		_tableInfo = new TableInfo(getCSSFigure());

		// construct the table structure.
		_tableInfo.constructTable();

		// calculate the user specified width/height for table and cells.
		// contentWidth is the user specified content width. If <= 0 means no
		// user
		// specification.
		int contentWidth = this._blockBox.getContentWidth();
		int availableWidth = this._blockBox.getRecommendedContentWidth();
		int contentHeight = this._blockBox.getContentHeight();

		_tableInfo.calculateWidth(contentWidth, availableWidth);
		_tableInfo.calculateHeight(contentHeight);

		int columnCount = _tableInfo.getColumnCount();

		int columnMinWidths[] = new int[columnCount];
		int columnMaxWidths[] = new int[columnCount];

		// For each column, determine a maximum and minimum column width from
		// the cells that span only that column. The minimum is that required by
		// the cell with the largest minimum cell width (or the column 'width',
		// whichever is larger). The maximum is that required by the cell with
		// the
		// largest maximum cell width (or the column 'width', whichever is
		// larger).
		List cells = _tableInfo.getCells();
		for (int i = 0, size = cells.size(); i < size; i++) {
			TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
			if (cellinfo.getColSpan() == 1) {
				int column = cellinfo.getColumnIndex();
				Dimension mincw = cellinfo.getMinCWDimension();
				Dimension maxcw = cellinfo.getMaxCWDimension();
				if (maxcw.width < mincw.width) {
					maxcw.width = mincw.width;
				}
				if (mincw.width > columnMinWidths[column]) {
					columnMinWidths[column] = mincw.width;
				}
				if (maxcw.width > columnMaxWidths[column]) {
					columnMaxWidths[column] = maxcw.width;
				}
			}
		}
		// For caption, determine a maximum and minimum width from it.
		int captionWidth = 0;
		if (_tableInfo.getCaption() != null) {
			captionWidth = _tableInfo.getCaption().getDimension().width;
		}

		// For each cell that spans more than one column, increase the
		// minimum widths of the columns it spans so that together, they
		// are at least as wide as the cell. Do the same for the maximum
		// widths. If possible, widen all spanned columns by approximately
		// the same amount.
		for (int i = 0, size = cells.size(); i < size; i++) {
			TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
			int colspan = cellinfo.getColSpan();
			if (colspan > 1) {
				int column = cellinfo.getColumnIndex();
				Dimension mincw = cellinfo.getMinCWDimension();
				Dimension maxcw = cellinfo.getMaxCWDimension();

				adjustWidth(column, colspan, mincw.width, columnMinWidths);
				adjustWidth(column, colspan, maxcw.width, columnMaxWidths);
			}
		}

		int sigmaMinWidth = 0;
		int sigmaMaxWidth = 0;
		for (int i = 0; i < columnMinWidths.length; i++) {
			sigmaMinWidth += columnMinWidths[i];
			if (columnMaxWidths[i] == Integer.MAX_VALUE) {
				sigmaMaxWidth = Integer.MAX_VALUE;
			} else if (sigmaMaxWidth != Integer.MAX_VALUE) {
				sigmaMaxWidth += columnMaxWidths[i];
				if (sigmaMaxWidth < 0) {
					sigmaMaxWidth = Integer.MAX_VALUE;
				}
			}
		}
		int spacingall = (columnMinWidths.length + 1) * _hspacing;
		sigmaMinWidth += spacingall;
		if (sigmaMaxWidth != Integer.MAX_VALUE) {
			sigmaMaxWidth += spacingall;
			if (sigmaMaxWidth < 0) {
				sigmaMaxWidth = Integer.MAX_VALUE;
			}
		}

		int tableWidth = _tableInfo.getTableWidth();
		if (tableWidth > 0) {
			// If the 'table' or 'inline-table' element's 'width' property has a
			// specified value (W) other than 'auto', the property's computed
			// value
			// is the greater of W and the minimum width required by all the
			// columns
			// plus cell spacing or borders (MIN). If W is greater than MIN, the
			// extra
			// width should be distributed over the columns.
			int maxMin = Math.max(captionWidth, sigmaMinWidth);
			if (maxMin >= tableWidth) {
				tableWidth = maxMin;
			}
			distribute(tableWidth - sigmaMinWidth, columnMinWidths,
					columnMaxWidths);
		} else {
			// If the 'table' or 'inline-table' element has 'width: auto', the
			// computed
			// table width is the greater of the table's containing block width
			// and MIN.
			// However, if the maximum width required by the columns plus cell
			// spacing or
			// borders (MAX) is less than that of the containing block, use MAX.
			// int availableWidth = this.getCurrentLine().getAvailableWidth();
			int maxMin = Math.max(captionWidth, sigmaMaxWidth);
			if (maxMin <= availableWidth) {
				// TODO: if _tableInfo.hasWidthPercentage, then we need take
				// that into consideration
				// to distribute the column width. Left to next version.
				tableWidth = maxMin;
				// columnMinWidths = columnMaxWidths;
			} else {
				tableWidth = availableWidth;
			}
			distribute(tableWidth - sigmaMinWidth, columnMinWidths,
					columnMaxWidths);
		}

		// now columnMinWidths contains width for each column
		_columnWidths = columnMinWidths;

		// ok, we have finished calculating column width.
		// next we need to find out row heights.
		_rowHeights = new int[_tableInfo.getRowCount()];

		// first find out those TR that has height settings and use them.
		List rows = _tableInfo.getRows();
		for (int i = 0, size = rows.size(); i < size && i < _rowHeights.length; i++) {
			TableRowInfo rowInfo = (TableRowInfo) rows.get(i);
			if (rowInfo.getSpecifiedRowHeight() > 0) {
				_rowHeights[i] = rowInfo.getSpecifiedRowHeight();
			}
		}

		// First the cells don't span multiple rows.
		cells = _tableInfo.getCells();
		for (int i = 0, size = cells.size(); i < size; i++) {
			TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
			IFigure figure = cellinfo.getFigure();
			int rowspan = cellinfo.getRowSpan();
			if (rowspan == 1) {
				int cellWidth = getCellWidth(cellinfo, _columnWidths);
				Dimension d = figure.getPreferredSize(cellWidth, cellinfo
						.getHeight());
				if (d.height > _rowHeights[cellinfo.getRowIndex()]) {
					_rowHeights[cellinfo.getRowIndex()] = d.height;
				}
			}
		}

		// Next those cells span multiple rows.
		cells = _tableInfo.getCells();
		for (int i = 0, size = cells.size(); i < size; i++) {
			TableCellInfo cellinfo = (TableCellInfo) cells.get(i);
			IFigure figure = cellinfo.getFigure();
			int rowspan = cellinfo.getRowSpan();
			if (rowspan > 1) {
				int cellWidth = getCellWidth(cellinfo, _columnWidths);
				Dimension d = figure.getPreferredSize(cellWidth, cellinfo
						.getHeight());
				if (d.height > getCellHeight(cellinfo, _rowHeights)) {
					adjustHeight(cellinfo.getRowIndex(), rowspan, d.height,
							_rowHeights);
				}
			}
		}

		// Next we may need distribute height.
		int sigmaHeight = (_tableInfo.getRowCount() + 1) * _vspacing;
		for (int i = 0; i < _rowHeights.length; i++) {
			sigmaHeight += _rowHeights[i];
		}
		if (sigmaHeight < contentHeight) {
			distributeHeights(contentHeight - sigmaHeight, _rowHeights);
		}

		// now we have calculated the width and height of all cells.
		// FIXME: border?
		Insets insets = (style == null ? new Insets() : style.getBorderInsets()
				.getAdded(style.getPaddingInsets()));
		_internalTableWidth = (_tableInfo.getColumnCount() + 1) * _hspacing;
		for (int i = 0; i < _columnWidths.length; i++) {
			_internalTableWidth += _columnWidths[i];
		}
		int minWidth = getLengthValue(style, ICSSPropertyID.ATTR_MIN_WIDTH);
		_internalTableWidth = _internalTableWidth > minWidth ? _internalTableWidth
				: minWidth;

		_blockBox.setWidth(_internalTableWidth + insets.getWidth());
		_internalTableHeight = (_tableInfo.getRowCount() + 1) * _vspacing;
		for (int i = 0; i < _rowHeights.length; i++) {
			_internalTableHeight += _rowHeights[i];
		}
		int minHeight = getLengthValue(style, ICSSPropertyID.ATTR_MIN_HEIGHT);
		_internalTableHeight = _internalTableHeight > minHeight ? _internalTableHeight
				: minHeight;

		int captionHeight = 0;
		if (_tableInfo.getCaption() != null) {
			_captionSize = _tableInfo.getCaption().getFigure().getPreferredSize(
					_internalTableWidth, SWT.DEFAULT);
			captionHeight = _captionSize.height;
		} else {
			_captionSize = null;
		}
		_internalTableHeight += captionHeight;

		_blockBox.setHeight(_internalTableHeight + insets.getHeight());

		_rowwidth = _internalTableWidth - 2 * _hspacing;
		_rowx = _hspacing; // XXX: table border width left?
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#endBlock()
	 */
	protected void endBlock() {
		_blockBox.setWidth(_internalTableWidth
				+ _blockBox.getBorderPaddingWidth());
		_blockBox.setHeight(_internalTableHeight
				+ _blockBox.getBorderPaddingHeight());
		super.endBlock();
	}

	//
	// /**
	// * when some of the column has percentage width, and sigmaMax smaller than
	// container,
	// * @param containerWidth
	// * @param columnMinWidths
	// * @param columnMaxWidths
	// * @return
	// */
	// private int distribute2(int containerWidth, int[] columnMinWidths, int[]
	// columnMaxWidths)
	// {
	//        
	// }
	//    
	/**
	 * Distribute the additional width to columnMinWidths, using max width as a
	 * possible reference on how to distribute.
	 * 
	 * @param toDistribute
	 * @param columnMinWidths
	 * @param columnMaxWidths
	 */
	private void distribute(int toDistribute, int[] columnMinWidths,
			int[] columnMaxWidths) {
		if (toDistribute <= 0)
			return;
		if (columnMinWidths.length == 0)
			return;

		int[] delta = new int[columnMinWidths.length];
		int sigmaDelta = 0;
		for (int i = 0; i < columnMinWidths.length && toDistribute > 0; i++) {
			if (_tableInfo.getWidthSpecified()[i]) {
				delta[i] = 0;
			} else {
				delta[i] = columnMaxWidths[i] - columnMinWidths[i];
				if (delta[i] <= 0) {
					delta[i] = 0;
				}
				sigmaDelta += delta[i];
			}
		}
		if (sigmaDelta == 0) {
			// should not happen, but anyway, distribute all to the last column
			// columnMinWidths[columnMinWidths.length-1] += toDistribute;
			averageDeltaToCell(columnMinWidths, toDistribute);
		} else {
			int left = toDistribute;
			for (int i = 0; i < columnMinWidths.length - 1; i++) {
				if (delta[i] > 0) {
					int add = delta[i] * toDistribute / sigmaDelta;
					left -= add;
					columnMinWidths[i] += add;
				}
			}
			columnMinWidths[columnMinWidths.length - 1] += left;
		}
	}

	private void averageDeltaToCell(int[] columnMinWidths, int toDistribute) {

		if (toDistribute <= 0) {
			return;
		}
		ArrayList list = new ArrayList();
		for (int i = 0; i < columnMinWidths.length; i++) {
			if (!_tableInfo.getWidthSpecified()[i]) {
				list.add(new Integer(i));
			}
		}
		if (list.size() == 0) {
			for (int i = 0; i < columnMinWidths.length; i++) {
				list.add(new Integer(i));
			}
		}
		int padding = toDistribute / list.size();
		int left = toDistribute % list.size();
		for (int i = 0, n = list.size(); i < n; i++) {
			columnMinWidths[((Integer) list.get(i)).intValue()] += padding;
		}
		if (left > 0) {
			for (int i = 0; i < left; i++) {
				columnMinWidths[((Integer) list.get(i)).intValue()] += 1;
			}
		}
	}

	/**
	 * @param i
	 * @param heights
	 */
	private void distributeHeights(int toDistribute, int[] heights) {
		if (heights.length == 0)
			return;
		int eachDelta = toDistribute / heights.length;
		for (int i = 0; i < heights.length - 1; i++) {
			heights[i] += eachDelta;
		}
		heights[heights.length - 1] += toDistribute - (heights.length - 1)
				* eachDelta;
	}

	/**
	 * @param cellinfo
	 * @param heights
	 * @return the cell height
	 */
	public int getCellHeight(TableCellInfo cellinfo, int[] heights) {
		int rowIndex = cellinfo.getRowIndex();
		int rowspan = cellinfo.getRowSpan();
		int h = 0;
		for (int i = 0; i < rowspan; i++) {
			h += heights[rowIndex + i];
		}
		h += (rowspan - 1) * _vspacing;
		return h;
	}

	/**
	 * @param cellinfo
	 * @param widths
	 * @return the cell width
	 */
	public int getCellWidth(TableCellInfo cellinfo, int[] widths) {
		int columnIndex = cellinfo.getColumnIndex();
		int colspan = cellinfo.getColSpan();
		int w = 0;
		for (int i = 0; i < colspan; i++) {
			w += widths[columnIndex + i];
		}
		w += (colspan - 1) * _hspacing;
		return w;
	}

	/**
	 * @param column
	 *            the start column
	 * @param colspan
	 *            number of columns
	 * @param width
	 *            desired width
	 * @param columnWidths
	 *            current columns widths. After the adjust, need make sure the
	 *            columnWidths to be bigger than desired width
	 */
	private void adjustWidth(int column, int colspan, int width,
			int[] columnWidths) {
		adjustSpan(column, colspan, width, columnWidths, _hspacing);
	}

	/**
	 * @see #adjustWidth(int, int, int, int[])
	 */
	private void adjustHeight(int rowIndex, int rowspan, int height,
			int[] heights) {
		adjustSpan(rowIndex, rowspan, height, heights, _vspacing);
	}

	static private void adjustSpan(int column, int colspan, int width,
			int[] columnWidths, int spacing) {
		int spanwidth = 0;
		for (int i = 0; i < colspan; i++) {
			spanwidth += columnWidths[column + i];
		}
		// XXX: vspacing here?
		spanwidth += (colspan - 1) * spacing;

		if (spanwidth >= width) {
			return;
		}
        int delta = width - spanwidth;
        int deltaeach = delta / colspan;
        for (int i = 0; i < colspan - 1; i++) {
        	columnWidths[column + i] += deltaeach;
        }
        columnWidths[column + colspan - 1] += (delta - (colspan - 1)
        		* deltaeach);
	}

	/**
	 * @return the row heights
	 */
	public int[] getRowHeights() {
		return _rowHeights;
	}

	/**
	 * @return the column widths
	 */
	public int[] getColumnWidths() {
		return _columnWidths;
	}

	/**
	 * @return the vertical spacing value
	 */
	public int getVSpacing() {
		return _vspacing;
	}

	/**
	 * @return the horizontal spacing value
	 */
	public int getHSpacing() {
		return _hspacing;
	}

	/**
	 * @param figure
	 * @return the table row info for the figure
	 */
	public TableRowInfo getRowInfo(CSSFigure figure) {
		return _tableInfo.findRowInfo(figure);
	}

	/**
	 * @return the table caption info
	 */
	public TableCaptionInfo getCaptionInfo() {
		return _tableInfo.getCaption();
	}

	/**
	 * @param figure
	 * @return the table row group info for the figure
	 */
	public TableRowGroupInfo getGroupInfo(CSSFigure figure) {
		return _tableInfo.findGroupInfo(figure);
	}

	/**
	 * @return the row's x
	 */
	public int getRowX() {
		return _rowx;
	}

	/**
	 * @return the row's width
	 */
	public int getRowWidth() {
		return _rowwidth;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#shouldExpand()
	 */
	public boolean shouldExpand() {
		return false;
	}

	/**
	 * @return the rendered dimensions of the table caption
	 */
	public Dimension getCaptionSize() {
		return _captionSize;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSPainter#paintFigure(org.eclipse.draw2d.Graphics)
	 */
	public void paintFigure(Graphics g) {
		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			ITagEditInfo info = (ITagEditInfo) style
					.getAdapter(ITagEditInfo.class);
			if (info != null && info.needTableDecorator()) {
				List cells = _tableInfo.getCells();
				for (int i = 0, size = cells.size(); i < size; i++) {
					TableCellInfo cellInfo = (TableCellInfo) cells.get(i);
					IFigure cellfigure = cellInfo.getFigure();
					Rectangle rect = cellfigure.getBounds().getCopy();
					rect = rect.expand(1, 1);
					g.setLineStyle(Graphics.LINE_SOLID);
					g.setLineWidth(1);
					g.setForegroundColor(ColorConstants.lightGray);
					g.drawRectangle(rect);
				}
			}
		}
	}

}
