/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.core.common.editpart.emf;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.DelegatingEditPartManager;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpartProvider;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YElement;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.runtime.common.dispose.IDisposable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// TODO: Auto-generated Javadoc
/**
 * The implementation of the main edit part. <br>
 * The whole ui is based on an ui model which is built by emf. And each edit
 * part is based on an EObject (ui model element) that is given in the
 * initialize method and contains all information required to render the ui
 * element. The edit part is just the controller that renders the ui but the
 * informations how to render is given by the EObject.
 * <p>
 * For general, edit parts have 3 different kind of methods. <br>
 * <h3>API</h3> API are public methods that are declared by the interfaces. They
 * can be used to create the ui based on the edit parts like
 * <p>
 * <code>
 * layoutEditpart.addElement(element)
 * </code>
 * <p>
 * Internally these methods do not handle the calls directly, but will delegate
 * to the underlying EMF model. What means, that the implementation of the
 * public methods do not create ui, but just changes the EObject.
 * 
 * <h3>EMF adpater</h3>
 * Since each edit part inherits {@link Adapter} and observes all the
 * notifications from the assigned element, the changes made by the public API
 * methods will notify the {@link #notifyChanged(Notification)} method that
 * delegates the call to the handleModel_... methods.<br>
 * 
 * <h3>Internal methods</h3> The handleModel_... methods interpret the model
 * change and invoke the internal... methods. These are responsible to make the
 * changes to internal state of the edit part.
 * 
 * <h3>Advantage</h3> The advantage of that pattern is to provide a very
 * flexible API. The ui can be built up by the edit parts, but it can be also
 * defined based on the underlying emf model.
 * 
 * <h3>Presenters</h3> The presenter used to render the ui by a special ui-kit
 * may use databinding. Therefore they can bind the emf model directly to become
 * notified of changes to the ui model. But they can also bind the edit parts
 * properties. But attention! Binding an edit part can only notify about edit
 * part related changes. For instance, if a new edit part was prepared based on
 * a model change. All returned lists for <code>"List get[Element]()"</code>
 * should return an unmodifiable bindable list representation like a
 * UnmodifiableObservableList.
 * <p>
 *
 * @param <M>
 *            the generic type
 */
public abstract class ElementEditpart<M extends YElement> extends AdapterImpl
		implements IElementEditpart, IElementEditpartProvider {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(ElementEditpart.class);

	/** The disposed. */
	private boolean disposed;

	/** The dispose listeners. */
	private List<IDisposable.Listener> disposeListeners;

	/** The model. */
	private M model;

	/** The id. */
	private String id;

	/** The disposing. */
	private boolean disposing;

	protected IViewContext viewContext;

	/**
	 * Returns the edit part for the given model yElement.
	 * 
	 * @param <A>
	 *            An instance of {@link IElementEditpart}
	 * @param yElement
	 *            the model element
	 * @return editpart
	 */
	public static <A extends IElementEditpart> A findEditPartFor(
			YElement yElement) {
		return EditpartManager.findEditPartFor(yElement);
	}

	/**
	 * Returns an existing edit part or creates a new one.
	 * 
	 * @param <A>
	 *            An instance of {@link IElementEditpart}
	 * @param context
	 *            the context to be used to create the editpart
	 * @param yElement
	 *            the model element
	 * @return editpart
	 */
	public static <A extends IElementEditpart> A getEditpart(
			IViewContext context, YElement yElement) {
		if (yElement == null) {
			return null;
		}

		A editPart = findEditPartFor(yElement);
		if (editPart != null) {
			return editPart;
		}
		return DelegatingEditPartManager.getInstance().getEditpart(context,
				yElement);
	}

	public IViewContext getContext() {
		return viewContext;
	}

	/**
	 * Returns the view context for the given embeddable.
	 *
	 * @param yEmbeddable
	 *            the y embeddable
	 * @return the view context
	 */
	public static IViewContext getViewContext(YEmbeddable yEmbeddable) {
		IViewEditpart viewEditpart = getViewEditpart(yEmbeddable);
		return viewEditpart != null ? viewEditpart.getContext() : null;
	}

	/**
	 * Returns the view editpart for the given embeddable. Or <code>null</code>.
	 *
	 * @param yEmbeddable
	 *            the y embeddable
	 * @return the view editpart
	 */
	public static IViewEditpart getViewEditpart(YEmbeddable yEmbeddable) {
		IEmbeddableEditpart editpart = findEditPartFor(yEmbeddable);
		return editpart != null ? editpart.getView() : null;
	}

	/**
	 * Returns the view context for the given embeddable.
	 *
	 * @param eObject
	 *            the context
	 * @return the view context
	 */
	public static IViewContext getViewContext(EObject eObject) {
		if (eObject == null) {
			return null;
		}

		if (eObject instanceof YElement) {
			IElementEditpart editpart = findEditPartFor((YElement) eObject);
			if (editpart != null && editpart.getContext() != null) {
				return editpart.getContext();
			}
		}

		// // otherwise iterate up the hierarchy to find a view context
		// if (context instanceof YEmbeddable) {
		// IViewEditpart viewEditpart = getViewEditpart((YEmbeddable) context);
		// return viewEditpart != null ? viewEditpart.getContext() : null;
		// } else if (context instanceof YView) {
		// IViewEditpart viewEditpart = getEditpart((YView) context);
		// return viewEditpart != null ? viewEditpart.getContext() : null;
		// } else {
		EObject parent = eObject.eContainer();
		return getViewContext(parent);
		// }
	}

	/**
	 * The default constructor.
	 */
	protected ElementEditpart() {
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getId() {
		checkDisposed();

		return id;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public M getModel() {
		// do not check disposed here. The model is required for lifecycle
		// events directly after disposing stuff.
		return model;
	}

	/**
	 * Is called to initialize this edit part with the given model. The editpart
	 * will be built based on the given model.
	 * 
	 * @param model
	 *            the model element
	 */
	public void initialize(IViewContext context, M model) {
		checkDisposed();

		if (this.model != null) {
			LOGGER.error("Editparts must only be initialized once!");
			throw new IllegalStateException(
					"Editparts must only be initialized once!");
		}

		this.viewContext = context;

		checkAdapter(model);

		this.model = model;

		id = model.getId();
		if (id == null || id.equals("")) {
			id = UUID.randomUUID().toString();
			model.setId(id);
		}

		registerAdapter(this);

		viewContext = getViewContext(model);
	}

	protected void checkAdapter(M model) {
		for (Adapter adapter : castEObject(model).eAdapters()) {
			if (adapter instanceof IElementEditpartProvider) {
				LOGGER.error("For a modelelement instance only one editpart can be created!");
				throw new RuntimeException(
						"For a modelelement instance only one editpart can be created!");
			}
		}
	}

	/**
	 * Casts element to eObject.
	 *
	 * @param element
	 *            the element
	 * @return the e object
	 */
	protected EObject castEObject(M element) {
		return (EObject) element;
	}

	/**
	 * Implementation of {@link IElementEditpartProvider} and returns
	 * <code>this</code> in that special case.
	 * 
	 * {@inheritDoc}
	 */
	@Override
	public IElementEditpart getEditpart() {
		checkDisposed();

		return this;
	}

	/**
	 * Registers an adapter at the model element.
	 * 
	 * @param adapter
	 *            The adapter to be added to the model element
	 */
	protected void registerAdapter(Adapter adapter) {
		checkDisposed();

		EObject eObject = castEObject(model);
		if (!eObject.eAdapters().contains(adapter)) {
			eObject.eAdapters().add(adapter);
		}
	}

	/**
	 * Unregisters an adapter at the model element.
	 * 
	 * @param adapter
	 *            The adapter to be removed from the model element
	 */
	protected void unregisterAdapter(Adapter adapter) {
		castEObject(model).eAdapters().remove(adapter);
	}

	/**
	 * Is called by the emf model element, if state changed.
	 * 
	 * @param notification
	 *            notification to be processed
	 */
	public void notifyChanged(Notification notification) {
		int featureId = notification.getFeatureID(YElement.class);
		switch (notification.getEventType()) {
		case Notification.ADD:
			handleModelAdd(featureId, notification);
			break;
		case Notification.ADD_MANY:
			handleModelAddMany(featureId, notification);
			break;
		case Notification.REMOVE:
			handleModelRemove(featureId, notification);
			break;
		case Notification.REMOVE_MANY:
			handleModelRemoveMany(featureId, notification);
			break;
		case Notification.MOVE:
			handleModelMove(featureId, notification);
			break;
		case Notification.SET:
			handleModelSet(featureId, notification);
			break;
		default:

		}
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the
	 * add-many-event to be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelRemoveMany(int featureId,
			Notification notification) {
		checkDisposed();
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the
	 * remove-many-event to be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelAddMany(int featureId, Notification notification) {
		checkDisposed();
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the add-event to
	 * be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelAdd(int featureId, Notification notification) {
		checkDisposed();
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the remove-event
	 * to be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelRemove(int featureId, Notification notification) {
		checkDisposed();
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the move-event to
	 * be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelMove(int featureId, Notification notification) {
		checkDisposed();
	}

	/**
	 * Is called from {@link #notifyChanged(Notification)} for the set-event to
	 * be handled by subclasses.
	 * 
	 * @param featureId
	 *            The featureId the notication belongs to
	 * @param notification
	 *            The notfication
	 */
	protected void handleModelSet(int featureId, Notification notification) {
		checkDisposed();

		if (featureId == CoreModelPackage.YELEMENT__ID) {
			throw new IllegalArgumentException("The id must never be changed!");
		}
	}

	/**
	 * Returns true, of the UI element contains a tag with the given tagName.
	 *
	 * @param tag
	 *            the tag
	 * @return true, if successful
	 */
	public boolean containsTag(String tag) {
		return getModel().getTags().contains(tag);
	}

	/**
	 * Returns true, of the UI element contains a property with the given key.
	 *
	 * @param key
	 *            the key
	 * @return true, if successful
	 */
	public boolean containsProperty(String key) {
		return getModel().getProperties().contains(key);
	}

	/**
	 * Returns the property value from the UI element with the given key.
	 *
	 * @param key
	 *            the key
	 * @return the property value
	 */
	public String getPropertyValue(String key) {
		return getModel().getProperties().get(key);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isDisposed() {
		return disposed;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isDisposing() {
		return disposing;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void dispose() {
		try {
			disposing = true;
			if (!isDisposed()) {
				internalDispose();
			}
		} finally {
			disposing = false;
		}
	}

	/**
	 * Is called to dispose all this instance.
	 */
	protected void internalDispose() {
		try {
			// unregisters the observer from observing the model
			unregisterAdapter(this);

			// first call the dispose listener and the set disposed=true
			notifyDisposeListeners();

			viewContext = null;
		} finally {
			disposed = true;
		}
	}

	/**
	 * Subclasses may override.
	 * <p>
	 * Default implementation of request dispose directly invokes #dispose()
	 */
	@Override
	public void requestDispose() {
		dispose();
	}

	/**
	 * Checks whether the element is disposed. Throws a DisposeException is the
	 * element is disposed.
	 *
	 * @throws DisposeException
	 *             the dispose exception
	 */
	protected void checkDisposed() {
		IDisposable.DisposableUtil.checkDisposed(this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.runtime.common.dispose.IDisposable#addDisposeListener
	 * (org.eclipse.osbp.runtime.common.dispose.IDisposable.Listener)
	 */
	@Override
	public void addDisposeListener(Listener listener) {
		checkDisposed();

		if (listener == null) {
			return;
		}

		if (disposeListeners == null) {
			disposeListeners = new ArrayList<IDisposable.Listener>();
		}

		if (!disposeListeners.contains(listener)) {
			disposeListeners.add(listener);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.runtime.common.dispose.IDisposable#removeDisposeListener
	 * (org.eclipse.osbp.runtime.common.dispose.IDisposable.Listener)
	 */
	@Override
	public void removeDisposeListener(Listener listener) {
		checkDisposed();

		if (listener == null || disposeListeners == null) {
			return;
		}

		disposeListeners.remove(listener);
	}

	/**
	 * Notifies all listeners about the disposal of that elemenyElement.
	 */
	protected void notifyDisposeListeners() {
		if (disposeListeners == null) {
			return;
		}

		for (IDisposable.Listener listener : disposeListeners
				.toArray(new IDisposable.Listener[disposeListeners.size()])) {
			listener.notifyDisposed(this);
		}
	}
}
