/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - 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                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective;

import java.util.HashMap;
import java.util.LinkedList;
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.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.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.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.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.model.application.ui.impl.UIElementImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
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.BPMOperation;
import org.eclipse.osbp.bpm.api.BPMTaskClientPerspectiveListener;
import org.eclipse.osbp.bpm.api.BPMTaskEventType;
import org.eclipse.osbp.bpm.api.BPMTaskSummary;
import org.eclipse.osbp.bpm.api.BPMTaskUserEvent;
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.IBlipBPMFunctionProvider;
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.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.organization.IOrganizationViewPartProvider;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
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.vaadin.bpmn.BpmnView;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.maintoolbar.IMainToolbarProvider;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.welcome.WelcomeView;
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.action.TaskActionEnum;
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.datainterchange.DataDSLPackage;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeGroup;
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.PerspectiveDataInterchange;
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.PerspectiveKanban;
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.PerspectiveSearch;
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.perspective.PerspectiveWelcome;
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.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

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

	/** 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
	@Optional
	private IBPMTaskClient taskClient;

	/** The task provider */
	@Inject
	@Optional
	private IBlipBPMFunctionProvider taskProvider;

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

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

	/** The optional org URI provider. */
	@Inject
	@Optional
	private IOrganizationViewPartProvider optionalOrgURIProvider;

	/** The event dispatcher. */
	@Inject
	private IEventDispatcher eventDispatcher;

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

	/** The trimmed window. */
	private MTrimmedWindow trimmedWindow = 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();
		modelService = eclipseContext.get(EModelService.class);
		eventDispatcher.addEventReceiver(this);
		subscribe();
	}

	/**
	 * Inits the perspective stack.
	 *
	 * @return the current perspective stack or null
	 */
	private MPerspectiveStack initPerspectiveStack() {
		log.debug("analyze app model");
		trimmedWindow = (MTrimmedWindow) appModel.getChildren().get(0);
		for (MWindowElement element : trimmedWindow.getChildren()) {
			if (element instanceof MPerspectiveStack) {
				return addToolbarAdapter((MPerspectiveStack) element);
			}
		}
		return null;
	}

	private MPerspectiveStack addToolbarAdapter(MPerspectiveStack stack) {
		// handle toolbar
		((EObject) stack).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
							&& PerspectiveProvider.isPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId())) {
						closePerspective(PerspectiveProvider.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId()));
					}
					// perspective changed
					if (notification.getNewValue() == null && notification.getOldValue() != null) {
						// deactivate old perspective - hide its toolBar
						String perspectiveId = PerspectiveProvider.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId());
						toolbarProvider.setActive(perspectiveId, false);
					}
					if (notification.getNewValue() != null && notification.getOldValue() == null) {
						// activate new perspective - show its toolbar
						String perspectiveId = PerspectiveProvider.fromPerspectiveElementId(((MPerspective) notification.getNewValue()).getElementId());
						toolbarProvider.setActive(perspectiveId, true);
					}
				}
			}
		});
		return stack;
	}

	/**
	 * 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) {
		return perspectiveId.startsWith(IPerspectiveProvider.E4Constants.PERSPECTIVE_PREFIX);
	}

	/**
	 * converts a name to a perspective element id.
	 *
	 * @param perspectiveId
	 *            the perspective id
	 * @return the string
	 */
	protected static String toPerspectiveElementId(String perspectiveId) {
		return IPerspectiveProvider.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(IPerspectiveProvider.E4Constants.PERSPECTIVE_PREFIX.length());
	}

	/**
	 * 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(MPerspectiveStack stack, Perspective perspectiveModel, String perspectiveId) {
		MPerspective perspective = AdvancedFactoryImpl.eINSTANCE.createPerspective();

		perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_REMOVE_ON_CLOSE);
		perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_NOT_IN_OPEN_PERSPECTIVE_DIALOG);

		perspective.setElementId(PerspectiveProvider.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 (!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", stack);
				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;
	}

	/**
	 * 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 (perspectiveFound.blipTask != null) {
				startInfo = taskProvider.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 = BasicFactoryImpl.eINSTANCE.createPartSashContainer();
		sashContainer.setAccessibilityPhrase(sashModel.getAccessibilityPhrase());
		addAdapter(sashContainer);
		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;
			}
		}

		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in 'getElementContainerData' below 
		// requires the element id and the parent information set to the part above.
		String elementContainerData = getElementContainerData(sashContainer);
		if (elementContainerData != null) {
			sashContainer.setContainerData(elementContainerData);
		} else {
			sashContainer.setContainerData(sashModel.getContainerData()!=null?sashModel.getContainerData().replace("\"", ""):"50");
		}

	}

	/**
	 * 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 = BasicFactoryImpl.eINSTANCE.createPartStack();
		stack.setAccessibilityPhrase(stackModel.getAccessibilityPhrase());
		addAdapter(stack);
		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;
			}
		}
		
		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in 'getElementContainerData' below 
		// requires the element id and the parent information set to the part above.
		String elementContainerData = getElementContainerData(stack);
		if (elementContainerData != null) {
			stack.setContainerData(elementContainerData);
		} else {
			stack.setContainerData(stackModel.getContainerData()!=null?stackModel.getContainerData().replace("\"", ""):"50");
		}

	}

	private String getElementContainerData(MUIElement element) {
		return (String)user.getProperty(getFQNKey(element));
	}

	/**
	 * 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 = BasicFactoryImpl.eINSTANCE.createPart();
		part.setAccessibilityPhrase(partModel.getAccessibilityPhrase());
		addAdapter(part);
		part.setElementId(partModel.getElementId());

		part.setIconURI(partModel.getIconURI());
		part.setLabel(partModel.getElementId());
		part.setVisible(true);
		part.setCloseable(partModel.isIsClosable());

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

		String flavor = getFlavor(partModel.getView());
		if (flavor != null) {
			part.getPersistedState().put(IPerspectiveProvider.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(part, partModel));
		}
		
		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in 'getElementContainerData' below 
		// requires the element id and the parent information set to the part above.
		String elementContainerData = getElementContainerData(part);
		if (elementContainerData != null) {
			part.setContainerData(elementContainerData);
		} else {
			part.setContainerData(partModel.getContainerData()!=null?partModel.getContainerData().replace("\"", ""):"50");
		}

	}

	/**
	 * 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(MPart part, PerspectivePart partModel) { // NOSONAR
		PerspectiveView viewModel = partModel.getView();
		if (viewModel instanceof PerspectiveTable) {
			String className = ((PerspectiveTable) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveSelection) {
			String className = ((PerspectiveSelection) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveGrid) {
			String className = ((PerspectiveGrid) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveChart) {
			String className = ((PerspectiveChart) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.CHART);
		} else if (viewModel instanceof PerspectiveReport) {
			String className = ((PerspectiveReport) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.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, IPerspectiveProvider.PerspectiveViewType.TOPOLOGY);
		} else if (viewModel instanceof PerspectiveDialog) {
			String className = ((PerspectiveDialog) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.DIALOG);
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			String className = ((PerspectiveDataInterchange) viewModel).getRefTypeJvm().getQualifiedName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.DATAINTERCHANGE);
		} else if (viewModel instanceof PerspectiveBPMN) {
			String className = BpmnView.class.getCanonicalName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.BPMN);
		} else if (viewModel instanceof PerspectiveWelcome) {
			String className = WelcomeView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(WelcomeView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME+"://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveSearch) {
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_DTO_CLASS, ((PerspectiveSearch) viewModel).getDtoRef());
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_DEPTH, ((PerspectiveSearch) viewModel).getDepth());
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_COLUMNS, Math.max(1, ((PerspectiveSearch) viewModel).getFilterCols()));
			String className = SearchView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(SearchView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME+"://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveKanban) {
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.DTO, ((PerspectiveKanban) viewModel).getDtoRef());
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.DIALOG, ((PerspectiveKanban) viewModel).getDialogRef());
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.CARD, ((PerspectiveKanban) viewModel).getCardRef());
			String className = KanbanView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(KanbanView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME+"://" + bundle.getSymbolicName() + "/" + className;
		}
		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 PerspectiveDataInterchange) {
			DataInterchangeGroup group = ((PerspectiveDataInterchange) viewModel).getRef();
			return group == null ? "" : group.getName();
		}
		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;
		} else if (viewModel instanceof PerspectiveKanban) {
			return ExtensionModelPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			return DataDSLPackage.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() {
		if(taskClient != null) {
			taskClient.registerPerspectiveListener(this);
		}
		createEventHandlers();
		eventBroker.subscribe(AuthenticationConstants.Events.Authentication.PRE_LOGOUT, doLogout);
	}

	/**
	 * Unsubscribe.
	 */
	@PreDestroy
	protected void unsubscribe() {
		taskClient.unsubscribeTaskEventNotification(this);
		if(taskClient != null) {
			taskClient.unregisterPerspectiveListener(this);
		}
	}

	/**
	 * Creates the event handlers.
	 */
	private void createEventHandlers() {
		doLogout = (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, BPMOperation.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 BPMTaskSummary taskSummary;
		public final Perspective perspective;
		public final BlipItem blipTask;
		public final Task bpmTask;

		protected PerspectiveFound(BPMTaskSummary 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(BPMTaskSummary taskSummary) {
		log.debug("find perspective model by task");
		for (EObject eObj : dslMetadataService.getAll(PerspectiveDslPackage.Literals.PERSPECTIVE)) {
			if ((((Perspective) eObj).getProcess() != null) && (((Perspective) eObj).getUserTask() != null)) {
				Process process = ((Perspective) eObj).getProcess().getProcess();
				BlipUserTask blipTask = ((Perspective) eObj).getUserTask();
				if ((process != null) && (process.getId().equals(taskSummary.getProcessId()))) {
					Task bpmTask = blipTask.getTask();
					if ((bpmTask != null) && bpmTask.getName().equals(taskSummary.getName())) {
						return new PerspectiveFound(taskSummary, (Perspective)eObj, 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(BPMTaskEventType type, BPMTaskUserEvent event) {
		closePerspective(event.getTaskId());
	}

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

	@Override
	public void receiveEvent(EventDispatcherEvent event) {
		if(event.getCommand() == EventDispatcherCommand.ACTION &&
			event.getData().containsKey(EventDispatcherDataTag.BUTTON_ID) && 
			event.getData().get(EventDispatcherDataTag.BUTTON_ID) instanceof TaskActionEnum &&
			event.getData().containsKey(EventDispatcherDataTag.TASK_ID) &&
			event.getData().get(EventDispatcherDataTag.TASK_ID) instanceof Long) {
			Object buttonId = event.getData().get(EventDispatcherDataTag.BUTTON_ID) ;
			TaskActionEnum enumId = (TaskActionEnum) buttonId;
			Long taskId = (Long)event.getData().get(EventDispatcherDataTag.TASK_ID);
			if(enumId == TaskActionEnum.TASK_ACTION_DELEGATE) {
				log.debug("dispatch action received in PerspectiveSupport for " + TaskActionEnum.TASK_ACTION_DELEGATE.getLiteral());
			} else {
				taskClient.operations(taskId, user, null, BPMOperation.valueOf(enumId.getLiteral()));
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider#openPerspective(java.lang.String, java.lang.String, java.lang.Class)
	 */
	@Override
	public void openPerspective(String elementId, String labelName, Class<?> clazz) {
		MPerspectiveStack stack = initPerspectiveStack();
		if(stack != null) {
			// bring to top if already contained in model
			for (MPerspective perspective : stack.getChildren()) {
				if ((PerspectiveProvider.toPerspectiveElementId(elementId)).equals(perspective.getElementId())) {
					modelService.bringToTop(perspective);
					return;
				}
			}
			MPerspective perspective = AdvancedFactoryImpl.eINSTANCE.createPerspective();
			
			perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_REMOVE_ON_CLOSE);
			perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_NOT_IN_OPEN_PERSPECTIVE_DIALOG);
			
			perspective.setElementId(PerspectiveProvider.toPerspectiveElementId(elementId));
			perspective.setLabel(labelName);
			perspective.setVisible(true);
			perspective.setToBeRendered(true);
			perspective.setIconURI(themeResourceService.getThemeURI("osbee", ThemeResourceType.ICON));
			MPart part = BasicFactoryImpl.eINSTANCE.createPart();
			part.setVisible(true);
			part.setCloseable(false);
			perspective.getChildren().add(part);
			String className = clazz.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(clazz);
			String contributionURI = E4Constants.BUNDLE_PROTOCOL_SCHEME+"://" + bundle.getSymbolicName() + "/" + className;
			part.setContributionURI(contributionURI);
			stack.getChildren().add(perspective);
			stack.setSelectedElement(perspective);
			modelService.bringToTop(perspective);
		}
	}

	@Override
	public void openPerspective(BPMTaskSummary taskSummary) {
		// register tasksummary in context for action's TaskHelper
		eclipseContext.set(BPMTaskSummary.class, taskSummary);
		PerspectiveFound perspectiveFound = null;
		log.debug("open perspective with taskId {}", taskSummary.getId());
		perspectiveFound = findPerspective(taskSummary);
		if (perspectiveFound != null) {
			// notify orgachart with current user's position
			eventBroker.post(EventBrokerMsg.ORGCHART_SELECT, user.getPosition());
			openPerspective(perspectiveFound, taskSummary.getId());
		} else {
			log.error("perspective for taskid {} not found", taskSummary.getId());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider#openPerspectiveEvent(java.lang.String)
	 */
	@Override
	public void openPerspective(String perspectiveId) { 
		PerspectiveFound perspectiveFound = findPerspective(perspectiveId);
		if(perspectiveFound != null) {
			openPerspective(perspectiveFound, -1L);
		} else {
			log.error("perspective id {} not found", perspectiveId);
		}
	}

	/**
	 * 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) {
		MPerspectiveStack stack = initPerspectiveStack();
		if (stack != null && perspectiveFound.perspective != null) {
			// bring to top if already contained in model
			// lo wants multiple manually opened perspectives of same type by 02/28/2018
			if(taskId > 0L) {
				for (MPerspective perspective : stack.getChildren()) {
					if ((PerspectiveProvider.toPerspectiveElementId(perspectiveFound.perspective.getName())).equals(perspective.getElementId())) {
						modelService.bringToTop(perspective);
						return;
					}
				}
			}

			log.debug("open perspective {}", perspectiveFound.perspective.getName());
			log.debug("add perspective");
			MPerspective perspective = createPerspective(stack, 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("Toolbar", "");
					toolbarProvider.addToolbar(perspectiveFound.perspective.getName(), findToolbar(toolBarId));
				}
			}
			stack.getChildren().add(perspective);
			stack.setSelectedElement(perspective);
			modelService.bringToTop(perspective);

			perspectives.put(perspectiveFound.perspective.getName(), perspective);
			perspectiveTasks.put(taskId, perspectiveFound.perspective.getName());
			// get notified from bpm
			if(taskClient != null) {
				taskClient.subscribeProcessCompletedEventNotification(this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Release, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Complete, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Delegated, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Fail, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Skipped, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Release, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Stop, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.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) {
		if (perspectiveTasks.containsValue(perspectiveId)) {
			for (Map.Entry<Long, String> perspective : perspectiveTasks.entrySet()) {
				if (perspective.getValue().equals(perspectiveId)) {
					closePerspective(perspective.getKey());
					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);
		}
	}

	@Override
	public void closePerspective(BPMTaskSummary taskSummary) {
		log.debug("close perspective {}", taskSummary.getId());
		// awaits a Long object as taskId
		closePerspective(taskSummary.getId());
	}
	
	private void addAdapter(MUIElement element) {
	    ((EObject)element).eAdapters().add(new AdapterImpl() {
	    	public void notifyChanged(Notification notification) {
	    		if (notification.getEventType()==Notification.SET && 
	    				notification.getFeatureID(UIElementImpl.class) == UiPackageImpl.UI_ELEMENT__CONTAINER_DATA && element.getElementId() != null)
	    		{
	    			user.addToProperties(getFQNKey(element), element.getContainerData());
	    		}
	    	}
	    });
	}
	
	private String getFQNKey(MUIElement element){
		MUIElement muiElement = element;
		List<String> elementIds = new LinkedList<>();
		StringBuffer strBuffer = new StringBuffer();
		while (muiElement!= null){
			if (muiElement.getElementId() != null) {
				elementIds.add(muiElement.getElementId());
				if (muiElement.getElementId().startsWith(E4Constants.PERSPECTIVE_PREFIX)) {
					break;
				}
				muiElement = muiElement.getParent();
			}
		}
		for (int i = elementIds.size(); i > 0; i--) {
			if (strBuffer.length()!=0){
				strBuffer.append(".");
			}
			strBuffer.append(elementIds.get(i-1));
		}
		return strBuffer.toString();
	}
}
