/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation 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:
 *     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));
				}
			}
		});
	}
}
