package at.ecrit.e4.tools.extension.core.listener;

import java.util.Map.Entry;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.e4.ui.model.application.impl.ApplicationFactoryImpl;
import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;

public class PersistedStateValueChangeListener implements IValueChangeListener {

	private String key;
	private IObservableValue value;
	private EditingDomain editingDomain;

	public PersistedStateValueChangeListener(String key,
			IObservableValue value, EditingDomain editingDomain) {
		this.key = key;
		this.value = value;
		this.editingDomain = editingDomain;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void handleValueChange(ValueChangeEvent event) {
		EObject applicationElementObject = (EObject) value.getValue();
		if (applicationElementObject == null)
			return;
		EMap<String, String> persistentState = (EMap<String, String>) applicationElementObject
				.eGet(ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__PERSISTED_STATE);
		int indexOfKey = persistentState.indexOfKey(key);

		String value = (String) event.getObservableValue().getValue();

		Command command = null;

		if (indexOfKey == -1) {
			BasicEMap.Entry<String, String> entry = (org.eclipse.emf.common.util.BasicEMap.Entry<String, String>) ApplicationFactoryImpl.eINSTANCE
					.createStringToStringMap();
			entry.setKey(key);
			entry.setHash(key.hashCode());
			entry.setValue(value);
			command = AddCommand
					.create(editingDomain,
							applicationElementObject,
							ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__PERSISTED_STATE,
							entry);
		} else {
			Entry<String, String> entry = persistentState.get(indexOfKey);
			entry.setValue(value);
			command = SetCommand
					.create(editingDomain,
							entry,
							ApplicationPackageImpl.Literals.STRING_TO_STRING_MAP__VALUE,
							value);
		}
		if (command.canExecute()) {
			editingDomain.getCommandStack().execute(command);
		}
	}

}
