/**
 *                                                                            
 * 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.drools.event.process.ProcessCompletedEvent;
import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.Task;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.EventUtils;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.advanced.MAdvancedFactory;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
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.bpm.api.AbstractBlipBPMFunctionProvider;
import org.eclipse.osbp.bpm.api.IBPMTaskClient;
import org.eclipse.osbp.bpm.api.IBPMTaskEventNotification;
import org.eclipse.osbp.bpm.api.IBlipBPMConstants;
import org.eclipse.osbp.bpm.api.IBlipBPMStartInfo;
import org.eclipse.osbp.bpm.api.IBlipBPMWorkloadModifiableItem;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.organization.IOrganizationViewPartProvider;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.utils.bpmn.views.BpmnView;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.maintoolbar.IMainToolbarProvider;
import org.eclipse.osbp.vaaclipse.publicapi.authentication.AuthenticationConstants;
import org.eclipse.osbp.vaadin.emf.api.IModelingContext;
import org.eclipse.osbp.xtext.action.ActionDSLPackage;
import org.eclipse.osbp.xtext.action.ActionToolbar;
import org.eclipse.osbp.xtext.blip.BlipItem;
import org.eclipse.osbp.xtext.blip.BlipUserTask;
import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartPackage;
import org.eclipse.osbp.xtext.dialogdsl.Dialog;
import org.eclipse.osbp.xtext.dialogdsl.DialogDSLPackage;
import org.eclipse.osbp.xtext.dialogdsl.DialogPackage;
import org.eclipse.osbp.xtext.organizationdsl.Organization;
import org.eclipse.osbp.xtext.organizationdsl.OrganizationDSLPackage;
import org.eclipse.osbp.xtext.organizationdsl.OrganizationPackage;
import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveBPMN;
import org.eclipse.osbp.xtext.perspective.PerspectiveChart;
import org.eclipse.osbp.xtext.perspective.PerspectiveDialog;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveElement;
import org.eclipse.osbp.xtext.perspective.PerspectiveGrid;
import org.eclipse.osbp.xtext.perspective.PerspectiveOrganization;
import org.eclipse.osbp.xtext.perspective.PerspectivePart;
import org.eclipse.osbp.xtext.perspective.PerspectivePartStack;
import org.eclipse.osbp.xtext.perspective.PerspectiveReport;
import org.eclipse.osbp.xtext.perspective.PerspectiveSashContainer;
import org.eclipse.osbp.xtext.perspective.PerspectiveSelection;
import org.eclipse.osbp.xtext.perspective.PerspectiveTable;
import org.eclipse.osbp.xtext.perspective.PerspectiveTopology;
import org.eclipse.osbp.xtext.perspective.PerspectiveView;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.ReportPackage;
import org.eclipse.osbp.xtext.table.Table;
import org.eclipse.osbp.xtext.table.TableDSLPackage;
import org.eclipse.osbp.xtext.table.TablePackage;
import org.eclipse.osbp.xtext.topologydsl.Topology;
import org.eclipse.osbp.xtext.topologydsl.TopologyDSLPackage;
import org.eclipse.osbp.xtext.topologydsl.TopologyPackage;
import org.jbpm.task.event.entity.TaskEventType;
import org.jbpm.task.event.entity.TaskUserEvent;
import org.jbpm.task.query.TaskSummary;
import org.jbpm.task.service.Operation;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class PerspectiveSupport. Available as injectable service to create and maintain perspectives coming from the perspective DSL model.
 */
@SuppressWarnings("restriction")
public class PerspectiveSupport implements IBPMTaskEventNotification {

	/** The log. */
	private static Logger log = LoggerFactory.getLogger(PerspectiveSupport.class);

	/**
	 * Removes the perspective from stack if it is closed.
	 */
	private static final String TAG__REMOVE_ON_CLOSE = "remove_on_close";

	/**
	 * The perspective is not visible in the open perspective dialog.
	 */
	private static final String TAG__NOT_IN_OPEN_PERSPECTIVE_DIALOG = "not_in_open_perspective_dialog";

	/** The event broker. */
	@Inject
	private IEventBroker eventBroker;

	/** The app model. */
	@Inject
	private MApplication appModel;

	/** The eclipse context. */
	@Inject
	private IEclipseContext eclipseContext;

	@Inject
	private IModelingContext modelingContext;

	/** The theme resource service. */
	@Inject
	private IThemeResourceService themeResourceService;

	/** The current user. */
	@Inject
	private IUser user;

	/** The task client. */
	@Inject
	private IBPMTaskClient taskClient;

	/** The task provider */
	private AbstractBlipBPMFunctionProvider taskProvider;

	/** The dsl metadata service. */
	@Inject
	private IDSLMetadataService dslMetadataService;

	/** The toolbar provider. */
	@Inject
	@Named("MainToolbar")
	private IMainToolbarProvider toolbarProvider;

	@Inject
	@Optional
	private IOrganizationViewPartProvider optionalOrgURIProvider;

	/** The dispatch action. */
	private EventHandler dispatchAction;

	/** The do open perspective. */
	private EventHandler doOpenPerspective;

	/** The do close perspective. */
	private EventHandler doClosePerspective;

	/** The do logout. */
	private EventHandler doLogout;

	/** The basic factory. */
	private BasicFactoryImpl basicFactory;

	/** The advanced factory. */
	private MAdvancedFactory advancedFactory;

	/** The current perspective stack. */
	private MPerspectiveStack currentPerspectiveStack = null;

	/** The trimmed window. */
	private MTrimmedWindow trimmedWindow = null;

	/** The trim bar. */
	private MTrimBar trimBar = null;

	/** The model service. */
	private EModelService modelService;

	/** The perspectives. */
	private Map<String, MPerspective> perspectives = new HashMap<>();

	/** The perspective tasks. */
	private Map<Long, String> perspectiveTasks = new HashMap<>();

	/**
	 * Inits the PerspectiveSupport.
	 */
	@PostConstruct
	protected void init() {
		perspectives.clear();
		perspectiveTasks.clear();
		basicFactory = BasicFactoryImpl.init();
		advancedFactory = AdvancedFactoryImpl.init();
		modelService = eclipseContext.get(EModelService.class);
		subscribe();
	}

	/**
	 * Prepare perspective contexts.
	 */
	private void prepareContext() {
		log.debug("analyze app model");
		if (appModel != null) {
			trimmedWindow = null;
			if (appModel.getChildren().isEmpty()) {
				trimmedWindow = BasicFactoryImpl.eINSTANCE.createTrimmedWindow();
				trimmedWindow.setToBeRendered(true);
				trimmedWindow.setVisible(true);
				appModel.getChildren().add(trimmedWindow);
			} else {
				trimmedWindow = (MTrimmedWindow) appModel.getChildren().get(0);
			}
			// find perspective stack
			if (trimmedWindow.getChildren().isEmpty()) {
				// create perspective stack
				currentPerspectiveStack = advancedFactory.createPerspectiveStack();
				currentPerspectiveStack.setElementId(PerspectiveConstants.E4Constants.PERSPECTIVESTACK);
				currentPerspectiveStack.setToBeRendered(true);
				currentPerspectiveStack.setVisible(true);
			} else {
				for (MWindowElement element : trimmedWindow.getChildren()) {
					if (element instanceof MPerspectiveStack) { // NOSONAR
						currentPerspectiveStack = (MPerspectiveStack) element;
						break;
					}
				}
			}

			// find trimbar
			trimBar = null;
			if (trimmedWindow.getTrimBars().isEmpty()) {
				// create trimbar
				trimBar = basicFactory.createTrimBar();
				trimBar.setElementId(PerspectiveConstants.E4Constants.TRIMBAR);
				trimBar.setToBeRendered(true);
				trimBar.setVisible(true);
				trimBar.setSide(SideValue.TOP);
				trimmedWindow.getTrimBars().add(trimBar);
			} else {
				trimBar = trimmedWindow.getTrimBars().get(0);
			}
		}

		// handle toolbar
		((EObject) currentPerspectiveStack).eAdapters().add(new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				if (notification.getEventType() == Notification.SET
						&& notification.getFeatureID(MElementContainer.class) == AdvancedPackageImpl.PERSPECTIVE_STACK__SELECTED_ELEMENT) {
					log.debug("perspective stack changed selection");
					if (notification.getNewValue() == null && notification.getOldValue() != null
							&& PerspectiveSupport.isPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId())) {
						closePerspective(PerspectiveSupport.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId()), true);
					} else {
						// perspective changed
						if (notification.getNewValue() != notification.getOldValue()) {
							if (notification.getOldValue() != null) {
								// deactivate old perspective - hide its toolBar
								String perspectiveId = PerspectiveSupport.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId());
								toolbarProvider.setActive(perspectiveId, false);
							}
							if (notification.getNewValue() != null) {
								// activate new perspective - show its toolbar
								String perspectiveId = PerspectiveSupport.fromPerspectiveElementId(((MPerspective) notification.getNewValue()).getElementId());
								toolbarProvider.setActive(perspectiveId, true);
							}
						}
					}
				}
			}
		});
	}

	/**
	 * Checks if is our perspective element id.
	 *
	 * @param elementId
	 *            the element id
	 * @return true, if is perspective element id
	 */
	protected static boolean isPerspectiveElementId(String perspectiveId) {
		if (perspectiveId.startsWith(PerspectiveConstants.E4Constants.PERSPECTIVE_PREFIX)) {
			return true;
		}
		return false;
	}

	/**
	 * converts a name to a perspective element id.
	 *
	 * @param perspectiveId
	 *            the perspective id
	 * @return the string
	 */
	protected static String toPerspectiveElementId(String perspectiveId) {
		return PerspectiveConstants.E4Constants.PERSPECTIVE_PREFIX + perspectiveId;
	}

	/**
	 * converts from perspective element id to a name.
	 *
	 * @param elementId
	 *            the element id
	 * @return the string
	 */
	protected static String fromPerspectiveElementId(String elementId) {
		return elementId.substring(PerspectiveConstants.E4Constants.PERSPECTIVE_PREFIX.length());
	}

	/**
	 * Creates a new perspective.
	 *
	 * @param perspectiveModel
	 *            the perspective model
	 */
	public void openPerspectiveEvent(String perspectiveId) {
		PerspectiveFound perspectiveFound = findPerspective(perspectiveId);
		openPerspective(perspectiveFound, -1L);
	}

	/**
	 * Creates a new perspective suitable for the given task it was called from.
	 *
	 * @param perspectiveModel
	 *            the perspective model
	 * @param humanTask
	 * @param taskSummary
	 */
	private void openPerspective(PerspectiveFound perspectiveFound, Long taskId) {
		if (perspectiveFound.perspective != null) {
			prepareContext();
			// bring to top if already contained in model
			for (MPerspective perspective : currentPerspectiveStack.getChildren()) {
				if ((PerspectiveSupport.toPerspectiveElementId(perspectiveFound.perspective.getName())).equals(perspective.getElementId())) {
					modelService.bringToTop(perspective);
					return;
				}
			}

			log.debug("open perspective with " + perspectiveFound.perspective.getName());
			log.debug("add perspective");
			MPerspective perspective = createPerspective(perspectiveFound.perspective, perspectiveFound.perspective.getName());
			if (taskId != -1L) {
				registerContext(perspective.getTransientData(), perspectiveFound);
				// create the toolbar
				if (perspectiveFound.perspective.getToolbarTypeJvm() != null) {
					String toolBarId = perspectiveFound.perspective.getToolbarTypeJvm().getQualifiedName().replace("Action", "");
					toolbarProvider.addToolbar(perspectiveFound.perspective.getName(), findToolbar(toolBarId));
					// we cannot subscribe earlier as the toolbar id is unknown
					// before
					eventBroker.subscribe(EventBrokerMsg.ACTION_BUTTON_EXECUTE_PREFIX + toolbarProvider.getToolbarId(), dispatchAction);
				}
			}
			currentPerspectiveStack.getChildren().add(perspective);
			currentPerspectiveStack.setSelectedElement(perspective);
			modelService.bringToTop(perspective);

			perspectives.put(perspectiveFound.perspective.getName(), perspective);
			perspectiveTasks.put(taskId, perspectiveFound.perspective.getName());
			// get notified from bpm
			taskClient.subscribeProcessCompletedEventNotification(this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Release, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Complete, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Delegated, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Fail, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Skipped, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Release, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Stop, this);
			taskClient.subscribeTaskEventNotification(TaskEventType.Suspended, this);
		}
	}

	/**
	 * Close perspective.
	 *
	 * @param perspectiveId
	 *            of the perspective to close
	 * @param suspendTask
	 *            is true if task should be set to susupended
	 */
	private void closePerspective(String perspectiveId, boolean suspendTask) {
		if (perspectiveTasks.containsValue(perspectiveId)) {
			for (Long taskId : perspectiveTasks.keySet()) {
				if (perspectiveTasks.get(taskId).equals(perspectiveId)) {
					closePerspective(taskId);
					break;
				}
			}
		}
	}

	/**
	 * Close perspective an remove from PerspectiveStack.
	 *
	 * @param taskId
	 *            of the perspective to close
	 * @param suspendTask
	 *            is true if task should be set to susupended
	 */
	private void closePerspective(long taskId) {
		if (perspectiveTasks.containsKey(taskId)) {
			modelService.resetPerspectiveModel(perspectives.get(perspectiveTasks.get(taskId)), trimmedWindow);
			modelService.removePerspectiveModel(perspectives.get(perspectiveTasks.get(taskId)), trimmedWindow);
			toolbarProvider.removeToolbar(perspectiveTasks.get(taskId));
			perspectives.remove(taskId);
			perspectiveTasks.remove(taskId);
		}
	}

	/**
	 * Add the perspective identified by perspectiveId to PerspectiveStack.
	 *
	 * @param perspectiveModel
	 *            - the model everything is based on
	 * @param perspectiveId
	 *            - unique identifier for a perspective in the model
	 * @return the m perspective
	 */
	private MPerspective createPerspective(Perspective perspectiveModel, String perspectiveId) {
		MPerspective perspective = advancedFactory.createPerspective();

		perspective.getTags().add(TAG__REMOVE_ON_CLOSE);
		perspective.getTags().add(TAG__NOT_IN_OPEN_PERSPECTIVE_DIALOG);

		perspective.setElementId(PerspectiveSupport.toPerspectiveElementId(perspectiveId));
		perspective.setLabel(perspectiveModel.getName());
		perspective.setVisible(true);
		perspective.setToBeRendered(true);
		perspective.setIconURI(themeResourceService.getThemeURI(perspectiveModel.getIconURI(), ThemeResourceType.ICON));
		perspective.setAccessibilityPhrase(perspectiveModel.getAccessibilityPhrase());
		if (perspectiveModel.isDescription()) {
			perspective.setTooltip(perspectiveModel.getDescriptionValue().replace("\"", ""));
		}

		// iterate over all elements
		traverseModel(perspective, perspectiveModel);
		if (isUseDesigner(perspectiveModel, perspective) && !perspective.getChildren().isEmpty()) {
			MPartSashContainerElement firstElement = perspective.getChildren().get(0);
			if (firstElement instanceof MPartSashContainer) {
				// create placeholder for designer
				//
				MPlaceholder designerPH = MAdvancedFactory.INSTANCE.createPlaceholder();
				MUIElement area = modelService.find("org.eclipse.osbp.model.area.designer", currentPerspectiveStack);
				designerPH.setRef(area);
				designerPH.setContainerData("40");
				designerPH.setVisible(modelingContext.isDesignMode());
				designerPH.setToBeRendered(modelingContext.isDesignMode());
				designerPH.getTags().add("designer:autoVisible");

				((MPartSashContainer) firstElement).getChildren().add(designerPH);
			}
		}
		return perspective;
	}

	protected boolean isUseDesigner(Perspective perspectiveModel, MPerspective perspective) {
		return true;
	}

	/**
	 * Because the startup of the bundles doesn't allow injecting the taskProvider via the preferred way, get the taskProvider later on manually!
	 * 
	 * @return the task provider
	 */
	private AbstractBlipBPMFunctionProvider getTaskProvider() {
		if (taskProvider == null) {
			IEclipseContext appCtx = appModel.getContext();
			taskProvider = appCtx.get(AbstractBlipBPMFunctionProvider.class);
		}
		return taskProvider;
	}

	/**
	 * Register context.
	 *
	 * @param map
	 *            the map
	 * @param task
	 *            the task
	 */
	private void registerContext(Map<String, Object> map, PerspectiveFound perspectiveFound) {
		String workloadDtoFqn = null;
		IDto workloadDto = null;
		IBlipBPMStartInfo startInfo = null;
		IBlipBPMWorkloadModifiableItem task = null;
		Class<?> operativeDtoClass = null;
		String operativeDtoFqn = null;
		List<IDto> operativeDtos = null;

		if (taskClient != null) {
			workloadDtoFqn = taskClient.getWorkloadDtoFqn(perspectiveFound.taskSummary);
			workloadDto = taskClient.getWorkloadDto(perspectiveFound.taskSummary);
			if ((getTaskProvider() != null) && (perspectiveFound.blipTask != null)) {
				startInfo = getTaskProvider().getStartInfo(perspectiveFound.taskSummary);
			}
			if (startInfo != null) {
				task = startInfo.getWorkloadMofifiableBpmItemForBlipId(perspectiveFound.blipTask.getName());
			}
			if (task != null) {
				operativeDtos = task.getOperativeDtos(workloadDto);
				operativeDtoClass = task.getOperativeDtoClass();
				if (operativeDtoClass != null) {
					operativeDtoFqn = operativeDtoClass.getCanonicalName();
				} else {
					operativeDtoClass = null;
				}
			}
		}
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_START_INFO, startInfo);
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO_FQN, workloadDtoFqn);
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO, workloadDto);
		map.put(IBlipBPMConstants.VARIABLE_TASK_JBPM_SUMMARY, perspectiveFound.taskSummary);
		map.put(IBlipBPMConstants.VARIABLE_TASK_BLIP_ITEM, perspectiveFound.blipTask);
		map.put(IBlipBPMConstants.VARIABLE_TASK_BPM2_ITEM, perspectiveFound.bpmTask);
		map.put(IBlipBPMConstants.VARIABLE_TASK_START_INFO, task);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_CLASS, operativeDtoClass);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_FQN, operativeDtoFqn);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTOS, operativeDtos);
	}

	/**
	 * for every model element that can hold children, traverse recursively the model.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param modelElement
	 *            - the current element which is traversed
	 */
	private void traverseModel(MElementContainer<?> parent, EObject modelElement) {
		if (modelElement instanceof Perspective) {
			log.debug("traverse model perspective");
			Perspective perspectiveModel = (Perspective) modelElement;
			for (PerspectiveElement element : perspectiveModel.getElements()) {
				addElement(parent, element);
			}
		} else if (modelElement instanceof PerspectiveSashContainer) {
			log.debug("traverse model sashcontainer");
			PerspectiveSashContainer sashModel = (PerspectiveSashContainer) modelElement;
			for (PerspectiveElement element : sashModel.getElements()) {
				addElement(parent, element);
			}
		} else if (modelElement instanceof PerspectivePartStack) {
			log.debug("traverse model perspectivestack");
			PerspectivePartStack stackModel = (PerspectivePartStack) modelElement;
			for (PerspectiveElement element : stackModel.getElements()) {
				addElement(parent, element);
			}
		}
	}

	/**
	 * for PerspectiveSashContainer create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectiveSashContainer(MElementContainer<?> parent, EObject element) {
		PerspectiveSashContainer sashModel = (PerspectiveSashContainer) element;
		MPartSashContainer sashContainer = basicFactory.createPartSashContainer();
		sashContainer.setAccessibilityPhrase(sashModel.getAccessibilityPhrase());
		if (sashModel.getContainerData() != null) {
			sashContainer.setContainerData(sashModel.getContainerData().replace("\"", ""));
		} else {
			sashContainer.setContainerData("50");
		}

		sashContainer.setElementId(sashModel.getElementId());
		if ("HORIZONTAL".equals(sashModel.getOrientation().getName())) {
			sashContainer.setHorizontal(true);
		} else {
			sashContainer.setHorizontal(false);
		}
		sashContainer.setVisible(true);
		sashContainer.setParent((MElementContainer<MUIElement>) parent);
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(sashContainer);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(sashContainer);
		}
		// go deeper
		traverseModel(sashContainer, element);
		// set selected references
		for (MPartSashContainerElement child : sashContainer.getChildren()) {
			if (sashModel.getSelectedElement() != null && child.getElementId().equals(sashModel.getSelectedElement().getElementId())) {
				sashContainer.setSelectedElement(child);
				break;
			}
		}
	}

	/**
	 * for addElementPerspectivePartStack create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectivePartStack(MElementContainer<?> parent, EObject element) {
		PerspectivePartStack stackModel = (PerspectivePartStack) element;
		MPartStack stack = basicFactory.createPartStack();
		stack.setAccessibilityPhrase(stackModel.getAccessibilityPhrase());
		if (stackModel.getContainerData() != null) {
			stack.setContainerData(stackModel.getContainerData().replace("\"", ""));
		} else {
			stack.setContainerData("50");
		}
		stack.setElementId(stackModel.getElementId());
		stack.setVisible(true);
		stack.setParent((MElementContainer<MUIElement>) parent);
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(stack);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(stack);
		}
		// go deeper
		traverseModel(stack, element);
		// set selected references
		for (MStackElement child : stack.getChildren()) {
			if (stackModel.getSelectedElement() != null && child.getElementId().equals(stackModel.getSelectedElement().getElementId())) {
				stack.setSelectedElement(child);
				break;
			}
		}
	}

	/**
	 * for addElementPerspectivePart create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectivePart(MElementContainer<?> parent, EObject element) {
		PerspectivePart partModel = (PerspectivePart) element;
		MPart part = basicFactory.createPart();
		part.setAccessibilityPhrase(partModel.getAccessibilityPhrase());
		if (partModel.getContainerData() != null) {
			part.setContainerData(partModel.getContainerData().replace("\"", ""));
		} else {
			part.setContainerData("50");
		}

		part.setElementId(partModel.getElementId());
		part.setIconURI(partModel.getIconURI());
		if (partModel.isDescription()) {
			part.setTooltip(partModel.getDescriptionValue().replace("\"", ""));
		}
		part.setLabel(partModel.getElementId());
		part.setVisible(true);
		part.setCloseable(partModel.isIsClosable());

		part.getPersistedState().put(PerspectiveConstants.E4Constants.OSBP_NS_URI, getNsURI(partModel.getView()));
		part.getPersistedState().put(PerspectiveConstants.E4Constants.OSBP_FQN, getFQN(partModel.getView()));

		String flavor = getFlavor(partModel.getView());
		if (flavor != null) {
			part.getPersistedState().put(PerspectiveConstants.E4Constants.OSBP_FLAVOR, flavor);
		}

		part.setParent((MElementContainer<MUIElement>) parent);
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(part);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(part);
		} else if (parent instanceof MPartStack) {
			((MPartStack) parent).getChildren().add(part);
		}
		if (partModel.getView() != null) {
			part.setContributionURI(getContributionURI(partModel.getView()));
		}
	}

	/**
	 * for every model element create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	private void addElement(MElementContainer<?> parent, EObject element) {
		if (element instanceof PerspectiveSashContainer) {
			addElementPerspectiveSashContainer(parent, element);
		} else if (element instanceof PerspectivePartStack) {
			addElementPerspectivePartStack(parent, element);
		} else if (element instanceof PerspectivePart) {
			addElementPerspectivePart(parent, element);
		}
	}

	/**
	 * create the view connected to a part.
	 * 
	 * @param viewModel
	 *            - the model of the view
	 * @return null or the classURI
	 */
	private String getContributionURI(PerspectiveView viewModel) { // NOSONAR
		if (viewModel instanceof PerspectiveTable) {
			String className = ((PerspectiveTable) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "table");
		} else if (viewModel instanceof PerspectiveSelection) {
			String className = ((PerspectiveSelection) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "table");
		} else if (viewModel instanceof PerspectiveGrid) {
			String className = ((PerspectiveGrid) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "table");
		} else if (viewModel instanceof PerspectiveChart) {
			String className = ((PerspectiveChart) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "chart");
		} else if (viewModel instanceof PerspectiveReport) {
			String className = ((PerspectiveReport) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "report");
		} else if (viewModel instanceof PerspectiveOrganization) {
			if (optionalOrgURIProvider != null) {
				return optionalOrgURIProvider.getViewPartURI();
			} else {
				return null;
			}
		} else if (viewModel instanceof PerspectiveTopology) {
			String className = ((PerspectiveTopology) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "topology");
		} else if (viewModel instanceof PerspectiveDialog) {
			String className = ((PerspectiveDialog) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, "dialog");
		} else if (viewModel instanceof PerspectiveBPMN) {
			String className = BpmnView.class.getCanonicalName();
			return dslMetadataService.getClassURI(className, "bpmn");
		}
		return null;
	}

	/**
	 * Returns the FQN for the content of the view.
	 * 
	 * @param viewModel
	 *            - the model of the view
	 * @return null or the FQN
	 */
	private String getFQN(PerspectiveView viewModel) { // NOSONAR
		if (viewModel instanceof PerspectiveTable) {
			Table object = ((PerspectiveTable) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveSelection) {
			Table object = ((PerspectiveSelection) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveGrid) {
			Table object = ((PerspectiveGrid) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveChart) {
			Chart object = ((PerspectiveChart) viewModel).getRef();
			ChartPackage pkg = (ChartPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveReport) {
			Report object = ((PerspectiveReport) viewModel).getRef();
			ReportPackage pkg = (ReportPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveOrganization) {
			Organization object = ((PerspectiveOrganization) viewModel).getRef();
			OrganizationPackage pkg = (OrganizationPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveTopology) {
			Topology object = ((PerspectiveTopology) viewModel).getRef();
			TopologyPackage pkg = (TopologyPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveDialog) {
			Dialog object = ((PerspectiveDialog) viewModel).getRef();
			DialogPackage pkg = (DialogPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveBPMN) {
			// TODO Right now PerspectiveBPMN has no attributes
		}
		return null;
	}

	/**
	 * Return the NS-URI for the content of the view. Used as a content type marker.
	 *
	 * @param viewModel
	 *            the view model
	 * @return the ns uri
	 */
	private String getNsURI(PerspectiveView viewModel) { // NOSONAR
		if (viewModel instanceof PerspectiveTable) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveSelection) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveGrid) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveChart) {
			return ChartDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveReport) {
			return ReportDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveOrganization) {
			return OrganizationDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveTopology) {
			return TopologyDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveDialog) {
			return DialogDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveBPMN) {
			return Bpmn2Package.eNS_URI;
		}
		return null;
	}

	private String getFlavor(PerspectiveView viewModel) { // NOSONAR
		if (viewModel instanceof PerspectiveTable) {
			return "table";
		} else if (viewModel instanceof PerspectiveGrid) {
			return "grid";
		}
		return null;
	}

	/**
	 * To fqn.
	 *
	 * @param pkg
	 *            the pkg
	 * @param name
	 *            the name
	 * @return the string
	 */
	private String toFQN(String pkg, String name) {
		return pkg + "." + name;
	}

	/**
	 * Subscribe.
	 */
	protected void subscribe() {
		createEventHandlers();
		eventBroker.subscribe(EventBrokerMsg.OPEN_PERSPECTIVE, doOpenPerspective);
		eventBroker.subscribe(EventBrokerMsg.CLOSE_PERSPECTIVE, doClosePerspective);
		eventBroker.subscribe(AuthenticationConstants.Events.Authentication.PRE_LOGOUT, doLogout);
	}

	/**
	 * Unsubscribe.
	 */
	@PreDestroy
	protected void unsubscribe() {
		eventBroker.unsubscribe(dispatchAction);
		taskClient.unsubscribeTaskEventNotification(this);
	}

	/**
	 * Creates the event handlers.
	 */
	private void createEventHandlers() {
		dispatchAction = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				EventBrokerMsg msg = (EventBrokerMsg) event.getProperty(EventUtils.DATA);
				log.debug("dispatch action received in PerspectiveSupport for " + msg.getName());
				if ("delegate".equalsIgnoreCase(msg.getName())) {
					// UI.getCurrent().addWindow(selectUserWindow.init(getAllUsers(),
					// eventBroker, EventBrokerMsg.TASK_DELEGATED, msg));
				} else {
					taskClient.operations(msg.getLong(), user, null, Operation.valueOf(msg.getName()));
				}
			}
		};
		doOpenPerspective = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				PerspectiveFound perspectiveFound = null;
				EventBrokerMsg msg = (EventBrokerMsg) event.getProperty(EventUtils.DATA);
				if (msg.getName() != null) { // called by menu
					log.debug("open perspective with id " + msg.getName());
					perspectiveFound = findPerspective(msg.getName());
					if (perspectiveFound == null) {
						log.error("the perspective " + msg.getName() + " doesn't exist. Either blip model or perspective model must be modified.");
						return;
					}
				} else if (msg.getObject1() != null) { // called by bpm task
														// client
					log.debug("open perspective with taskId " + msg.getLong());
					perspectiveFound = findPerspective((TaskSummary) msg.getObject1());
					if (perspectiveFound != null) {
						eventBroker.post(EventBrokerMsg.BPMNCHART_EVENT, new EventBrokerMsg(perspectiveFound.taskSummary.getProcessId(), perspectiveFound.taskSummary.getName()));
						// notify orgachart with current user's position
						eventBroker.post(EventBrokerMsg.ORGCHART_SELECT, user.getPosition());
					}
				}
				if (perspectiveFound != null) {
					openPerspective(perspectiveFound, msg.getLong());
				}
			}
		};
		doClosePerspective = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				EventBrokerMsg msg = (EventBrokerMsg) event.getProperty(EventUtils.DATA);
				log.debug("close perspective " + msg.getName());
				// awaits a Long object as taskId
				closePerspective(msg.getLong());
			}
		};
		doLogout = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				log.debug("logout pending");
				suspendAllTasks();
			}
		};
	}

	/**
	 * Suspend all pending tasks while user pressed logout or closed browser.
	 * 
	 */
	private void suspendAllTasks() {
		for (Long taskId : perspectiveTasks.keySet()) {
			log.debug("suspend task " + taskId);
			taskClient.operations(taskId, user, null, Operation.Suspend);
		}
	}

	/**
	 * Tries to find the perspective model using the perspective builder service.
	 *
	 * @param perspectiveId
	 *            - the id of the perspective used in the model
	 * @return the perspective
	 */
	protected PerspectiveFound findPerspective(String perspectiveId) {
		log.debug("find perspective model by id");
		return new PerspectiveFound(null, (Perspective) dslMetadataService.getMetadata(perspectiveId, PerspectiveDslPackage.Literals.PERSPECTIVE), null, null);
	}

	private final class PerspectiveFound {
		public final TaskSummary taskSummary;
		public final Perspective perspective;
		public final BlipItem blipTask;
		public final Task bpmTask;

		protected PerspectiveFound(TaskSummary taskSummary, Perspective perspective, BlipItem blipTask, Task bpmTask) {
			this.taskSummary = taskSummary;
			this.perspective = perspective;
			this.blipTask = blipTask;
			this.bpmTask = bpmTask;
		}
	}

	/**
	 * Tries to find the perspective model using the perspective builder service.
	 *
	 * @param task
	 *            the task
	 * @return the perspective
	 */
	protected PerspectiveFound findPerspective(TaskSummary taskSummary) {
		log.debug("find perspective model by task");
		for (EObject eObj : dslMetadataService.getAll(PerspectiveDslPackage.Literals.PERSPECTIVE)) {
			// assumed that all packages of any dsl inherit LPackage
			if (eObj instanceof Perspective) {
				Perspective perspective = (Perspective) eObj;
				if ((perspective.getProcess() != null) && (perspective.getUserTask() != null)) {
					Process process = perspective.getProcess().getProcess();
					BlipUserTask blipTask = perspective.getUserTask();
					if ((process != null) && (process.getId().equals(taskSummary.getProcessId()))) {
						Task bpmTask = blipTask.getTask();
						if ((bpmTask != null) && taskSummary.getName().equals(bpmTask.getName())) {
							if (taskClient != null) {
								IDto wd = taskClient.getWorkloadDto(taskSummary);
								System.err.println();
							}
							return new PerspectiveFound(taskSummary, perspective, blipTask, bpmTask);
						}
					}
				}
			}
		}
		return null;
	}

	/**
	 * Tries to find the action toolbar model using the action builder service.
	 *
	 * @param toolbarId
	 *            the toolbar id
	 * @return the action toolbar
	 */
	protected ActionToolbar findToolbar(String toolbarId) {
		log.debug("find toolbar model");
		return (ActionToolbar) dslMetadataService.getMetadata(toolbarId, ActionDSLPackage.Literals.ACTION_TOOLBAR);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.bpm.api.IBPMTaskEventNotification#notifyTaskEvent(org .jbpm.task.event.entity.TaskEventType, org.jbpm.task.event.entity.TaskUserEvent)
	 */
	@Override
	public void notifyTaskEvent(TaskEventType type, TaskUserEvent event) {
		closePerspective(event.getTaskId());
	}

	@Override
	public void notifyProcessCompletedEvent(ProcessCompletedEvent event) {
		// NOP
	}

	// protected String getFQN(EObject obj, String name) {
	// while(obj != null && !(obj instanceof PerspectivePackage)) {
	// obj = obj.eContainer();
	// }
	// if(obj != null) {
	// String key = I18NKeyGenerator.key(name);
	// return ((PerspectivePackage) obj).getName()+"."+key;
	// }
	// return name;
	// }
}
