/*******************************************************************************
 * Copyright (c) 2000, 2013 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.ant.internal.ui.preferences;

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

import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.core.AntObject;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.ColumnSorter;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;

/**
 * Provides the generic implementation for a sub-page in the Ant preference page.
 */
public abstract class AntPage {

	protected static final int ADD_BUTTON = IDialogConstants.CLIENT_ID + 1;
	protected static final int EDIT_BUTTON = IDialogConstants.CLIENT_ID + 2;
	protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;

	protected SelectionAdapter selectionAdapter = new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent e) {
			buttonPressed(((Integer) e.widget.getData()).intValue());
		}
	};

	private AntRuntimePreferencePage preferencePage;
	private TableViewer tableViewer;
	private AntContentProvider contentProvider;
	private AntObjectLabelProvider labelProvider = new AntObjectLabelProvider();

	protected Button editButton;
	protected Button removeButton;

	private final String[] fTableColumnHeaders = { AntPreferencesMessages.AntPage_0, AntPreferencesMessages.AntPage_1,
			AntPreferencesMessages.AntPage_2, AntPreferencesMessages.AntPage_3 };
	private final ColumnLayoutData[] fTableColumnLayouts = { new ColumnWeightData(33), new ColumnWeightData(23), new ColumnWeightData(22),
			new ColumnWeightData(22) };

	/**
	 * Creates an instance of this page.
	 */
	public AntPage(AntRuntimePreferencePage preferencePage) {
		super();
		this.preferencePage = preferencePage;
	}

	/**
	 * Adds buttons specific to the page.
	 */
	protected abstract void addButtonsToButtonGroup(Composite parent);

	/**
	 * Give this page a chance to initialize itself
	 */
	protected abstract void initialize();

	/**
	 * Adds an object to the contents
	 */
	protected void addContent(Object o) {
		if (contentProvider != null) {
			contentProvider.add(o);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#buttonPressed(int)
	 */
	private void buttonPressed(int buttonId) {
		switch (buttonId) {
			case ADD_BUTTON:
				add();
				break;
			case EDIT_BUTTON:
				edit(getSelection());
				break;
			case REMOVE_BUTTON:
				remove();
				break;
			default:
				break;
		}
	}

	/**
	 * Creates and returns a button with appropriate size and layout.
	 * 
	 * @param parent
	 *            the control to create the button on
	 * @param labelKey
	 *            the key to lookup the button's label
	 * @param buttonId
	 *            the id to assign to this button
	 * @return a new and initialized button
	 */
	protected Button createPushButton(Composite parent, String buttonText, int buttonId) {
		Button button = new Button(parent, SWT.PUSH);
		button.setFont(parent.getFont());
		button.setText(buttonText);
		button.setData(Integer.valueOf(buttonId));
		button.addSelectionListener(selectionAdapter);
		preferencePage.setButtonLayoutData(button);
		return button;
	}

	/**
	 * Creates the group which will contain the buttons.
	 */
	protected void createButtonGroup(Composite top) {
		Composite buttonGroup = new Composite(top, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonGroup.setLayout(layout);
		buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		buttonGroup.setFont(top.getFont());

		addButtonsToButtonGroup(buttonGroup);
	}

	/**
	 * Creates the table viewer.
	 */
	protected void createTable(Composite parent) {
		Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = 425;
		data.heightHint = table.getItemHeight();
		data.horizontalSpan = 1;
		table.setLayoutData(data);
		table.setFont(parent.getFont());

		TableLayout tableLayout = new TableLayout();
		table.setLayout(tableLayout);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		contentProvider = getContentProvider();
		tableViewer = new TableViewer(table);
		tableViewer.setContentProvider(contentProvider);
		tableViewer.setLabelProvider(this.labelProvider);
		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				tableSelectionChanged((IStructuredSelection) event.getSelection());
			}
		});

		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				if (!event.getSelection().isEmpty() && editButton.isEnabled()) {
					edit((IStructuredSelection) event.getSelection());
				}
			}
		});
		ArrayList<ColumnSorter> sorters = new ArrayList<>(fTableColumnHeaders.length);
		for (int i = 0; i < fTableColumnHeaders.length; i++) {
			tableLayout.addColumnData(fTableColumnLayouts[i]);
			TableColumn column = new TableColumn(table, SWT.NONE, i);
			column.setResizable(fTableColumnLayouts[i].resizable);
			column.setText(fTableColumnHeaders[i]);
			sorters.add(new ColumnSorter(this.tableViewer, column) {
				@Override
				public String getCompareText(Object obj, int columnindex) {
					return AntPage.this.labelProvider.getColumnText(obj, columnindex);
				}
			});
		}

		table.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				if (editButton.isEnabled() && event.character == SWT.DEL && event.stateMask == 0) {
					remove(tableViewer);
				}
			}
		});

		restoreColumnSettings(AntUIPlugin.getDefault().getDialogSettings(), sorters);
	}

	/**
	 * Persist table settings into the give dialog store, prefixed with the given key.
	 * 
	 * @param settings
	 *            dialog store
	 * @since 3.5
	 */
	public void saveColumnSettings(IDialogSettings settings) {
		Table table = this.tableViewer.getTable();
		int columnCount = table.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			settings.put(getHelpContextId() + ".columnWidth" + i, table.getColumn(i).getWidth()); //$NON-NLS-1$
		}
		TableColumn column = table.getSortColumn();
		if (column != null) {
			settings.put(getHelpContextId() + ".sortColumn", table.indexOf(column)); //$NON-NLS-1$
			settings.put(getHelpContextId() + ".sortDirection", table.getSortDirection()); //$NON-NLS-1$
		}
	}

	/**
	 * Restore table settings from the given dialog store using the given key.
	 * 
	 * @param settings
	 *            dialog settings store
	 * @since 3.5
	 */
	private void restoreColumnSettings(IDialogSettings settings, ArrayList<ColumnSorter> sorters) {
		restoreColumnWidths(settings);
		int idx = 0;
		int direction = SWT.DOWN;
		try {
			idx = settings.getInt(getHelpContextId() + ".sortColumn"); //$NON-NLS-1$
			direction = settings.getInt(getHelpContextId() + ".sortDirection"); //$NON-NLS-1$
		}
		catch (NumberFormatException e) {
			// do nothing
		}
		Table table = this.tableViewer.getTable();
		if (table.getColumnCount() < 1) {
			return;
		}
		TableColumn column = table.getColumn(idx);
		if (column != null) {
			table.setSortColumn(column);
			table.setSortDirection(direction);
			ColumnSorter sorter = sorters.get(idx);
			sorter.setDirection(direction);
		}
		sorters.clear();
	}

	/**
	 * Restores the column widths from dialog settings
	 * 
	 * @param settings
	 * @since 3.5
	 */
	private void restoreColumnWidths(IDialogSettings settings) {
		Table table = this.tableViewer.getTable();
		int columnCount = table.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			int width = -1;
			try {
				width = settings.getInt(getHelpContextId() + ".columnWidth" + i); //$NON-NLS-1$
			}
			catch (NumberFormatException e) {
				// do nothing
			}

			if ((width <= 0) || (i == table.getColumnCount() - 1)) {
				table.getColumn(i).pack();
			} else {
				table.getColumn(i).setWidth(width);
			}
		}
	}

	/**
	 * Returns the content provider to use for the table viewer
	 * 
	 * @return AntPageContentProvider
	 */
	protected AntContentProvider getContentProvider() {
		return new AntContentProvider(false);
	}

	/**
	 * Returns the currently listed objects in the table if the library for that entry is still included in the preferences. Default objects are
	 * included depending on the value of the <code>forDisplay</code> parameter. Returns <code>null</code> if this widget has not yet been created or
	 * has been disposed.
	 * 
	 * @param forDisplay
	 *            Whether the result is to be displayed in the UI or stored in the preferences
	 * @return The list of objects currently displayed in the table
	 */
	protected List<Object> getContents(boolean forDisplay) {
		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
			return null;
		}
		List<IAntClasspathEntry> entries = getPreferencePage().getLibraryEntries();

		Object[] elements = contentProvider.getElements(tableViewer.getInput());
		List<Object> contents = new ArrayList<>(elements.length);
		Object element;
		AntObject antObject;
		for (int i = 0; i < elements.length; i++) {
			element = elements[i];
			if (element instanceof AntObject) {
				antObject = (AntObject) element;
				if (forDisplay) {
					if (!antObject.isDefault() && !entries.contains(antObject.getLibraryEntry())) {
						continue;
					}
				} else if (antObject.isDefault() || !entries.contains(antObject.getLibraryEntry())) {
					continue;
				}
			}
			contents.add(element);
		}
		return contents;
	}

	/**
	 * Returns the selection in the viewer, or <code>null</code> if none.
	 */
	protected final IStructuredSelection getSelection() {
		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
			return null;
		}
		return ((IStructuredSelection) tableViewer.getSelection());
	}

	/**
	 * Returns the shell of the sub-page.
	 */
	protected final Shell getShell() {
		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
			return null;
		}
		return tableViewer.getControl().getShell();
	}

	/**
	 * Handles the remove button pressed event
	 */
	protected void remove() {
		remove(tableViewer);
	}

	protected void remove(TableViewer viewer) {
		AntContentProvider antContentProvider = (AntContentProvider) viewer.getContentProvider();
		IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
		Iterator<?> itr = sel.iterator();
		while (itr.hasNext()) {
			antContentProvider.remove(itr.next());
		}
	}

	/**
	 * Sets the contents of the table on this page. Has no effect if this widget has not yet been created or has been disposed.
	 */
	protected void setInput(List<?> inputs) {
		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
			return;
		}
		tableViewer.setInput(inputs);
		tableSelectionChanged((IStructuredSelection) tableViewer.getSelection());
	}

	/**
	 * Updates the content element in the table viewer.
	 */
	protected final void updateContent(Object element) {
		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
			return;
		}
		tableViewer.update(element, null);
	}

	/**
	 * Creates the default contents of this page
	 */
	protected Composite createContents(Composite top) {
		PlatformUI.getWorkbench().getHelpSystem().setHelp(top, getHelpContextId());
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight = 2;
		layout.marginWidth = 2;
		top.setLayout(layout);

		top.setLayoutData(new GridData(GridData.FILL_BOTH));

		createTable(top);
		createButtonGroup(top);

		return top;
	}

	protected AntRuntimePreferencePage getPreferencePage() {
		return preferencePage;
	}

	protected TableViewer getTableViewer() {
		return tableViewer;
	}

	/**
	 * Handles selection changes in the table viewer.
	 */
	protected void tableSelectionChanged(IStructuredSelection newSelection) {
		int size = newSelection.size();
		boolean enabled = true;

		Iterator<?> itr = newSelection.iterator();
		while (itr.hasNext()) {
			Object element = itr.next();
			if (element instanceof AntObject) {
				AntObject antObject = (AntObject) element;
				if (antObject.isDefault()) {
					enabled = false;
					break;
				}
			}
		}
		editButton.setEnabled(enabled && size == 1);
		removeButton.setEnabled(enabled && size > 0);
	}

	/**
	 * Allows the user to edit a custom Ant object.
	 * 
	 * @param selection
	 *            The selection containing the object to edit
	 */
	protected abstract void edit(IStructuredSelection selection);

	/**
	 * Allows the user to add a custom Ant object.
	 * 
	 */
	protected abstract void add();

	/**
	 * Returns this page's help context id, which is hooked to this page on creation.
	 * 
	 * @return help context id
	 */
	protected abstract String getHelpContextId();

	protected void connectToFolder(final TabItem item, TabFolder folder) {
		folder.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (e.item == item) {
					// remove ant objects whose library has been removed
					setInput(getContents(true));
				}
			}
		});
	}
}
