/*******************************************************************************
 * 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 java.util.Map;
import java.util.Map.Entry;

import org.eclipse.ant.core.Property;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.ColumnSorter;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
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.jface.window.Window;
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.graphics.Font;
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.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import com.ibm.icu.text.MessageFormat;

public class AntPropertiesBlock {

	/**
	 * Constant representing the id of the settings for the property table column widths
	 * 
	 * @since 3.5
	 */
	private static final String PROPERTY_COLUMN_WIDTH = "ant.properties.block.property.columnWidth"; //$NON-NLS-1$

	/**
	 * Constant representing the id of the settings for the property table sort column
	 * 
	 * @since 3.5
	 */
	private static final String PROPERTY_SORT_COLUMN = "ant.properties.block.property.sortColumn"; //$NON-NLS-1$

	/**
	 * Constant representing the id of the settings for the property table sort direction
	 * 
	 * @since 3.5
	 */
	private static final String PROPERTY_SORT_DIRECTION = "ant.properties.block.property.sortDirection"; //$NON-NLS-1$

	private IAntBlockContainer container;

	private Button editButton;
	private Button removeButton;
	private Button addButton;

	private Button addFileButton;
	private Button addExternalFileButton;
	private Button removeFileButton;

	private TableViewer propertyTableViewer;
	private TableViewer fileTableViewer;

	private final AntObjectLabelProvider labelProvider = new AntObjectLabelProvider();

	private IDialogSettings dialogSettings;

	private boolean tablesEnabled = true;

	private final String[] fTableColumnHeaders = { AntPreferencesMessages.AntPropertiesBlock_0, AntPreferencesMessages.AntPropertiesBlock_5,
			AntPreferencesMessages.AntPropertiesBlock_6 };

	private final ColumnLayoutData[] fTableColumnLayouts = { new ColumnWeightData(30),// , 190, true),
			new ColumnWeightData(40),// , 190, true),
			new ColumnWeightData(30) // , 190, true)
	};

	/**
	 * Button listener that delegates for widget selection events.
	 */
	private SelectionAdapter buttonListener = new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent event) {
			if (event.widget == addButton) {
				addProperty();
			} else if (event.widget == editButton) {
				edit();
			} else if (event.widget == removeButton) {
				remove(propertyTableViewer);
			} else if (event.widget == addFileButton) {
				addPropertyFile();
			} else if (event.widget == addExternalFileButton) {
				addExternalPropertyFile();
			} else if (event.widget == removeFileButton) {
				remove(fileTableViewer);
			}
		}
	};

	/**
	 * Key listener that delegates for key pressed events.
	 */
	private KeyAdapter keyListener = new KeyAdapter() {
		@Override
		public void keyPressed(KeyEvent event) {
			if (event.getSource() == propertyTableViewer) {
				if (removeButton.isEnabled() && event.character == SWT.DEL && event.stateMask == 0) {
					remove(propertyTableViewer);
				}
			} else if (event.getSource() == fileTableViewer) {
				if (removeFileButton.isEnabled() && event.character == SWT.DEL && event.stateMask == 0) {
					remove(fileTableViewer);
				}
			}
		}
	};

	/**
	 * Selection changed listener that delegates selection events.
	 */
	private ISelectionChangedListener tableListener = new ISelectionChangedListener() {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			if (tablesEnabled) {
				if (event.getSource() == propertyTableViewer) {
					propertyTableSelectionChanged((IStructuredSelection) event.getSelection());
				} else if (event.getSource() == fileTableViewer) {
					fileTableSelectionChanged((IStructuredSelection) event.getSelection());
				}
			}
		}
	};

	public AntPropertiesBlock(IAntBlockContainer container) {
		this.container = container;
	}

	private void addPropertyFile() {
		String title = AntPreferencesMessages.AntPropertiesFileSelectionDialog_12;
		String message = AntPreferencesMessages.AntPropertiesFileSelectionDialog_13;
		String filterExtension = "properties"; //$NON-NLS-1$
		String filterMessage = AntPreferencesMessages.AntPropertiesFileSelectionDialog_14;

		Object[] existingFiles = getPropertyFiles();
		List<IFile> propFiles = new ArrayList<>(existingFiles.length);
		for (int j = 0; j < existingFiles.length; j++) {
			String file = (String) existingFiles[j];
			try {
				propFiles.add(AntUtil.getFileForLocation(VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(file), null));
			}
			catch (CoreException e) {
				AntUIPlugin.log(e.getStatus());
			}
		}

		FileSelectionDialog dialog = new FileSelectionDialog(propertyTableViewer.getControl().getShell(), propFiles, title, message, filterExtension, filterMessage);
		if (dialog.open() == Window.OK) {
			Object[] elements = dialog.getResult();
			for (int i = 0; i < elements.length; i++) {
				IFile file = (IFile) elements[i];
				String varExpression = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", file.getFullPath().toString()); //$NON-NLS-1$
				((AntContentProvider) fileTableViewer.getContentProvider()).add(varExpression);
			}
			container.update();
		}
	}

	public void createControl(Composite top, String propertyLabel, String propertyFileLabel) {
		Font font = top.getFont();
		dialogSettings = AntUIPlugin.getDefault().getDialogSettings();

		Label label = new Label(top, SWT.NONE);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);
		label.setFont(font);
		label.setText(propertyLabel);

		int idx = 0;
		int direction = SWT.DOWN;
		try {
			idx = dialogSettings.getInt(PROPERTY_SORT_COLUMN);
			direction = dialogSettings.getInt(PROPERTY_SORT_DIRECTION);
		}
		catch (NumberFormatException e) {
			// do nothing
		}
		propertyTableViewer = createTableViewer(top, true, false, idx, direction);
		propertyTableViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				if (!event.getSelection().isEmpty() && editButton.isEnabled()) {
					edit();
				}
			}
		});

		propertyTableViewer.getTable().addKeyListener(keyListener);

		createButtonGroup(top);

		label = new Label(top, SWT.NONE);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);
		label.setFont(font);
		label.setText(propertyFileLabel);

		fileTableViewer = createTableViewer(top, false, true, 0, SWT.DOWN);
		fileTableViewer.getTable().addKeyListener(keyListener);

		createButtonGroup(top);
	}

	/**
	 * Creates the group which will contain the buttons.
	 */
	private 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 | GridData.HORIZONTAL_ALIGN_FILL));
		buttonGroup.setFont(top.getFont());

		addButtonsToButtonGroup(buttonGroup);
	}

	/**
	 * Creates and returns a configured table viewer in the given parent
	 */
	private TableViewer createTableViewer(Composite parent, boolean setColumns, boolean defaultsorting, int sortcolumnidx, int sortdirection) {
		Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
		GridData data = new GridData(GridData.FILL_BOTH);
		int availableRows = availableRows(parent);
		if (setColumns) {
			data.heightHint = table.getItemHeight() * (availableRows / 10);
		}
		data.widthHint = 425;
		table.setLayoutData(data);
		table.setFont(parent.getFont());

		TableViewer tableViewer = new TableViewer(table);
		tableViewer.setContentProvider(new AntContentProvider(defaultsorting));
		tableViewer.setLabelProvider(labelProvider);
		tableViewer.addSelectionChangedListener(tableListener);

		if (setColumns) {
			TableLayout tableLayout = new TableLayout();
			table.setLayout(tableLayout);
			table.setHeaderVisible(true);
			table.setLinesVisible(true);
			ColumnSorter sorter = null;
			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]);
				sorter = new ColumnSorter(tableViewer, column) {
					@Override
					public String getCompareText(Object obj, int columnindex) {
						return AntPropertiesBlock.this.labelProvider.getColumnText(obj, columnindex);
					}
				};
				if (i == sortcolumnidx) {
					sorter.setDirection(sortdirection);
				}
			}
		}
		return tableViewer;
	}

	/**
	 * Used to persist any settings for the block that the user has set
	 * 
	 * @since 3.5
	 */
	public void saveSettings() {
		if (propertyTableViewer != null) {
			saveColumnSettings();
		}
	}

	/**
	 * Persist table settings into the give dialog store.
	 * 
	 * @since 3.5
	 */
	private void saveColumnSettings() {
		Table table = this.propertyTableViewer.getTable();
		int columnCount = table.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			dialogSettings.put(PROPERTY_COLUMN_WIDTH + i, table.getColumn(i).getWidth());
		}
		TableColumn column = table.getSortColumn();
		if (column != null) {
			dialogSettings.put(PROPERTY_SORT_COLUMN, table.indexOf(column));
			dialogSettings.put(PROPERTY_SORT_DIRECTION, table.getSortDirection());
		}
	}

	/**
	 * Restore table settings from the given dialog store.
	 * 
	 * @since 3.5
	 */
	private void restoreColumnSettings() {
		if (this.propertyTableViewer == null) {
			return;
		}
		restoreColumnWidths();
	}

	/**
	 * Restores the column widths from dialog settings
	 * 
	 * @since 3.5
	 */
	private void restoreColumnWidths() {
		Table table = this.propertyTableViewer.getTable();
		int columnCount = table.getColumnCount();
		for (int i = 0; i < columnCount; i++) {
			int width = -1;
			try {
				width = dialogSettings.getInt(PROPERTY_COLUMN_WIDTH + i);
			}
			catch (NumberFormatException e) {
				// do nothing
			}

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

	/**
	 * Return the number of rows available in the current display using the current font.
	 * 
	 * @param parent
	 *            The Composite whose Font will be queried.
	 * @return The result of the display size divided by the font size.
	 */
	private int availableRows(Composite parent) {
		int fontHeight = (parent.getFont().getFontData())[0].getHeight();
		int displayHeight = parent.getDisplay().getClientArea().height;
		return displayHeight / fontHeight;
	}

	/*
	 * (non-Javadoc) Method declared on AntPage.
	 */
	protected void addButtonsToButtonGroup(Composite parent) {
		if (editButton == null) {
			addButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_1);
			editButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_2);
			removeButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_3);
		} else {
			addFileButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_4);
			addExternalFileButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_14);
			removeFileButton = createPushButton(parent, AntPreferencesMessages.AntPropertiesBlock_removeFileButton);
		}
	}

	/**
	 * Creates and returns a configured button in the given composite with the given label. Widget selection call-backs for the returned button will
	 * be processed by the <code>buttonListener</code>
	 */
	private Button createPushButton(Composite parent, String label) {
		Button button = container.createPushButton(parent, label);
		button.addSelectionListener(buttonListener);
		GridData gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
		button.setLayoutData(gridData);
		return button;
	}

	/**
	 * Allows the user to enter external property files
	 */
	private void addExternalPropertyFile() {
		String lastUsedPath;
		lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTEXTFILE);
		if (lastUsedPath == null) {
			lastUsedPath = IAntCoreConstants.EMPTY_STRING;
		}
		FileDialog dialog = new FileDialog(fileTableViewer.getControl().getShell(), SWT.MULTI);
		dialog.setFilterExtensions(new String[] { "*.properties", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$;
		dialog.setFilterPath(lastUsedPath);

		String result = dialog.open();
		if (result == null) {
			return;
		}
		IPath filterPath = new Path(dialog.getFilterPath());
		String[] results = dialog.getFileNames();
		for (int i = 0; i < results.length; i++) {
			String fileName = results[i];
			IPath path = filterPath.append(fileName).makeAbsolute();
			((AntContentProvider) fileTableViewer.getContentProvider()).add(path.toOSString());
		}

		dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTEXTFILE, filterPath.toOSString());
		container.update();
	}

	private void remove(TableViewer viewer) {
		AntContentProvider antContentProvider = (AntContentProvider) viewer.getContentProvider();
		IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
		antContentProvider.remove(sel);
		container.update();
	}

	/**
	 * Allows the user to enter a user property
	 */
	private void addProperty() {
		String title = AntPreferencesMessages.AntPropertiesBlock_Add_Property_2;
		AddPropertyDialog dialog = new AddPropertyDialog(propertyTableViewer.getControl().getShell(), title, new String[] {
				IAntCoreConstants.EMPTY_STRING, IAntCoreConstants.EMPTY_STRING });
		if (dialog.open() == Window.CANCEL) {
			return;
		}

		String[] pair = dialog.getNameValuePair();
		String name = pair[0];
		if (!overwrite(name)) {
			return;
		}
		Property prop = new Property();
		prop.setName(name);
		prop.setValue(pair[1]);
		((AntContentProvider) propertyTableViewer.getContentProvider()).add(prop);
		container.update();
	}

	private void edit() {
		IStructuredSelection selection = (IStructuredSelection) propertyTableViewer.getSelection();
		Property prop = (Property) selection.getFirstElement();

		String originalName = prop.getName();
		String title = AntPreferencesMessages.AntPropertiesBlock_Edit_User_Property_5;
		AddPropertyDialog dialog = new AddPropertyDialog(propertyTableViewer.getControl().getShell(), title, new String[] { prop.getName(),
				prop.getValue(false) });

		if (dialog.open() == Window.CANCEL) {
			return;
		}

		String[] pair = dialog.getNameValuePair();
		String name = pair[0];
		if (!name.equals(originalName)) {
			if (!overwrite(name)) {
				return;
			}
		}
		prop.setName(name);
		prop.setValue(pair[1]);
		// trigger a resort
		propertyTableViewer.refresh();
		container.update();
	}

	private boolean overwrite(String name) {
		Object[] properties = getProperties();
		for (int i = 0; i < properties.length; i++) {
			Property property = (Property) properties[i];
			String propertyName = property.getName();
			if (propertyName.equals(name)) {
				if (property.isDefault()) {
					MessageDialog.openError(propertyTableViewer.getControl().getShell(), AntPreferencesMessages.AntPropertiesBlock_17, MessageFormat.format(AntPreferencesMessages.AntPropertiesBlock_18, new Object[] {
							propertyName, property.getPluginLabel() }));
					return false;
				}
				boolean overWrite = MessageDialog.openQuestion(propertyTableViewer.getControl().getShell(), AntPreferencesMessages.AntPropertiesBlock_15, MessageFormat.format(AntPreferencesMessages.AntPropertiesBlock_16, new Object[] { name }));
				if (!overWrite) {
					return false;
				}
				((AntContentProvider) propertyTableViewer.getContentProvider()).remove(property);
				break;
			}
		}
		return true;
	}

	/**
	 * Handles selection changes in the Property file table viewer.
	 */
	private void fileTableSelectionChanged(IStructuredSelection newSelection) {
		removeFileButton.setEnabled(newSelection.size() > 0);
	}

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

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

	}

	public void populatePropertyViewer(Map<String, String> properties) {
		if (properties == null) {
			propertyTableViewer.setInput(new Property[0]);
			return;
		}
		Property[] result = new Property[properties.size()];
		Iterator<Map.Entry<String, String>> entries = properties.entrySet().iterator();
		int i = 0;
		while (entries.hasNext()) {
			Entry<String, String> element = entries.next();
			Property property = new Property();
			property.setName(element.getKey());
			property.setValue(element.getValue());
			result[i] = property;
			i++;
		}
		propertyTableViewer.setInput(result);
		restoreColumnSettings();
	}

	public void setPropertiesInput(Property[] properties) {
		propertyTableViewer.setInput(properties);
	}

	public void setPropertyFilesInput(String[] files) {
		fileTableViewer.setInput(files);
	}

	public void update() {
		propertyTableSelectionChanged((IStructuredSelection) propertyTableViewer.getSelection());
		fileTableSelectionChanged((IStructuredSelection) fileTableViewer.getSelection());
	}

	public Object[] getProperties() {
		return ((AntContentProvider) propertyTableViewer.getContentProvider()).getElements(null);
	}

	public Object[] getPropertyFiles() {
		return ((AntContentProvider) fileTableViewer.getContentProvider()).getElements(null);
	}

	public void setEnabled(boolean enable) {
		setTablesEnabled(enable);
		addButton.setEnabled(enable);
		addExternalFileButton.setEnabled(enable);
		addFileButton.setEnabled(enable);
		editButton.setEnabled(enable);
		removeButton.setEnabled(enable);
		removeFileButton.setEnabled(enable);

		if (enable) {
			propertyTableViewer.setSelection(propertyTableViewer.getSelection());
			fileTableViewer.setSelection(fileTableViewer.getSelection());
		}
	}

	public void setTablesEnabled(boolean tablesEnabled) {
		this.tablesEnabled = tablesEnabled;
	}
}
