/*******************************************************************************
 * Copyright (c) 2007, 2010 BMW Car IT, Technische Universitaet Muenchen, 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:
 *     BMW Car IT - Initial API and implementation
 *     Technische Universitaet Muenchen - Major refactoring and extension
 *******************************************************************************/
package org.eclipse.emf.edapt.common.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IFontDecorator;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;

/**
 * A composite to select a value. The possible values are represented as a tree.
 * Selection criteria can be entered through a text field.
 * 
 * @author herrmama
 * @author $Author$
 * @version $Rev$
 * @levd.rating RED Rev:
 */
public class ValueSelectionComposite extends Composite {

	/**
	 * The filter
	 */
	protected Pattern filter;

	/**
	 * Viewer to display filtered values
	 */
	private TreeViewer filteredViewer;

	/**
	 * Whether multiple values can be selected
	 */
	private final boolean multi;

	/**
	 * The label provider
	 */
	protected final AdapterFactoryLabelProvider labelProvider;

	/**
	 * Root elements of area in which values can be found
	 */
	@SuppressWarnings("unchecked")
	private final Collection valueArea;

	/**
	 * Current value that is selected
	 */
	private final Object value;

	/**
	 * Validator to determine possible values.
	 */
	private final IValueValidator validator;

	/**
	 * Constructor
	 */
	@SuppressWarnings("unchecked")
	public ValueSelectionComposite(Composite parent,
			AdapterFactoryLabelProvider labelProvider, Object value,
			boolean multi, Collection valueArea, IValueValidator validator) {
		super(parent, SWT.None);

		this.labelProvider = labelProvider;
		this.multi = multi;
		this.value = value;
		this.valueArea = valueArea;
		this.validator = validator;

		filter = Pattern.compile(".*");

		init();
	}

	/**
	 * Initialize the composite.
	 */
	private void init() {
		GridLayout layout = new GridLayout();
		layout.marginHeight = layout.marginWidth = 0;
		setLayout(layout);
		GridData data = new GridData(GridData.FILL_BOTH);
		setLayoutData(data);

		createFilterText();
		createFilteredViewer();

		selectValue();
	}

	/**
	 * Create the text field to provider the filter pattern
	 */
	private void createFilterText() {
		final Text filterText = new Text(this, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		filterText.setLayoutData(data);

		filterText.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				setFilter(filterText.getText());
			}

		});

		filterText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.ARROW_DOWN) {
					filteredViewer.getControl().setFocus();
				}
			}
		});

		filterText.addTraverseListener(new TraverseListener() {

			public void keyTraversed(TraverseEvent e) {
				if (e.detail == SWT.TRAVERSE_RETURN) {
					e.doit = false;
					filteredViewer.getControl().setFocus();
					filteredViewer.setSelection(new StructuredSelection(
							getFirstMatchingElement()));
				}
			}
		});
	}

	/**
	 * Set the filter pattern
	 */
	private void setFilter(String pattern) {
		StringBuffer escaped = new StringBuffer();

		String[] starSplit = pattern.split("\\*");
		for (int i = 0, n = starSplit.length; i < n; i++) {
			if (i > 0) {
				escaped.append(".*");
			}
			String star = starSplit[i];
			String[] questionSplit = star.split("\\?");
			for (String question : questionSplit) {
				if (i > 0) {
					escaped.append(".?");
				}
				escaped.append(Pattern.quote(question));
			}
		}

		escaped.append(".*");

		filter = Pattern.compile(escaped.toString(), Pattern.CASE_INSENSITIVE);
		refreshFilteredViewer();
	}

	/**
	 * Refresh the filtered viewer
	 */
	protected void refreshFilteredViewer() {
		filteredViewer.getControl().setRedraw(false);
		filteredViewer.refresh(true);
		filteredViewer.expandAll();
		ISelection oldSelection = filteredViewer.getSelection();
		Object firstValue = valueArea.iterator().next();
		filteredViewer.setSelection(new StructuredSelection(firstValue), true);
		filteredViewer.setSelection(oldSelection);
		filteredViewer.getControl().setRedraw(true);
	}

	/**
	 * Create the list to display the values
	 */
	private void createFilteredViewer() {
		int style = SWT.BORDER;
		if (multi) {
			style |= SWT.MULTI;
		}

		filteredViewer = new TreeViewer(this, style);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = 400;
		data.heightHint = 400;
		filteredViewer.getControl().setLayoutData(data);

		filteredViewer.setContentProvider(new AdapterFactoryContentProvider(
				labelProvider.getAdapterFactory()) {
			@SuppressWarnings("unchecked")
			@Override
			public Object[] getElements(Object object) {
				Collection objects = (Collection) object;
				return objects.toArray();
			}
		});
		filteredViewer.setLabelProvider(new DecoratingLabelProvider(
				labelProvider, new Decorator()));

		filteredViewer.addFilter(new ViewerFilter() {

			@Override
			public boolean select(Viewer viewer, Object parentElement,
					Object element) {
				if (select(element)) {
					return true;
				}
				for (Object child : ((ITreeContentProvider) filteredViewer
						.getContentProvider()).getChildren(element)) {
					if (select(viewer, element, child)) {
						return true;
					}
				}
				return false;
			}

			private boolean select(Object element) {
				return isSelectable(element);
			}

		});

		filteredViewer.setInput(valueArea);

		filteredViewer.expandAll();
	}

	/**
	 * Checks whether the selection contains only valid values
	 */
	public boolean validSelection() {
		List<Object> elements = getSelectedElements();
		if (elements.size() == 0) {
			return false;
		}
		for (Object element : elements) {
			if (!validator.isPossibleValue(element)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Select the current value.
	 */
	@SuppressWarnings("unchecked")
	private void selectValue() {
		if (value != null) {
			if (multi) {
				if (value instanceof Collection) {
					filteredViewer.setSelection(new StructuredSelection(
							new ArrayList((Collection) value)));
				}
			} else {
				filteredViewer.setSelection(new StructuredSelection(value));
			}
		}
	}

	/**
	 * Return the first matching element
	 */
	private EObject getFirstMatchingElement() {
		TreeItem item = getFirstMatchingItem(filteredViewer.getTree()
				.getItems());
		if (item != null) {
			return (EObject) item.getData();
		}
		return null;
	}

	/**
	 * Get the first tree item that represents a value
	 */
	private TreeItem getFirstMatchingItem(TreeItem[] items) {
		for (int i = 0, n = items.length; i < n; i++) {
			TreeItem item = items[i];
			if (isSelectable(item.getData())) {
				return item;
			}
			item = getFirstMatchingItem(item.getItems());
			if (item != null) {
				return item;
			}
		}
		return null;
	}

	/**
	 * Get the selected elements
	 */
	public List<Object> getSelectedElements() {
		return SelectionUtils
				.getSelectedElements(filteredViewer.getSelection());
	}

	/**
	 * Add a listener to listen to changes of the selection.
	 */
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		filteredViewer.addSelectionChangedListener(listener);
	}

	/**
	 * Remove a listener to listen to changes of the selection.
	 */
	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		filteredViewer.removeSelectionChangedListener(listener);
	}

	/**
	 * Add a listener to listen to double clicks.
	 */
	public void addDoubleClickListener(IDoubleClickListener listener) {
		filteredViewer.addDoubleClickListener(listener);
	}

	/**
	 * Remove a listener to listen to double clicks.
	 */
	public void removeDoubleClickListener(IDoubleClickListener listener) {
		filteredViewer.removeDoubleClickListener(listener);
	}

	/**
	 * Whether an element can be selected based on the current filter.
	 */
	private boolean isSelectable(Object element) {
		if (validator.isPossibleValue(element)) {
			String label = labelProvider.getText(element);
			Matcher matcher = filter.matcher(label);
			return matcher.matches();
		}
		return false;
	}

	/**
	 * Decorator to highlight elements which can be selected
	 */
	private class Decorator implements ILabelDecorator, IFontDecorator {

		/** {@inheritDoc} */
		public Image decorateImage(Image image, Object element) {
			return null;
		}

		/** {@inheritDoc} */
		public String decorateText(String text, Object element) {
			return null;
		}

		/** {@inheritDoc} */
		public void addListener(ILabelProviderListener listener) {
			// not required
		}

		/** {@inheritDoc} */
		public void dispose() {
			// not required
		}

		/** {@inheritDoc} */
		public boolean isLabelProperty(Object element, String property) {
			return false;
		}

		/** {@inheritDoc} */
		public void removeListener(ILabelProviderListener listener) {
			// not required
		}

		/** {@inheritDoc} */
		public Font decorateFont(Object element) {
			if (isSelectable(element)) {
				return JFaceResources.getFontRegistry().getBold(
						JFaceResources.DIALOG_FONT);
			}
			return null;
		}
	}
}
