/*******************************************************************************
 * Copyright (c) 2000, 2017 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 | SWT.SHEET);
		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;
	}
}
