/**
 *                                                                            
 *  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
 * 
 */
package org.eclipse.osbp.ecview.extension.editparts.emf;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.osbp.ecview.core.common.editpart.ICommandEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableEndpointEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessorEditpart;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingSet;
import org.eclipse.osbp.ecview.core.common.model.core.YCommand;
import org.eclipse.osbp.ecview.core.common.model.core.YCommandSet;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.visibility.YVisibilityProcessor;
import org.eclipse.osbp.ecview.extension.editparts.ISuspectEditpart;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.ecview.extension.model.YSuspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implementation of {@link ISuspectEditpart}.
 */
public class SuspectEditpart extends ElementEditpart<YSuspect> implements
		ISuspectEditpart {

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

	/** The bindings. */
	private List<IBindableEndpointEditpart> bindings;
	
	/** The commands. */
	private List<ICommandEditpart> commands;
	
	/** The visibility processors. */
	private List<IVisibilityProcessorEditpart> visibilityProcessors;

	/**
	 * A default constructor.
	 */
	protected SuspectEditpart() {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#createModel()
	 */
	//
	// @Override
	// protected void doInitPresentation(IWidgetPresentation<?> presentation) {
	// IFieldPresentation<?> fieldPresentation = (IFieldPresentation<?>)
	// presentation;
	//
	// if (fieldPresentation == null) {
	// LOGGER.warn("Presentation is null for " + getModel());
	// return;
	// }
	// }

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#handleModelAdd(int, org.eclipse.emf.common.notify.Notification)
	 */
	@Override
	protected void handleModelAdd(int featureId, Notification notification) {
		checkDisposed();

		switch (featureId) {
		case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
			YBindingEndpoint yBindingEndpoint = (YBindingEndpoint) notification
					.getNewValue();

			IBindableEndpointEditpart editPart = (IBindableEndpointEditpart) getEditpart(getContext(),yBindingEndpoint);
			internalAddBindingEndpoint(editPart);
			break;
		case YECviewPackage.YSUSPECT__COMMANDS:
			YCommand yCommand = (YCommand) notification.getNewValue();

			ICommandEditpart cEditPart = (ICommandEditpart) getEditpart(getContext(),yCommand);
			internalAddCommand(cEditPart);
			break;
		case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
			YVisibilityProcessor yProcessor = (YVisibilityProcessor) notification
					.getNewValue();

			IVisibilityProcessorEditpart pEditPart = (IVisibilityProcessorEditpart) getEditpart(getContext(),yProcessor);
			internalAddVisibilityProcessor(pEditPart);
			break;
		default:
			break;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#handleModelRemove(int, org.eclipse.emf.common.notify.Notification)
	 */
	@Override
	protected void handleModelRemove(int featureId, Notification notification) {
		checkDisposed();

		switch (featureId) {
		case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
			YBindingEndpoint yBindingEndpoint = (YBindingEndpoint) notification
					.getOldValue();

			IBindableEndpointEditpart editPart = (IBindableEndpointEditpart) getEditpart(getContext(),yBindingEndpoint);
			internalRemoveBindingEndpoint(editPart);
			break;
		case YECviewPackage.YSUSPECT__COMMANDS:
			YCommand yCommand = (YCommand) notification.getOldValue();

			ICommandEditpart cEditPart = (ICommandEditpart) getEditpart(getContext(),yCommand);
			internalRemoveCommand(cEditPart);
			break;
		case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
			YVisibilityProcessor yProcessor = (YVisibilityProcessor) notification
					.getOldValue();

			IVisibilityProcessorEditpart pEditPart = (IVisibilityProcessorEditpart) getEditpart(getContext(),yProcessor);
			internalRemoveVisibilityProcessor(pEditPart);
			break;
		default:
			break;
		}
	}

	/**
	 * Ensures that the internal bindings are loaded properly.
	 */
	private void ensureBindingEndpointsLoaded() {
		if (bindings == null) {
			internalLoadBindingEndpoints();
		}
	}

	/**
	 * Is called to load and initialize all bindings.
	 */
	protected void internalLoadBindingEndpoints() {
		checkDisposed();

		if (bindings == null) {
			bindings = new ArrayList<IBindableEndpointEditpart>();
			for (YBindingEndpoint yBindingEP : getModel()
					.getValueBindingEndpoints()) {
				IBindableEndpointEditpart editPart = getEditpart(getContext(),yBindingEP);
				internalAddBindingEndpoint(editPart);
			}
		}
	}

	/**
	 * Is called to change the internal state and add the given editpart to the
	 * list of bindings.
	 * 
	 * @param editpart
	 *            The editpart to be added
	 */
	protected void internalAddBindingEndpoint(IBindableEndpointEditpart editpart) {
		checkDisposed();

		ensureBindingEndpointsLoaded();
		if (!bindings.contains(editpart)) {
			bindings.add(editpart);
		}
	}

	/**
	 * Is called to change the internal state and remove the given editpart from
	 * the list of bindings.
	 * 
	 * @param editpart
	 *            The editpart to be removed
	 */
	protected void internalRemoveBindingEndpoint(
			IBindableEndpointEditpart editpart) {
		checkDisposed();

		if (bindings != null && editpart != null) {
			bindings.remove(editpart);
		}
	}

	/**
	 * Gets the binding endpoints.
	 *
	 * @return the binding endpoints
	 */
	public List<IBindableEndpointEditpart> getBindingEndpoints() {
		ensureBindingEndpointsLoaded();
		return Collections.unmodifiableList(bindings);
	}

	/**
	 * Ensures that the internal commands are loaded properly.
	 */
	private void ensureCommandsLoaded() {
		if (commands == null) {
			internalLoadCommands();
		}
	}

	/**
	 * Is called to load and initialize all commands.
	 */
	protected void internalLoadCommands() {
		checkDisposed();

		if (commands == null) {
			commands = new ArrayList<ICommandEditpart>();
			for (YCommand yCommand : getModel().getCommands()) {
				ICommandEditpart editPart = getEditpart(getContext(),yCommand);
				internalAddCommand(editPart);
			}
		}
	}

	/**
	 * Is called to change the internal state and add the given editpart to the
	 * list of commands.
	 * 
	 * @param editpart
	 *            The editpart to be added
	 */
	protected void internalAddCommand(ICommandEditpart editpart) {
		checkDisposed();

		ensureCommandsLoaded();
		if (!commands.contains(editpart)) {
			commands.add(editpart);
		}
	}

	/**
	 * Is called to change the internal state and remove the given editpart from
	 * the list of commands.
	 * 
	 * @param editpart
	 *            The editpart to be removed
	 */
	protected void internalRemoveCommand(ICommandEditpart editpart) {
		checkDisposed();

		if (commands != null && editpart != null) {
			commands.remove(editpart);
		}
	}

	/**
	 * Gets the commands.
	 *
	 * @return the commands
	 */
	public List<ICommandEditpart> getCommands() {
		ensureCommandsLoaded();
		return Collections.unmodifiableList(commands);
	}

	/**
	 * Ensures that the internal visibilityProcessors are loaded properly.
	 */
	private void ensureVisibilityProcessorLoaded() {
		if (visibilityProcessors == null) {
			internalLoadVisibilityProcessors();
		}
	}

	/**
	 * Is called to load and initialize all visibilityProcessors.
	 */
	protected void internalLoadVisibilityProcessors() {
		checkDisposed();

		if (visibilityProcessors == null) {
			visibilityProcessors = new ArrayList<IVisibilityProcessorEditpart>();
			for (YVisibilityProcessor yVisibilityProcessor : getModel()
					.getVisibilityProcessors()) {
				IVisibilityProcessorEditpart editPart = getEditpart(getContext(),yVisibilityProcessor);
				internalAddVisibilityProcessor(editPart);
			}
		}
	}

	/**
	 * Is called to change the internal state and add the given editpart to the
	 * list of visibilityProcessors.
	 *
	 * @param editpart
	 *            the editpart
	 */
	protected void internalAddVisibilityProcessor(
			IVisibilityProcessorEditpart editpart) {
		checkDisposed();

		ensureVisibilityProcessorLoaded();
		if (!visibilityProcessors.contains(editpart)) {
			visibilityProcessors.add(editpart);
		}
	}

	/**
	 * Is called to change the internal state and remove the given editpart from
	 * the list of visibilityProcessors.
	 * 
	 * @param editpart
	 *            The editpart to be removed
	 */
	protected void internalRemoveVisibilityProcessor(
			IVisibilityProcessorEditpart editpart) {
		checkDisposed();

		if (visibilityProcessors != null && editpart != null) {
			visibilityProcessors.remove(editpart);
		}
	}

	/**
	 * Gets the visibility processors.
	 *
	 * @return the visibility processors
	 */
	public List<IVisibilityProcessorEditpart> getVisibilityProcessors() {
		ensureVisibilityProcessorLoaded();
		return Collections.unmodifiableList(visibilityProcessors);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#internalDispose()
	 */
	@Override
	protected void internalDispose() {
		try {
			
			LOGGER.info("Disposing " + toString());
			
			// lazy loading: edit parts also have to be disposed if they have
			// not been loaded yet, but exist in the model.
			if (bindings != null
					|| getModel().getValueBindingEndpoints().size() > 0) {
				List<IBindableEndpointEditpart> tempElements = getBindingEndpoints();
				synchronized (bindings) {
					for (IBindableEndpointEditpart editpart : tempElements
							.toArray(new IBindableEndpointEditpart[tempElements
									.size()])) {
						editpart.dispose();
					}
				}
			}
			bindings = null;
			
			if (commands != null || getModel().getCommands().size() > 0) {
				List<ICommandEditpart> tempElements = getCommands();
				synchronized (commands) {
					for (ICommandEditpart editpart : tempElements
							.toArray(new ICommandEditpart[tempElements.size()])) {
						editpart.dispose();
					}
				}
			}
			commands = null;

			if (visibilityProcessors != null
					|| getModel().getVisibilityProcessors().size() > 0) {
				List<IVisibilityProcessorEditpart> tempElements = getVisibilityProcessors();
				synchronized (visibilityProcessors) {
					for (IVisibilityProcessorEditpart editpart : tempElements
							.toArray(new IVisibilityProcessorEditpart[tempElements
									.size()])) {
						editpart.dispose();
					}
				}
			}
			visibilityProcessors = null;

		} finally {
			super.internalDispose();
		}
	}

/**
	// * Is called to created the presenter for this edit part.<br>
	// * We are forwarding to the element presentation.
	// */
	// protected <A extends IWidgetPresentation<?>> A createPresenter() {
	// IViewEditpart viewEditPart = getView();
	// if (viewEditPart == null) {
	// LOGGER.info("View is null");
	// return null;
	// }
	//
/**
/**
	// YEmbeddable yEmbeddable = getModel().getElement();
	// IEmbeddableEditpart editpart = getEditpart(getContext(),yEmbeddable);
	// return DelegatingPresenterFactory.getInstance().createPresentation(
	// viewEditPart.getContext(), editpart);
	// }

	// @Override
	// public Object render(Object parentWidget) {
	// internalActivate();
	//
	// return getPresentation().createWidget(parentWidget);
	// }
	//
	// @Override
	// public void unrender() {
	// getPresentation().unrender();
	//
	// internalDeactivate();
	// }

	/**
	 * Internally activates the suspect.
	 */
	protected void internalActivate() {

		YView yView = (YView) getView();

		// activate bindings
		 YBindingSet yBindingSet = yView.getOrCreateBindingSet();
		 yBindingSet.getTransientBindings().addAll(getModel().getAssociatedBindings());

		// activate commands
		YCommandSet yCommandSet = yView.getCommandSet();
		yCommandSet.getTransientCommands().addAll(getModel().getCommands());

		// activate visibilityProcessors
		yView.getTransientVisibilityProcessors().addAll(
				getModel().getVisibilityProcessors());

	}

	/**
	 * Gets the view.
	 *
	 * @return the view
	 */
	public IViewEditpart getView() {
		YView yView = ((YStrategyLayout) getModel().eContainer()).getView();
		return yView != null ? (IViewEditpart) getEditpart(getContext(),yView) : null;
	}

	/**
	 * Internally deactivates the suspect.
	 */
	protected void internalDeactivate() {
		YView yView = (YView) getView();

		// deactivate bindings
		 YBindingSet yBindingSet = yView.getOrCreateBindingSet();
		 yBindingSet.getTransientBindings().removeAll(getModel().getAssociatedBindings());

		// deactivate commands
		YCommandSet yCommandSet = yView.getCommandSet();
		yCommandSet.getTransientCommands().removeAll(getModel().getCommands());

		// deactivate visibilityProcessors
		yView.getTransientVisibilityProcessors().removeAll(
				getModel().getVisibilityProcessors());
	}
}
