/*******************************************************************************
 * Copyright (c) 2005, 2010 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.texteditor.templates;

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;

/**
 * Layout for tables, adapted from <code>TableLayoutComposite</code>.
 * <p>
 * XXX: Should switch to use {@link org.eclipse.jface.layout.TableColumnLayout}.
 * </p>
 *
 * @since 3.2
 */
final class ColumnLayout extends Layout {

	private static final String RECALCULATE_LAYOUT= "recalculateKey"; //$NON-NLS-1$

	/**
	 * The number of extra pixels taken as horizontal trim by the table column.
	 * To ensure there are N pixels available for the content of the column,
	 * assign N+COLUMN_TRIM for the column width.
	 * <p>
	 * XXX: Should either switch to use
	 * {@link org.eclipse.jface.layout.TableColumnLayout} or get API from JFace
	 * or SWT, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=218483
	 * </p>
	 *
	 * @since 3.1
	 */
	private static int COLUMN_TRIM;
	static {
		String platform= SWT.getPlatform();
		switch (platform) {
		case "win32": //$NON-NLS-1$
			COLUMN_TRIM= 4;
			break;
		case "carbon": //$NON-NLS-1$
			COLUMN_TRIM= 24;
			break;
		default:
			COLUMN_TRIM= 3;
			break;
		}
	}

	private List<ColumnLayoutData> columns= new ArrayList<>();

	/**
	 * Adds a new column of data to this table layout.
	 *
	 * @param data the column layout data
	 */
	public void addColumnData(ColumnLayoutData data) {
		columns.add(data);
	}

	private Point computeTableSize(Table table, int wHint, int hHint) {
		Point result= table.computeSize(wHint, hHint);

		int width= 0;
		int size= columns.size();
		for (int i= 0; i < size; ++i) {
			ColumnLayoutData layoutData= columns.get(i);
			if (layoutData instanceof ColumnPixelData) {
				ColumnPixelData col= (ColumnPixelData) layoutData;
				width += col.width;
				if (col.addTrim) {
					width += COLUMN_TRIM;
				}
			} else if (layoutData instanceof ColumnWeightData) {
				ColumnWeightData col= (ColumnWeightData) layoutData;
				width += col.minimumWidth;
			} else {
				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
			}
		}
		if (width > result.x)
			result.x= width;
		return result;
	}

	private void layoutTable(final Table table, final int width, final Rectangle area, final boolean increase) {
		final TableColumn[] tableColumns= table.getColumns();
		final int size= Math.min(columns.size(), tableColumns.length);
		final int[] widths= new int[size];

		final int[] weightIteration= new int[size];
		int numberOfWeightColumns= 0;

		int fixedWidth= 0;
		int minWeightWidth= 0;
		int totalWeight= 0;

		// First calc space occupied by fixed columns
		for (int i= 0; i < size; i++) {
			ColumnLayoutData col= columns.get(i);
			if (col instanceof ColumnPixelData) {
				ColumnPixelData cpd= (ColumnPixelData) col;
				int pixels= cpd.width;
				if (cpd.addTrim) {
					pixels += COLUMN_TRIM;
				}
				widths[i]= pixels;
				fixedWidth += pixels;
			} else if (col instanceof ColumnWeightData) {
				ColumnWeightData cw= (ColumnWeightData) col;
				weightIteration[numberOfWeightColumns]= i;
				numberOfWeightColumns++;
				totalWeight += cw.weight;
				minWeightWidth += cw.minimumWidth;
				widths[i]= cw.minimumWidth;
			} else {
				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
			}
		}


		// Do we have columns that have a weight?
		final int restIncludingMinWidths= width - fixedWidth;
		final int rest= restIncludingMinWidths - minWeightWidth;
		if (numberOfWeightColumns > 0 && rest > 0) {

			// Modify the weights to reflect what each column already
			// has due to its minimum. Otherwise, columns with low
			// minimums get discriminated.
			int totalWantedPixels= 0;
			final int[] wantedPixels= new int[numberOfWeightColumns];
			for (int i= 0; i < numberOfWeightColumns; i++) {
				ColumnWeightData cw= (ColumnWeightData) columns.get(weightIteration[i]);
				wantedPixels[i]= totalWeight == 0 ? 0 : cw.weight * restIncludingMinWidths / totalWeight;
				totalWantedPixels+= wantedPixels[i];
			}

			// Now distribute the rest to the columns with weight.
			int totalDistributed= 0;
			for (int i= 0; i < numberOfWeightColumns; ++i) {
				int pixels= totalWantedPixels == 0 ? 0 : wantedPixels[i] * rest / totalWantedPixels;
				totalDistributed += pixels;
				widths[weightIteration[i]] += pixels;
			}

			// Distribute any remaining pixels to columns with weight.
			int diff= rest - totalDistributed;
			for (int i= 0; diff > 0; i= ((i + 1) % numberOfWeightColumns)) {
				++widths[weightIteration[i]];
				--diff;
			}
		}

		if (increase) {
			table.setSize(area.width, area.height);
		}
		for (int i= 0; i < size; i++) {
			tableColumns[i].setWidth(widths[i]);
		}
		if (!increase) {
			table.setSize(area.width, area.height);
		}
	}

	@Override
	protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
		return computeTableSize(getTable(composite), wHint, hHint);
	}

	@Override
	protected void layout(Composite composite, boolean flushCache) {
		Rectangle area= composite.getClientArea();
		Table table= getTable(composite);
		int tableWidth= table.getSize().x;
		int trim= computeTrim(area, table, tableWidth);
		int width= Math.max(0, area.width - trim);

		if (width > 1)
			layoutTable(table, width, area, tableWidth < area.width);

		if( composite.getData(RECALCULATE_LAYOUT) == null ) {
			composite.setData(RECALCULATE_LAYOUT, Boolean.FALSE);
			composite.layout();
		}
	}

	private int computeTrim(Rectangle area, Table table, int tableWidth) {
		Point preferredSize= computeTableSize(table, area.width, area.height);
		int trim;
		if (tableWidth > 1) {
			trim= tableWidth - table.getClientArea().width;
		} else {
			// initially, the table has no extend and no client area - use the border with
			// plus some padding as educated guess
			trim= 2 * table.getBorderWidth() + 1 ;
		}
		if (preferredSize.y > area.height) {
			// Subtract the scrollbar width from the total column width
			// if a vertical scrollbar will be required, but is not currently showing
			// (in which case it is already subtracted above)
			ScrollBar vBar= table.getVerticalBar();
			if (!vBar.isVisible()) {
				Point vBarSize= vBar.getSize();
				trim += vBarSize.x;
			}
		}
		return trim;
	}

	private Table getTable(Composite composite) {
		return (Table) composite.getChildren()[0];
	}

}
