/*******************************************************************************
 * Copyright (c) 2013-2016 Ericsson
 *
 * 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:
 *   Jacques Bouthillier - Initial Implementation of the table view
 ******************************************************************************/
package org.eclipse.egerrit.internal.dashboard.ui.model;

import java.util.Arrays;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.egerrit.internal.dashboard.ui.GerritUi;
import org.eclipse.egerrit.internal.dashboard.ui.commands.table.AdjustMyStarredHandler;
import org.eclipse.egerrit.internal.dashboard.ui.utils.UIUtils;
import org.eclipse.egerrit.internal.dashboard.ui.views.GerritTableView;
import org.eclipse.egerrit.internal.model.ChangeInfo;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider.ColorProvider;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.ui.PlatformUI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class handles the creation of the table widget shown in the dashboard.
 */
public class UIReviewTable {
	private static final String DASHBOARD_CONTEXT_MENU = "org.eclipse.egerrit.dashboard.contextMenu"; //$NON-NLS-1$

	private static final String EGERRIT_DASHBOARD = "egerrit.dashboard"; //$NON-NLS-1$

	private static final String VIEW_COLUMN_ORDER = "egerritViewColumnOrder"; //$NON-NLS-1$

	private static final String VIEW_COLUMN_WIDTH = "egerritViewColumnWidth"; //$NON-NLS-1$

	private static Logger logger = LoggerFactory.getLogger(UIReviewTable.class);

	private static final int TABLE_STYLE = SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;

	private TableViewer fViewer;

	private ComposedAdapterFactory adapterFactory;

	private ColorProvider labelProvider;

	private AdapterFactoryContentProvider contentProvider;

	private int defaultColumn = ReviewTableDefinition.values().length;

	private String[] voteColumns;

	public Composite createTableViewerSection(Composite aParent, String[] voteColumns) {
		this.voteColumns = voteColumns;
		Composite viewerForm = new Composite(aParent, SWT.BORDER | SWT.SHADOW_ETCHED_IN);
		viewerForm.setLayout(new FillLayout());

		// Create the table viewer to maintain the list of reviews
		fViewer = new TableViewer(viewerForm, TABLE_STYLE);
		fViewer = buildAndLayoutTable(fViewer);
		fViewer.getTable().addDisposeListener(e -> storeColumnsSettings());

		// Add a Key event and mouse down listener
		fViewer.getTable().addListener(SWT.MouseDown, mouseButtonListener);

		adapterFactory = new ComposedAdapterFactory();
		adapterFactory.addAdapterFactory(new ModifiedModelItemProviderAdapterFactory(voteColumns));

		contentProvider = new AdapterFactoryContentProvider(adapterFactory);
		fViewer.setContentProvider(contentProvider);

		if (voteColumns != null) {
			setLabelProvider(voteColumns);
		}

		return viewerForm;
	}

	/**
	 * Create the label provider after we defined the dynamic columns
	 *
	 * @param voteColumns
	 */
	private void setLabelProvider(String[] voteColumns) {
		for (String column : voteColumns) {
			createTableViewerLabelColumn(getAcronymLabel(column));
		}

		ReviewTableSorter.bind(fViewer);
		fViewer.setComparator(new ReviewTableSorter(7)); // sort by Updated, descending

		labelProvider = new AdapterFactoryLabelProvider.ColorProvider(adapterFactory, null, null);
		fViewer.setLabelProvider(labelProvider);
		restoreColumnsSettings();
	}

	private String getAcronymLabel(String label) {
		String ret = ""; //$NON-NLS-1$
		if (!label.isEmpty()) {
			String[] arraySt = label.split("-"); //$NON-NLS-1$
			for (String s : arraySt) {
				ret = ret.concat(s.substring(0, 1));
			}
		}
		return ret;
	}

	/**
	 * Create each column for the List of Reviews
	 *
	 * @param aParent
	 * @param aViewer
	 */
	private TableViewer buildAndLayoutTable(final TableViewer aViewer) {
		final Table table = aViewer.getTable();

		//Get the review table definition
		ReviewTableDefinition[] tableInfo = ReviewTableDefinition.values();
		int size = tableInfo.length;
		logger.debug("Table	Name	Width	Resize Moveable"); //$NON-NLS-1$
		for (int index = 0; index < size; index++) {
			logger.debug("index [ " + index + " ] " + tableInfo[index].getName() + "\t: " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
					+ tableInfo[index].getWidth() + "\t: " + tableInfo[index].getResize() + "\t: " //$NON-NLS-1$ //$NON-NLS-2$
					+ tableInfo[index].getMoveable());
			createTableViewerColumn(tableInfo[index]);
		}

		TableLayout tableLayout = new TableLayout();
		table.setLayout(tableLayout);

		handleTooltipNotOnWindow(aViewer, table);

		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		MenuManager menuManager = new MenuManager();
		Menu contextMenu = menuManager.createContextMenu(table);
		table.setMenu(contextMenu);
		GerritTableView.getActiveView(true).getSite().registerContextMenu(DASHBOARD_CONTEXT_MENU, menuManager, aViewer);
		return aViewer;
	}

	/**
	 * Handle the tooltip on a the dashboard table when the operating system is not a window environment
	 *
	 * @param aViewer
	 * @param table
	 */
	private void handleTooltipNotOnWindow(final TableViewer aViewer, final Table table) {
		String os = org.eclipse.core.runtime.Platform.getOS();
		// nothing to do on windows
		if (!Platform.OS_WIN32.equals(os)) {
			final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
			final ToolTip tip = new ToolTip(shell, SWT.ICON_INFORMATION);

			table.addListener(SWT.MouseMove, event -> tip.setVisible(false));

			table.addListener(SWT.MouseHover, event -> {
				ViewerCell viewerCell = UIUtils.getAdjustedViewerCell(event, aViewer);
				if (viewerCell != null) {
					String message = ""; //$NON-NLS-1$
					int columnIndex = viewerCell.getColumnIndex();
					message = adjustSubjectTooltip(viewerCell, columnIndex);
					TableItem item = (TableItem) viewerCell.getViewerRow().getItem();
					Rectangle rect = item.getBounds(columnIndex);
					if (message.isEmpty()) {
						message = item.getText(columnIndex);
					}
					tip.setMessage(message);
					Point displayPos = item.getParent().toDisplay(rect.x, rect.y);
					tip.setLocation(displayPos.x, displayPos.y);
					tip.setVisible(true);
				}
			});
		}
	}

	/**
	 * Use the commit message when hovering the subject column.
	 *
	 * @param viewerCell
	 * @param columnIndex
	 * @return String
	 */
	private String adjustSubjectTooltip(ViewerCell viewerCell, int columnIndex) {
		String message = ""; //$NON-NLS-1$
		if (columnIndex == ReviewTableDefinition.SUBJECT.ordinal()) {
			Object obj = viewerCell.getElement();
			if (obj instanceof ChangeInfo) {
				ChangeInfo changeInfo = (ChangeInfo) obj;
				message = changeInfo.getRevision() != null ? changeInfo.getRevision().getCommit().getMessage() : ""; //$NON-NLS-1$
			}

		}
		return message;
	}

	/**
	 * Create each column in the review table list
	 *
	 * @param ReviewTableDefinition
	 * @return TableViewerColumn
	 */
	private TableViewerColumn createTableViewerColumn(ReviewTableDefinition aTableInfo) {
		final TableViewerColumn viewerColumn = new TableViewerColumn(fViewer, SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		column.setText(aTableInfo.getName());
		column.setWidth(aTableInfo.getWidth());
		column.setAlignment(aTableInfo.getAlignment());
		column.setResizable(aTableInfo.getResize());
		column.setMoveable(aTableInfo.getMoveable());
		return viewerColumn;
	}

	private final Listener mouseButtonListener = aEvent -> {
		logger.debug("mouseButtonListener() for " + aEvent.button); //$NON-NLS-1$
		switch (aEvent.type) {
		case SWT.MouseDown:
			// Left Click, Selection over the STAR column only will activate the request to modify it
			if (aEvent.button == 1) {
				Point p = new Point(aEvent.x, aEvent.y);
				ViewerCell viewerCell = fViewer.getCell(p);
				if (viewerCell != null && viewerCell.getColumnIndex() == ReviewTableDefinition.STARRED.ordinal()) {

					// Execute the command to adjust the column: ID with the
					// starred information
					AdjustMyStarredHandler handler = new AdjustMyStarredHandler();
					try {
						handler.execute(new ExecutionEvent());
					} catch (ExecutionException excutionException) {
						logger.error(excutionException.getMessage());
					}
				}
			}

			// For now, button 2 not used
			if (aEvent.button == 2) {

			}

			// Right Click
			if (aEvent.button == 3) {
				// Process the Item table handling
				// processItemSelection()
			}
			break;
		default:
			break;
		}

	};

	public TableViewer getViewer() {
		return fViewer;
	}

	public void dispose() {
		if (labelProvider != null) {
			labelProvider.dispose();
		}
		if (contentProvider != null) {
			contentProvider.dispose();
		}
		if (adapterFactory != null) {
			adapterFactory.dispose();
		}
	}

	private void storeColumnsSettings() {
		if (fViewer == null) {
			return;
		}
		int[] columnOrder = fViewer.getTable().getColumnOrder();
		//Use only the store when there is more than the default columns
		//This is to allow the dynamic column position
		if (columnOrder.length == ReviewTableDefinition.values().length) {
			return;
		}

		int colInTable = fViewer.getTable().getColumnCount();
		int[] columnWidth = new int[colInTable];
		for (int i = 0; i < colInTable; i++) {
			columnWidth[i] = fViewer.getTable().getColumn(i).getWidth();
		}

		getDialogSettings().put(VIEW_COLUMN_ORDER,
				Arrays.stream(columnOrder).mapToObj(i -> String.valueOf(i)).toArray(String[]::new));
		getDialogSettings().put(VIEW_COLUMN_WIDTH,
				Arrays.stream(columnWidth).mapToObj(i -> String.valueOf(i)).toArray(String[]::new));
	}

	private void restoreColumnsSettings() {
		if (fViewer == null) {
			return;
		}
		String[] backedUpValue = getDialogSettings().getArray(VIEW_COLUMN_ORDER);
		if (backedUpValue == null) {
			return;
		}
		int[] columnOrderStored = Arrays.stream(backedUpValue).mapToInt(Integer::parseInt).toArray();
		int columInTable = fViewer.getTable().getColumnCount();
		//Keep default column position until we have data to display in the dashboard
		if (columInTable == ReviewTableDefinition.values().length) {
			return;
		}
		//Keep an array of the last saved value concerning the columns width in the dashboard
		int[] oldvalue = new int[columInTable];
		for (int i = 0; i < columInTable; i++) {
			int width = fViewer.getTable().getColumn(i).getWidth();
			oldvalue[i] = width;
		}

		//Lets deal with the columns order
		//Initialize variables
		int lastStoredColumnSize = columnOrderStored.length;
		int[] nextTableColumn = new int[columInTable];
		if (columInTable < columnOrderStored.length) {
			//More stored columns than what we need now, let reduce the array
			System.arraycopy(columnOrderStored, 0, nextTableColumn, 0, columInTable);
		} else {
			//Table have more columns than the storage
			System.arraycopy(columnOrderStored, 0, nextTableColumn, 0, columnOrderStored.length);
			//Get the extra column
			//Initialize the columns order when there are more columns in the table than what has been stored previously
			for (int i = lastStoredColumnSize; i < nextTableColumn.length; i++) {
				nextTableColumn[i] = i; //init the new dynamic columns at the end of the table
			}
		}

		//Validate the column , it should be between 0 to number of columns
		int nextColumSize = nextTableColumn.length;
		int numberColumnToMove = 0;
		for (int i = 0; i < nextColumSize; i++) {
			if (nextTableColumn[i] >= nextColumSize) {
				numberColumnToMove++;
				//Move by one slot the array
				System.arraycopy(columnOrderStored, i + numberColumnToMove, nextTableColumn, i, nextColumSize - i);
				//need to maintain the counter for next loop if the new number has to move as well
				i--;
			}
		}

		fViewer.getTable().setColumnOrder(nextTableColumn);

		restoreColumnWidth(columnOrderStored, columInTable, oldvalue, lastStoredColumnSize - 1, nextTableColumn); //decrease by one to read the array

	}

	/**
	 * @param columnOrderStored
	 * @param columInTable
	 * @param oldvalue
	 * @param lastStoredColumnSize
	 * @param nextTableColumn
	 */
	private void restoreColumnWidth(int[] columnOrderStored, int columInTable, int[] oldvalue, int lastStoredColumnSize,
			int[] nextTableColumn) {
		String[] backedUpValue;
		//Lets deal now with the columns width
		backedUpValue = getDialogSettings().getArray(VIEW_COLUMN_WIDTH);
		if (backedUpValue == null) {
			return;
		}
		int[] columnWidth = Arrays.stream(backedUpValue).mapToInt(Integer::parseInt).toArray();
		int totalSize = 0;
		if (columInTable < columnWidth.length) {
			//More store column than what we need now, let reduce the array
			System.arraycopy(columnWidth, 0, nextTableColumn, 0, columInTable);
		} else {
			//Table have more columns than the storage
			System.arraycopy(columnWidth, 0, nextTableColumn, 0, columnWidth.length);
			//Add the extra columns width from the table data
			for (int i = columnWidth.length; i < nextTableColumn.length; i++) {
				nextTableColumn[i] = oldvalue[i];
			}
		}
		for (int i = 0; i < nextTableColumn.length; i++) {
			totalSize = totalSize + nextTableColumn[i];
			fViewer.getTable().getColumn(i).setWidth(nextTableColumn[i]);
		}

		//Reset if total size is small number (50 or less )pixels.
		if (totalSize <= 50) {
			resetDefault();
		}

		//Read and adjust the last column defined before the dynamic labels
		//Needs to be reset to allow to see the dynamic columns in the client area
		if (lastStoredColumnSize < fViewer.getTable().getColumnCount()) {
			int defaultWidth = oldvalue[lastStoredColumnSize];//column before the new labels
			int testCol = columnOrderStored[lastStoredColumnSize];
			if (testCol < ReviewTableDefinition.values().length) {
				defaultWidth = ReviewTableDefinition.values()[testCol].getWidth();//column before the dynamic labels
			}
			fViewer.getTable().getColumn(testCol).setWidth(defaultWidth);
		}
	}

	/**
	 * Reset the column width and order, then save it for the next time
	 */
	public void resetDefault() {
		Table table = fViewer.getTable();
		ReviewTableDefinition[] tableInfo = ReviewTableDefinition.values();
		int defaultLength = tableInfo.length;
		int colInTable = table.getColumnCount();
		int[] newOrder = new int[colInTable];
		//Reset the column order
		for (int i = 0; i < colInTable; i++) {
			newOrder[i] = i;
		}
		table.setColumnOrder(newOrder);//Re-set the initial column order, plus the LABELS at the end
		//Use the default length defined for the table without the dynamic columns
		for (int i = 0; i < defaultLength; i++) {
			table.getColumn(i).setWidth(tableInfo[i].getWidth());
		}
		//For the dynamic columns, defined the minimum value
		for (int i = defaultLength; i < colInTable; i++) {
			table.getColumn(i).pack();
		}

		storeColumnsSettings();
	}

	private IDialogSettings getDialogSettings() {
		IDialogSettings settings = GerritUi.getDefault().getDialogSettings();
		IDialogSettings section = settings.getSection(EGERRIT_DASHBOARD);
		if (section == null) {
			section = settings.addNewSection(EGERRIT_DASHBOARD);
		}
		return section;
	}

	/**
	 * Create each column in the review table list
	 *
	 * @param ReviewTableDefinition
	 * @return TableViewerColumn
	 */
	private void createTableViewerLabelColumn(String label) {
		int width = 28 + 5 * label.length();
		final TableViewerColumn viewerColumn = new TableViewerColumn(fViewer, SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		column.setText(label);
		column.setWidth(width);
		column.setAlignment(SWT.LEFT);
		column.setResizable(true);
		column.setMoveable(true);
	}

	/**
	 * Return the name for a dynamic column
	 *
	 * @param column
	 * @return
	 */
	public String getColumnLabel(int column) {
		int val = column - defaultColumn;//Adjust the dynamic column value
		if (val >= 0) {
			return voteColumns[val];
		}
		return ""; //$NON-NLS-1$
	}
}
