/*******************************************************************************
 * Copyright (c) 2011, 2012 Red Hat, Inc.
 *  All rights reserved.
 * This program is 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:
 * Red Hat, Inc. - initial API and implementation
 *
 * @author Bob Brodt
 ******************************************************************************/

package org.eclipse.bpmn2.modeler.core.merrimac.dialogs;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map.Entry;

import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.bpmn2.modeler.core.IConstants;
import org.eclipse.bpmn2.modeler.core.adapters.AdapterRegistry;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesProvider;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * @author Bob Brodt
 *
 */
public class ComboObjectEditor extends MultivalueObjectEditor {

	protected ComboViewer comboViewer;
	protected Composite buttons = null;
	protected boolean keyPressed = false;
	protected Button editButton = null;
	protected Button createButton = null;
	protected Hashtable<String,Object> choices = null; // cache choices
	
	/**
	 * @param parent
	 * @param object
	 * @param feature
	 */
	public ComboObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature) {
		this(parent, object, feature, null);
	}

	public ComboObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature, EClass featureEType) {
		super(parent, object, feature, featureEType);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.bpmn2.modeler.ui.property.editors.ObjectEditor#createControl(org.eclipse.swt.widgets.Composite, java.lang.String, int)
	 */
	@Override
	protected Control createControl(Composite composite, String label, int style) {
		if (label==null)
			label = ExtendedPropertiesProvider.getLabel(object,feature);
		createLabel(composite, label);

		boolean canEdit = canEdit();
		boolean canEditInline = canEditInline();
		boolean canCreateNew = canCreateNew();
		
		if (style == SWT.READ_ONLY) {
			canEdit = false;
			canEditInline = false;
			canCreateNew = false;
		}
		
		if (!canEditInline)
			style |= SWT.READ_ONLY;
		comboViewer = createComboViewer(composite, AdapterRegistry.getLabelProvider(), style);
		Combo combo = comboViewer.getCombo();
		combo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, (canEdit || canCreateNew) ? 1 : 2, 1));
		combo.addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent e) {
				comboViewer = null;
			}
			
		});
		
		if (canEditInline) {
			combo.addKeyListener( new KeyListener() {

				@Override
				public void keyPressed(KeyEvent e) {
					keyPressed = true;
				}

				@Override
				public void keyReleased(KeyEvent e) {
				}
				
			});
			combo.addFocusListener( new FocusListener() {

				@Override
				public void focusGained(FocusEvent e) {
				}

				@Override
				public void focusLost(FocusEvent e) {
					if (keyPressed) {
						keyPressed = false;
						String text = comboViewer.getCombo().getText();
						comboViewer.setSelection(new StructuredSelection(text));
					}
				}
				
			});
		}

		buttons = null;
		if (canEdit || canCreateNew) {
			buttons =  getToolkit().createComposite(composite);
			buttons.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
			buttons.setLayout(new FillLayout(SWT.HORIZONTAL));

			if (canCreateNew) {
				createButton = getToolkit().createButton(buttons, null, SWT.PUSH);
				createButton.setImage( Activator.getDefault().getImage(IConstants.ICON_ADD_20));
				createButton.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						buttonClicked(ID_CREATE_BUTTON);
						fillCombo();
					}
				});
			}
			if (canEdit) {
				editButton = getToolkit().createButton(buttons, null, SWT.PUSH);
				editButton.setImage( Activator.getDefault().getImage(IConstants.ICON_EDIT_20));
				editButton.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						buttonClicked(ID_EDIT_BUTTON);
						fillCombo();
					}
				});
				editButton.setEnabled(canEdit());
			}
		}

		fillCombo();

		comboViewer.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				if (!isWidgetUpdating) {
					ISelection selection = comboViewer.getSelection();
					if (selection instanceof StructuredSelection) {
						String firstElement = (String) ((StructuredSelection) selection).getFirstElement();
						if(firstElement!=null && comboViewer.getData(firstElement)!=null)
							setValue(comboViewer.getData(firstElement));
						else {
							if (firstElement!=null && firstElement.isEmpty())
								firstElement = null;
							if (firstElement==null)
								firstElement = comboViewer.getCombo().getText();
							setValue(firstElement);
							fillCombo();
						}
						if (editButton!=null)
							editButton.setEnabled(canEdit() && firstElement!=null && !firstElement.isEmpty());
					}
				}
			}
		});
		
		return combo;
	}

	protected void buttonClicked(int buttonId) {
		if (buttonId==ID_CREATE_BUTTON) {
			// create a new target object
			try {
				EObject value = createObject();
				setValue(value);
				fillCombo();
			}
			catch (OperationCanceledException ex1) {
			}
			catch (Exception ex2) {
				Activator.logError(ex2);
			}
		}
		else if (buttonId==ID_EDIT_BUTTON) {
			ISelection selection = comboViewer.getSelection();
			if (selection instanceof StructuredSelection) {
				String firstElement = (String) ((StructuredSelection) selection).getFirstElement();
				if ((firstElement != null && firstElement.isEmpty())) {
					// nothing to edit
					firstElement = null;
				}
				if (firstElement != null && comboViewer.getData(firstElement) instanceof EObject) {
					EObject value = (EObject) comboViewer.getData(firstElement);
					try {
						value = editObject(value);
						setValue(value);
						fillCombo();
					}
					catch (OperationCanceledException ex1) {
					}
					catch (Exception ex2) {
						Activator.logError(ex2);
					}
				}
			}
		}
	}
	
	protected EObject createObject() throws Exception {
		FeatureEditingDialog dialog = createFeatureEditingDialog(null);
		dialog.setFeatureEType(featureEType);
		if ( dialog.open() == Window.OK)
			return dialog.getNewObject();
		throw new OperationCanceledException("Dialog Cancelled"); //$NON-NLS-1$
	}
	
	protected EObject editObject(EObject value) throws Exception {
		FeatureEditingDialog dialog = createFeatureEditingDialog(value);
		dialog.setFeatureEType(featureEType);
		if ( dialog.open() == Window.OK)
			return dialog.getNewObject();
		throw new OperationCanceledException("Dialog Cancelled"); //$NON-NLS-1$
	}

	@Override
	public boolean setValue(Object result) {
		keyPressed = false;
		return super.setValue(result);
	}

	@Override
	public Object getValue() {
		Object v =  object.eGet(feature);
		// hack to deal with List features: use the first element in the list to
		// determine which item to select as active in the combobox
		if (v instanceof EObjectEList) {
			EObjectEList list = (EObjectEList)v;
			if (list.size()>0)
				v = list.get(0);
		}
		return v;
	}

	public String getTextValue() {
		ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(object);
		if (adapter!=null) {
			return adapter.getFeatureDescriptor(feature).getTextValue();
		}
		return getValue().toString();
	}
	
	protected void fillCombo() {
		try {
			isWidgetUpdating = true;
			if (comboViewer!=null) {
				comboViewer.getCombo().setRedraw(false);
				Object oldValue =  getValue();
				String oldTextValue = getTextValue();
		
				while (comboViewer.getElementAt(0) != null)
					comboViewer.remove(comboViewer.getElementAt(0));
				
				choices = getChoiceOfValues(object, feature);
				if (canSetNull()) {
					// selecting this one will set the target's value to null
					comboViewer.add(""); //$NON-NLS-1$
				}
				
				// add all other possible selections
				ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(oldValue);
	
				StructuredSelection currentSelection = null;
				if (choices!=null) {
					ArrayList<String> list = new ArrayList<String>(choices.keySet());
					Collections.sort(list);
					for (String key : list) {
						comboViewer.add(key);
						// try to find selection using current value of this feature
						Object newValue = choices.get(key); 
						if (newValue!=null) {
							comboViewer.setData(key, newValue);
							if (currentSelection==null) {
								if (newValue.equals(oldValue) || key.equals(oldValue) || key.equals(oldTextValue)) {
									currentSelection = new StructuredSelection(key);
								}
								else if (adapter!=null) {
									if (adapter.getObjectDescriptor().equals(newValue)) {
										currentSelection = new StructuredSelection(key);
									}
								}
							}
						}
					}
				}
				if (currentSelection!=null)
					comboViewer.setSelection(currentSelection);
				if (editButton!=null)
					editButton.setEnabled(canEdit() && currentSelection!=null);
			}
		}
		finally {
			if (comboViewer!=null)
				comboViewer.getCombo().setRedraw(true);
			isWidgetUpdating = false;
		}
	}
	
	private boolean itemsChanged() {
		if (comboViewer==null)
			return false;

		Object newValue =  getValue();
		ExtendedPropertiesAdapter adapter = ExtendedPropertiesAdapter.adapt(newValue);

//		isWidgetUpdating = false;
//		Hashtable<String,Object> choices = new Hashtable<String,Object>();
//		int index = 0;
//		while (comboViewer.getElementAt(index) != null) {
//			String key = (String)comboViewer.getElementAt(index);
//			if (!key.isEmpty()) {
//				Object value = comboViewer.getData(key);
//				choices.put(key, value);
//			}
//			++index;
//		}
//		isWidgetUpdating = false;
		
		Hashtable<String,Object> newChoices = getChoiceOfValues(object, feature);

		if (choices==null || choices.size()!=newChoices.size())
			return true;
		
		StructuredSelection oldSelection = (StructuredSelection)comboViewer.getSelection();
		Object oldValue = oldSelection.getFirstElement();
		if (oldValue instanceof String)
			oldValue = comboViewer.getData((String)oldValue);
		if (oldValue==null) {
			if (newValue!=null)
				return true;
			else
				return false;
		}
		else if (adapter!=null) {
			if (!adapter.getObjectDescriptor().equals(oldValue))
				return true;
		}
		else if (!oldValue.equals(newValue))
			return true;

		for (Entry<String, Object> entry : newChoices.entrySet()) {
			oldValue = choices.get(entry.getKey());
			newValue = entry.getValue();
			adapter = ExtendedPropertiesAdapter.adapt(newValue);
			if (newValue==null) {
				if (oldValue!=null)
					return true;
			}
			else if (adapter!=null) {
				if (!adapter.getObjectDescriptor().equals(oldValue))
					return true;
			}
			else if (!newValue.equals(oldValue))
				return true;
		}
		return false;
	}

	private ComboViewer createComboViewer(Composite parent, AdapterFactoryLabelProvider labelProvider, int style) {
		ComboViewer comboViewer = new ComboViewer(parent, style);
		comboViewer.setLabelProvider(labelProvider);
		return comboViewer;
	}
	
	@Override
	public void notifyChanged(Notification notification) {
		super.notifyChanged(notification);
		if ((notification.getEventType() == -1 || notification.getFeature()==feature) && itemsChanged()) {
			fillCombo();
		}
	}
	
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		comboViewer.getCombo().setVisible(visible);
		GridData data = (GridData)comboViewer.getCombo().getLayoutData();
		data.exclude = !visible;
		if (buttons!=null) {
			buttons.setVisible(visible);
			data = (GridData)buttons.getLayoutData();
			data.exclude = !visible;
		}
	}
	
	public void dispose() {
		super.dispose();
		if (comboViewer!=null && !comboViewer.getCombo().isDisposed()) {
			comboViewer.getCombo().dispose();
			comboViewer = null;
		}
		if (editButton!=null && !editButton.isDisposed()) {
			editButton.dispose();
			editButton = null;
		}
		if (createButton!=null && !createButton.isDisposed()) {
			createButton.dispose();
			createButton = null;
		}
		if (buttons!=null && !buttons.isDisposed()) {
			buttons.dispose();
			buttons = null;
		}
	}
	
	public Control getControl() {
		return comboViewer.getCombo();
	}
}
