/*
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  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:                                                      
 * 	   Florian Pirchner - Initial implementation
 *     Loetz GmbH&Co.KG                               
 * 
 */
package org.eclipse.osbp.vaadin.emf.data;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.eclipse.osbp.vaadin.emf.api.IModelingContext;
import org.eclipse.osbp.vaadin.emf.views.UiSync;

import com.vaadin.data.Item;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.server.Resource;

// TODO: Auto-generated Javadoc
/**
 * The base container to provide eObject hierarchy and their values based on
 * emf.edit. It registers a change notifier on the model to refresh items on the
 * fly.
 * <p>
 * ATTENTION: This container MUST be disposed!
 */
@SuppressWarnings("serial")
public class EmfModelTreeContainer extends HierarchicalContainer {

	/** The Constant ICON. */
	private static final String ICON = "icon";
	
	/** The Constant LABEL. */
	private static final String LABEL = "label";

	/** The root element. */
	private EObject rootElement;
	
	/** The editing domain. */
	private final EditingDomain editingDomain;
	
	/** The adapter factory. */
	private final AdapterFactory adapterFactory;
	
	/** The ui sync. */
	private final UiSync uiSync;

	/** The resolved. */
	private Set<Object> resolved = new HashSet<Object>();
	
	/** The resource provider. */
	private IResourceProvider resourceProvider;
	
	/** The change listener. */
	private INotifyChangedListener changeListener;

	/**
	 * Instantiates a new emf model tree container.
	 *
	 * @param modelingContext
	 *            the modeling context
	 * @param resourceProvider
	 *            the resource provider
	 * @param uiSync
	 *            the ui sync
	 */
	public EmfModelTreeContainer(IModelingContext modelingContext,
			IResourceProvider resourceProvider, UiSync uiSync) {
		this.resourceProvider = resourceProvider;
		this.editingDomain = modelingContext.getEditingDomain();
		this.adapterFactory = modelingContext.getAdapterFactory();
		this.uiSync = uiSync;

		addContainerProperty(LABEL, String.class, "");
		addContainerProperty(ICON, Resource.class, null);

		IChangeNotifier notifier = (IChangeNotifier) modelingContext
				.getAdapterFactory();
		notifier.addListener(getModelChangeListener());
	}

	/**
	 * Gets the root element.
	 *
	 * @return the root element
	 */
	public EObject getRootElement() {
		return rootElement;
	}

	/**
	 * Sets the root element.
	 *
	 * @param rootElement
	 *            the new root element
	 */
	public void setRootElement(EObject rootElement) {
		if (this.rootElement == rootElement) {
			return;
		}

		removeAllItems();
		resolved.clear();

		this.rootElement = rootElement;

		loadRootElements();
	}

	/**
	 * Load root elements.
	 */
	private void loadRootElements() {
		if (rootElement != null) {
			doAddItem(null, rootElement, -1);
			resolveChildren(rootElement);
		}
	}

	/**
	 * Resolve children.
	 *
	 * @param itemId
	 *            the item id
	 */
	public void resolveChildren(Object itemId) {
		// if children are allowed and they have not been resolved so far
		if (areChildrenAllowed(itemId)
				&& (getChildren(itemId) == null || getChildren(itemId)
						.isEmpty())) {
			resolved.add(itemId);

			ITreeItemContentProvider parentTreeProvider = (ITreeItemContentProvider) adapterFactory
					.adapt(itemId, ITreeItemContentProvider.class);

			// resolve children
			for (Object newChild : parentTreeProvider.getChildren(itemId)) {
				doAddItem(itemId, (EObject) newChild, -1);
			}
		}
	}

	/**
	 * Refreshes the given node.
	 *
	 * @param itemId
	 *            the item id
	 */
	public void refreshNode(Object itemId) {
		for (Object child : new ArrayList<>(getChildren(itemId))) {
			removeItemRecursively(child);
		}
		resolved.remove(itemId);
		resolveChildren(itemId);
	}

	/**
	 * Adds a new item.
	 *
	 * @param parent
	 *            the parent
	 * @param newChild
	 *            the new child
	 * @param index
	 *            pass -1 for last index
	 */
	@SuppressWarnings("unchecked")
	private void doAddItem(Object parent, EObject newChild, int index) {
		if (newChild == null || (parent != null && !containsId(parent))) {
			return;
		}
		Item item;
		if (index >= 0) {
			item = addItemAt(index, newChild);
		} else {
			item = addItem(newChild);
		}
		if(item == null) {
			// TODO handle same EObject instances
			return;
		}
		IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory
				.adapt(newChild, IItemLabelProvider.class);
		item.getItemProperty(LABEL).setValue(labelProvider.getText(newChild));

		// parse the platform uri
		URL url = ((URL) labelProvider.getImage(newChild));
		item.getItemProperty(ICON).setValue(
				resourceProvider.getResource(url.toString()));

		// calculate children allowed
		// ITreeItemContentProvider treeProvider = (ITreeItemContentProvider)
		// adapterFactory
		// .adapt(newChild, ITreeItemContentProvider.class);
		// setChildrenAllowed(newChild, treeProvider.hasChildren(newChild));

		// if the newChild is not root and the container is available in the
		// tree
		if (newChild.eContainer() != null && containsId(newChild.eContainer())) {
			setParent(newChild, newChild.eContainer());
			// the new parent may have children again
			// setChildrenAllowed(newChild.eContainer(), true);
		}
	}

	/* (non-Javadoc)
	 * @see com.vaadin.data.util.HierarchicalContainer#hasChildren(java.lang.Object)
	 */
	@Override
	public boolean hasChildren(Object itemId) {
		boolean result = super.hasChildren(itemId);
		if (!result) {
			// calculate children allowed
			ITreeItemContentProvider treeProvider = (ITreeItemContentProvider) adapterFactory
					.adapt(itemId, ITreeItemContentProvider.class);
			result = treeProvider.hasChildren(itemId);
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see com.vaadin.data.util.HierarchicalContainer#areChildrenAllowed(java.lang.Object)
	 */
	@Override
	public boolean areChildrenAllowed(Object itemId) {
		// calculate children allowed
		ITreeItemContentProvider treeProvider = (ITreeItemContentProvider) adapterFactory
				.adapt(itemId, ITreeItemContentProvider.class);
		return treeProvider.hasChildren(itemId);
	}

	/**
	 * Gets the model change listener.
	 *
	 * @return the model change listener
	 */
	private INotifyChangedListener getModelChangeListener() {
		this.changeListener = e -> handleNotification(e);
		return changeListener;
	}

	/**
	 * Refreshes the item with the given eObject.
	 *
	 * @param notification
	 *            the notification
	 */
	protected void handleNotification(Notification notification) {
		if (notification.isTouch()) {
			return;
		}

		switch (notification.getEventType()) {
		case Notification.ADD:
			uiSync.sync(new Runnable() {
				@Override
				public void run() {
					if (notification.getNewValue() instanceof EObject) {
						EObject addItem = (EObject) notification.getNewValue();
						doAddItem(addItem.eContainer(), addItem,
								notification.getPosition());
					}
				}
			});
			break;
		case Notification.REMOVE:
			uiSync.sync(new Runnable() {
				@Override
				public void run() {
					if (notification.getOldValue() instanceof EObject) {
						EObject removeItem = (EObject) notification
								.getOldValue();
						removeItemRecursively(removeItem);
					}
				}
			});
			break;
		case Notification.MOVE:
			EObject moveItem = (EObject) notification.getNewValue();
			EStructuralFeature feature = moveItem.eContainingFeature();
			if (feature.isMany()) {
				EObject container = moveItem.eContainer();
				// if the parent is not visible, then leave
				if (!containsId(container)) {
					return;
				}
				uiSync.sync(new Runnable() {
					@SuppressWarnings("unchecked")
					@Override
					public void run() {
						List<EObject> eObjects = (List<EObject>) container
								.eGet(feature);
						EObject previousSibling = null;
						if (notification.getPosition() > 0) {
							previousSibling = eObjects.get(notification
									.getPosition() - 1);
							moveAfterSibling(moveItem, previousSibling);
						}
					}
				});
			}
			break;
		case Notification.SET:
			// update the property with the changed value
			uiSync.sync(new Runnable() {
				@Override
				public void run() {
					EObject notifier = (EObject) notification.getNotifier();
					if (notification.getNewValue() instanceof EObject) {
						EObject itemId = (EObject) notification.getNewValue();
						// the containment reference was set
						if (itemId.eContainingFeature() == notification
								.getFeature()) {
							removeItem(itemId);
							doAddItem(itemId.eContainer(), itemId, -1);
						} else {
							refreshLabel(notifier);
						}
					} else {
						refreshLabel(notifier);
					}
				}

				@SuppressWarnings({ "unchecked" })
				private void refreshLabel(EObject notifier) {
					Item item = getItem(notifier);
					if (item != null) {
						IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory
								.adapt(notifier, IItemLabelProvider.class);
						item.getItemProperty(LABEL).setValue(
								labelProvider.getText(notifier));
					}
				}
			});
			break;
		case Notification.ADD_MANY:
			uiSync.sync(new Runnable() {
				@SuppressWarnings("unchecked")
				@Override
				public void run() {
					if (notification.getOldValue() instanceof Collection) {
						Collection<Object> elements = (Collection<Object>) notification
								.getNewValue();
						for (Object element : elements) {
							EObject addItem = (EObject) element;
							doAddItem(addItem.eContainer(), addItem,
									notification.getPosition());
						}
					}
				}
			});
			break;
		case Notification.REMOVE_MANY:
			uiSync.sync(new Runnable() {
				@SuppressWarnings("unchecked")
				@Override
				public void run() {
					if (notification.getOldValue() instanceof Collection) {
						Collection<Object> elements = (Collection<Object>) notification
								.getOldValue();
						for (Object element : elements) {
							EObject removeItem = (EObject) element;
							removeItemRecursively(removeItem);
						}
					}
				}
			});
			break;
		}
	}

	/**
	 * This container MUST be disposed!.
	 */
	public void dispose() {
		IChangeNotifier notifier = (IChangeNotifier) adapterFactory;
		notifier.removeListener(changeListener);
	}
}
