/**
 *                                                                            
 *  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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */

package org.eclipse.osbp.xtext.action.jvmmodel

import java.util.List
import java.util.Map
import javax.inject.Inject
import org.eclipse.e4.core.contexts.Active
import org.eclipse.e4.core.contexts.IEclipseContext
import org.eclipse.e4.core.di.annotations.CanExecute
import org.eclipse.e4.core.di.annotations.Execute
import org.eclipse.e4.core.di.annotations.Optional
import org.eclipse.e4.ui.model.application.MApplication
import org.eclipse.e4.ui.model.application.ui.MUIElement
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective
import org.eclipse.e4.ui.model.application.ui.basic.MPart
import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar
import org.eclipse.e4.ui.workbench.IPresentationEngine
import org.eclipse.emf.common.util.Enumerator
import org.eclipse.osbp.core.api.persistence.IPersistenceService
import org.eclipse.osbp.datainterchange.api.IDataInterchange
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature
import org.eclipse.osbp.ecview.core.common.context.IViewContext
import org.eclipse.osbp.runtime.common.event.IEventDispatcher
import org.eclipse.osbp.ui.api.contextfunction.ICommandsProvider
import org.eclipse.osbp.ui.api.customfields.IBlobService
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService
import org.eclipse.osbp.ui.api.themes.IThemeResourceService
import org.eclipse.osbp.ui.api.user.IUser
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService
import org.eclipse.osbp.utils.annotation.CommonUtils
import org.eclipse.osbp.vaaclipse.api.VaadinExecutorService
import org.eclipse.osbp.xtext.action.ActionButton
import org.eclipse.osbp.xtext.action.ActionChart
import org.eclipse.osbp.xtext.action.ActionCommand
import org.eclipse.osbp.xtext.action.ActionDatainterchange
import org.eclipse.osbp.xtext.action.ActionDialog
import org.eclipse.osbp.xtext.action.ActionFunction
import org.eclipse.osbp.xtext.action.ActionPackage
import org.eclipse.osbp.xtext.action.ActionReport
import org.eclipse.osbp.xtext.action.ActionSelectWorkload
import org.eclipse.osbp.xtext.action.ActionSpacer
import org.eclipse.osbp.xtext.action.ActionState
import org.eclipse.osbp.xtext.action.ActionTable
import org.eclipse.osbp.xtext.action.ActionTask
import org.eclipse.osbp.xtext.action.ActionToolbar
import org.eclipse.osbp.xtext.action.ActionToolbarItem
import org.eclipse.osbp.xtext.action.ActionUI
import org.eclipse.osbp.xtext.action.ActionWorkflow
import org.eclipse.osbp.xtext.action.DialogActionEnum
import org.eclipse.osbp.xtext.action.UIActionEnum
import org.eclipse.osbp.xtext.action.common.IToolbarAction
import org.eclipse.osbp.xtext.datainterchange.AttributeFilter
import org.eclipse.osbp.xtext.datainterchange.DataInterchange
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFilter
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeGroup
import org.eclipse.osbp.xtext.datainterchange.ReferenceFilter
import org.eclipse.osbp.xtext.datainterchange.ReferenceFilterWithAttr
import org.eclipse.osbp.xtext.datainterchange.ReferenceFilterWithOutAttr
import org.eclipse.osbp.xtext.datainterchange.jvmmodel.DataDSLJvmModelInferrer
import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryPackage
import org.eclipse.osbp.xtext.messagedsl.MessagePackage
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.JvmVisibility
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.osgi.service.component.annotations.Component
import org.slf4j.Logger

/**
 * <p>Infers a JVM model from the source model.</p> 
 * 
 * <p>The JVM model should contain all elements that would appear in the Java code 
 * which is generated from the source model. Other models link against the JVM model rather than the source model.</p>     
 */
class ActionDSLJvmModelInferrer extends AbstractModelInferrer {

	@Inject extension JvmTypesBuilder
	@Inject extension IQualifiedNameProvider
	@Inject extension DataDSLJvmModelInferrer data
	@Inject extension CommonUtils

	var String contextClassName = ""
	var String clsName = ""

	def dispatch void infer(ActionPackage pkg, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
		for (toolbar : pkg.toolbars) {
			var toolbarClass = toolbar.toClass(toolbar.className)
			acceptor.accept(toolbarClass, [
				superTypes += _typeReferenceBuilder.typeRef(IToolbarAction)
				it.toToolbarConstructor(toolbar)
				it.toToolbarFields(toolbar)
				it.toToolbarOperations(toolbar)
				it.fileHeader = pkg.documentation
			])

		}
		// the command handlers
		for (command : pkg.commands) {
			var handlerClass = command.toClass(command.className)
			acceptor.accept(handlerClass, [
				it.toHandlerFields(command)
				it.toHandlerOperations(command)
				it.fileHeader = pkg.documentation
			])
		}
		// the commands class
		if (! pkg.withouCommandProvider) {
			clsName = pkg.name.toString.concat(".").concat("CommandsProvider")
			val cls = pkg.toClass(clsName)
			cls.superTypes.add(_typeReferenceBuilder.typeRef(ICommandsProvider))
			acceptor.accept(cls, [
				var annotationRef = _annotationTypesBuilder.annotationRef(typeof(Component))
				annotationRef.addAnnAttr(pkg, "service",
					_typeReferenceBuilder.typeRef(ICommandsProvider) as JvmTypeReference)
				annotations += annotationRef
				it.toCommandsConstructor(pkg)
				it.toCommandsOperations(pkg)
			])
		}
	}

	def void toCommandsOperations(JvmGenericType type, ActionPackage pkg) {
		// init
		type.members += pkg.toMethod("init", _typeReferenceBuilder.typeRef(Void::TYPE), [
			annotations += _annotationTypesBuilder.annotationRef(Override)
			parameters += pkg.toParameter("application", _typeReferenceBuilder.typeRef(MApplication))
			body = [append('''«pkg.init»''')]
		])
	}

	def init(ActionPackage pkg) {
		var body = '''
			if(!application.getBindingTables().isEmpty()) {
				MBindingTable bindingTable = application.getBindingTables().get(0);
				MKeyBinding keyBinding;
				MCommand command;
				MHandler commandHandler;
		'''
		for (command : pkg.commands) {
			body = '''
				«body»
					command = CommandsFactoryImpl.eINSTANCE.createCommand();
					command.setElementId("«pkg.fullyQualifiedName».«command.name»");
					command.setCommandName("«command.name»");
					«IF command.hasDescription»command.setDescription("«command.description»");«ENDIF»
					application.getCommands().add(command);
					commandHandler = CommandsFactoryImpl.eINSTANCE.createHandler();
					commandHandler.setElementId("«pkg.fullyQualifiedName».«command.name»Handler");
					commandHandler.setCommand(command);
					commandHandler.setContributionURI("bundleclass://"+FrameworkUtil.getBundle(«command.className».class).getSymbolicName()+"/«command.className»");
					application.getHandlers().add(commandHandler);
					«IF command.hasKeyBinding»
						keyBinding = CommandsFactoryImpl.eINSTANCE.createKeyBinding();
						keyBinding.setElementId("«pkg.fullyQualifiedName».«command.name»Keybinding");
						keyBinding.setKeySequence("«command.keyBinding.replace(" ", "+")»");
						keyBinding.setCommand(command);
					bindingTable.getBindings().add(keyBinding);«ENDIF»
			'''
		}
		body = '''
			«body»
			}
		'''
		return body
	}

	def void toCommandsConstructor(JvmGenericType type, ActionPackage pkg) {
		type.members += pkg.toConstructor([
			body = [append('''''')]
		])
	}

	/**
	 * <p>build the constructors.</p> 
	 * 
	 */
	def void toToolbarConstructor(JvmGenericType type, ActionToolbar toolbar) {
		type.members += toolbar.toConstructor(
		[
			body = [append('''super();''')]
		])
	}

	def String className(ActionToolbar toolbar) {
		var pkg = toolbar.eContainer as ActionPackage
		return pkg.name.toString.concat(".").concat(toolbar.name.toFirstUpper).concat("Toolbar")
	}

	def String className(ActionCommand actionCommand) {
		var pkg = actionCommand.eContainer as ActionPackage
		return pkg.name.toString.concat(".").concat(actionCommand.name.toFirstUpper).concat("Action")
	}

	def void toToolbarOperations(JvmGenericType type, ActionToolbar toolbar) {
		// create a toolbar
		type.members += toolbar.toMethod("createToolbar", _typeReferenceBuilder.typeRef(Void::TYPE), [
			parameters += toolbar.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
			parameters += toolbar.toParameter("renderingEngine", _typeReferenceBuilder.typeRef(IPresentationEngine))
			parameters +=
				toolbar.toParameter("themeResourceService", _typeReferenceBuilder.typeRef(IThemeResourceService))
			parameters += toolbar.toParameter("uuid", _typeReferenceBuilder.typeRef(String))
			visibility = JvmVisibility.PUBLIC
			annotations += _annotationTypesBuilder.annotationRef(Override)
			body = [append('''«toolbar.createToolbar»''')]
		])
		// get toolbar
		type.members += toolbar.toMethod("getToolBar", _typeReferenceBuilder.typeRef(MToolBar), [
			annotations += _annotationTypesBuilder.annotationRef(Override)
			body = [append('''return toolbar;''')]
		])
		// get stateLabelUUID
		type.members += toolbar.toMethod("getStateLabelUUID", _typeReferenceBuilder.typeRef(String), [
			annotations += _annotationTypesBuilder.annotationRef(Override)
			body = [append('''return stateLabelUUID;''')]
		])
		// set command
		type.members += toolbar.toMethod("setCommand", _typeReferenceBuilder.typeRef(Void::TYPE), [
			parameters += toolbar.toParameter("commandName", _typeReferenceBuilder.typeRef(String))
			parameters += toolbar.toParameter("toolItem", _typeReferenceBuilder.typeRef(MHandledToolItem))
			parameters += toolbar.toParameter("application", _typeReferenceBuilder.typeRef(MApplication))
			visibility = JvmVisibility.PRIVATE
			body = [
				append(
			'''
					for(MCommand command:application.getCommands()) {
						if(command.getCommandName().equals(commandName)) {
							toolItem.setCommand(command);
							break;
						}
					}
				''')
			]
		])
	}

	def String createToolbar(ActionToolbar toolbar) {
		var body = ""
		body = '''
			«body»
			this.uuid = uuid;
			MenuFactoryImpl factory = MenuFactoryImpl.eINSTANCE;
			MHandledToolItem toolItem = null;
			MToolBarSeparator separator = null;
			
			MApplication application = (MApplication)eclipseContext.get(MApplication.class);
			MPart part = (MPart)eclipseContext.get(MPart.class);
			if(part != null) {
				toolbar = part.getToolbar();
				if (toolbar == null) {
					toolbar = factory.createToolBar();
					toolbar.setElementId(uuid);
					part.getContext().set("«IToolbarAction.TOOLBAR_UUID»", toolbar.getElementId());
					toolbar.setToBeRendered(true);
					part.setToolbar(toolbar);
					
					Panel panel = (Panel) part.getWidget();
					if (panel != null) {		// it is already visible in terms of vaadin
						//create toolbar area
						VerticalLayout rootContainer = (VerticalLayout)panel.getContent();
						CssLayout toolbarArea = new CssLayout();
						toolbarArea.setStyleName(EnumCssClass.MPARTTOOLBARAREA.toString());
						toolbarArea.setSizeUndefined();
						toolbarArea.setWidth("100%");
						rootContainer.addComponentAsFirst(toolbarArea);
						
						//create toolbar
						Component toolbarWidget = (Component) renderingEngine.createGui(toolbar);
						((AbstractLayout)toolbarWidget).setSizeUndefined();
						toolbarWidget.setStyleName(EnumCssClass.MPARTTOOLBAR.toString());
						toolbarArea.addComponent(toolbarWidget);
					}
				}
				else {
					toolbar.getChildren().removeIf(c -> c.isToBeRendered());
				}
		'''
		for (action : toolbar.actions) {
			body = '''«body»«toolbar.createToolItem(action)»'''
		}
		body = '''
		«body»
		}'''
		return body
	}

	def createToolItem(ActionToolbar toolbar, ActionToolbarItem action) {
		if (action instanceof ActionButton) {
			return '''
				toolItem = factory.createHandledToolItem();
				toolItem.setElementId(UUID.randomUUID().toString());
				toolItem.setType(ItemType.PUSH);
				toolItem.setTooltip("«IF action.command.actionType instanceof ActionDatainterchange && (action.command.actionType as ActionDatainterchange).dataRef.description»«(action.command.actionType as ActionDatainterchange).dataRef.descriptionValue»«ELSE»«action.name»«ENDIF»«IF action.command.hasKeyBinding».keybinding.«action.command.keyBinding»«ENDIF»");
				toolItem.setIconURI(themeResourceService.getThemeURI("«action.iconURI»", ThemeResourceType.ICON));
				toolItem.setEnabled(true);
				toolItem.setToBeRendered(true);
				toolItem.setVisible(true);
				setCommand("«action.command.name»", toolItem, application);
				toolbar.getChildren().add(toolItem);
				«IF action.command.actionType instanceof ActionReport»
					toolItem.getTags().add("«(action.command.actionType as ActionReport).action.literal»");
				«ENDIF»
				«IF action.command.actionType instanceof ActionTable»
					toolItem.getTags().add("«(action.command.actionType as ActionTable).action.literal»");
				«ENDIF»
				«IF action.command.actionType instanceof ActionChart»
					toolItem.getTags().add("«(action.command.actionType as ActionChart).action.literal»");
				«ENDIF»
			'''
		} else if (action instanceof ActionSpacer) {
			return '''
				separator = factory.createToolBarSeparator();
				toolbar.getChildren().add(separator);
				'''
		} else if (action instanceof ActionState) {
			return '''
				MToolControl state = factory.createToolControl();
				state.setContributionURI(E4Helper.getDialogStateHandlerURI());
				stateLabelUUID = UUID.randomUUID().toString();
				state.setElementId(stateLabelUUID);
				state.setToBeRendered(true);
				state.setVisible(true);
				toolbar.getChildren().add(state);
				'''
		}
	}

	def void toToolbarFields(JvmGenericType type, ActionToolbar toolbar) {
		var JvmField field = null
		// create logger
		field = toolbar.toField("log", _typeReferenceBuilder.typeRef(Logger)) [
			setInitializer([append('''org.slf4j.LoggerFactory.getLogger("toolbar")''')])
		]
		field.static = true
		field.visibility = JvmVisibility::PRIVATE
		type.members += field
		// create UUID
		field = toolbar.toField("uuid", _typeReferenceBuilder.typeRef(String))
		field.visibility = JvmVisibility::PRIVATE
		type.members += field
		field = toolbar.toField("toolbar", _typeReferenceBuilder.typeRef(MToolBar))
		type.members += field
		field = toolbar.toField("stateLabelUUID", _typeReferenceBuilder.typeRef(String))
		field.visibility = JvmVisibility::PRIVATE
		type.members += field
	}

	// handler stuff	
	def void toHandlerFields(JvmGenericType type, ActionCommand action) {
		var JvmField field = null
		// create logger
		field = action.toField("log", _typeReferenceBuilder.typeRef(Logger)) [
			setInitializer([append('''org.slf4j.LoggerFactory.getLogger("action")''')])
		]
		field.static = true
		field.visibility = JvmVisibility::PRIVATE
		type.members += field
		
		var JvmField field2 = null
		// create logger
		field2 = action.toField("isGranted", _typeReferenceBuilder.typeRef(Map,_typeReferenceBuilder.typeRef(String),_typeReferenceBuilder.typeRef(Boolean))) [
			setInitializer([append('''new HashMap()''')])
		]
		field2.static = true
		field2.visibility = JvmVisibility::PRIVATE
		type.members += field2
		// create a field
		type.members += action.toField("activePart", _typeReferenceBuilder.typeRef(MUIElement))
		// create a getter
		type.members += action.toMethod("getActivePart", _typeReferenceBuilder.typeRef(MUIElement), [
			body = [append('''return activePart;''')]
		])

	}

	def activatePart() '''
		if (part == null || part.equals(activePart)) {
			return;
		}
		if(activePart != null && activePart.getWidget() instanceof Panel) {
			((Panel)activePart.getWidget()).removeStyleName(EnumCssClass.HAS_FOCUS.styleName());
		}
		if(part != null && part.getWidget() instanceof Panel) {
			((Panel)part.getWidget()).addStyleName(EnumCssClass.HAS_FOCUS.styleName());
		}
		activePart = part;
		IE4Dialog dialog = part.getContext().get(IE4Dialog.class);
		if (dialog != null) {
			ContextInjectionFactory.invoke(dialog, Focus.class, part.getContext());
		}
		IE4Table table = part.getContext().get(IE4Table.class);
		if (table != null) {
			ContextInjectionFactory.invoke(table, Focus.class, part.getContext());
		}
		IE4Focusable focusable = part.getContext().get(IE4Focusable.class);
		if (focusable != null) {
			ContextInjectionFactory.invoke(focusable, Focus.class, part.getContext());
		}
	'''

	/**
	 * <p>build the methods to be used as toolbar handlers by an e4 application.</p> 
	 * 
	 */
	def void toHandlerOperations(JvmDeclaredType type, ActionCommand action) {
		if (action.actionType instanceof ActionUI &&
			((action.actionType as ActionUI).action == UIActionEnum.NEXT_PART ||
				(action.actionType as ActionUI).action == UIActionEnum.PREVIOUS_PART)) {
			// create activePart
			type.members += action.toMethod("activePart", _typeReferenceBuilder.typeRef(Void::TYPE), [
				annotations += _annotationTypesBuilder.annotationRef(Inject)
				var para = action.toParameter("part", _typeReferenceBuilder.typeRef(MPart))
				para.annotations += _annotationTypesBuilder.annotationRef(typeof(Active))
				para.annotations += _annotationTypesBuilder.annotationRef(typeof(Optional))
				parameters += para
				body = [append('''«activatePart»''')]
			])
		}
		if (action.actionType instanceof ActionUI &&
			((action.actionType as ActionUI).action == UIActionEnum.NEXT_PERSPECTIVE ||
			(action.actionType as ActionUI).action == UIActionEnum.PREVIOUS_PERSPECTIVE)) {
			// create activePerspective
			type.members += action.toMethod("activePerspective", _typeReferenceBuilder.typeRef(Void::TYPE), [
				annotations += _annotationTypesBuilder.annotationRef(Inject)
				var para = action.toParameter("part", _typeReferenceBuilder.typeRef(MPerspective))
				para.annotations += _annotationTypesBuilder.annotationRef(typeof(Active))
				para.annotations += _annotationTypesBuilder.annotationRef(typeof(Optional))
				parameters += para
				body = [append('''«activatePart»''')]
			])
		}
		// create canExecute
		type.members += action.toMethod("canExecute", _typeReferenceBuilder.typeRef(boolean), [
			annotations += _annotationTypesBuilder.annotationRef(CanExecute)
			switch (action.actionType) {
				ActionTask: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
				}
				ActionSelectWorkload: {
				}
				ActionDialog: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("userAccessService", _typeReferenceBuilder.typeRef(IUserAccessService))
					parameters += action.toParameter("viewContext", _typeReferenceBuilder.typeRef(IViewContext))
				}
				ActionReport: {
				}
				ActionChart: {
				}
				ActionWorkflow: {
				}
				ActionTable: {
				}
				ActionDatainterchange: {
					parameters += action.toParameter("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange))
					if((action.actionType as ActionDatainterchange).hasfilter){
						parameters += action.toParameter("viewContext", _typeReferenceBuilder.typeRef(IViewContext))
					}
				}
				ActionFunction: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
				}
				ActionUI: {
					if ((action.actionType as ActionUI).action == UIActionEnum.DATABASE_INFO) {
						parameters +=
							action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					}
				}
			}
			body = [append('''«action.canExecute»''')]
		])
		// create execute
		type.members += action.toMethod("execute", _typeReferenceBuilder.typeRef(Void::TYPE), [
			annotations += _annotationTypesBuilder.annotationRef(Execute)
			switch (action.actionType) {
				ActionTask: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionSelectWorkload: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionDialog: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionReport: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionChart: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionTable: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionWorkflow: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
				}
				ActionDatainterchange: {
					parameters += action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
					parameters +=
						action.toParameter("persistenceService", _typeReferenceBuilder.typeRef(IPersistenceService))
					parameters += action.toParameter("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange))
					parameters +=
						action.toParameter("executorService", _typeReferenceBuilder.typeRef(VaadinExecutorService))
					parameters +=
						action.toParameter("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService))
					parameters += action.toParameter("blobService", _typeReferenceBuilder.typeRef(IBlobService))
					parameters += action.toParameter("user", _typeReferenceBuilder.typeRef(IUser))
					if((action.actionType as ActionDatainterchange).hasFilter ){						
						parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					}
				}
				ActionFunction: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					if ((action.actionType as ActionFunction).hasExecuteLater) {
						parameters +=
							action.toParameter("executorService", _typeReferenceBuilder.typeRef(VaadinExecutorService))
					}
					if ((action.actionType as ActionFunction).hasMessage ||
						(action.actionType as ActionFunction).hasStartedMessage) {
						parameters +=
							action.toParameter("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService))
						parameters += action.toParameter("user", _typeReferenceBuilder.typeRef(IUser))
					}
				}
				ActionUI: {
					if ((action.actionType as ActionUI).action == UIActionEnum.DATABASE_INFO) {
						parameters +=
							action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
						parameters +=
							action.toParameter("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))
					} else if ((action.actionType as ActionUI).action == UIActionEnum.MDX_QUERY) {
						parameters +=
							action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
					}
				}
			}
			body = [append('''«action.execute»''')]
		])
	}

	def execute(ActionCommand command) {
		switch command.actionType {
			ActionDatainterchange:
				((command.actionType as ActionDatainterchange).dataRef as DataInterchange)?.doInterchange(command)
			default:
				command.doExecute
		}
	}

	def doInterchange(DataInterchange dataInterchange, ActionCommand action)'''
	«val actioninterchange = (action.actionType as ActionDatainterchange)»
	«getConfigFileURL((dataInterchange.eContainer as DataInterchangeGroup).name)»
	«data.getBasicRunConfiguration(dataInterchange, true, actioninterchange.action.literal, null)»
	«dataInterchange.getDefaultVariableName()».setDirection(WorkerThreadRunnable.Direction.«actioninterchange.action.literal.toUpperCase»);
	«dataInterchange.getDefaultVariableName()».setEventDispatcher(eventDispatcher);
	«dataInterchange.getDefaultVariableName()».setBlobService(blobService);
	
	«if(actioninterchange.hasFilter){
		'''
		«determineInterchangeFilter(dataInterchange.getDefaultVariableName(), actioninterchange)»
		«dataInterchange.getDefaultVariableName()».setActionFilterExecutionNeeded(true);
		'''
	}»
	
	Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "datainterchangeStarted"),Notification.Type.HUMANIZED_MESSAGE);
	executorService.invokeLater(null, new Runnable() {
		@Override
		public void run() {
			«dataInterchange.getDefaultVariableName()».run();
		}
	});'''
	
	def determineInterchangeFilter(String interchangename, ActionDatainterchange actioninterchange){
		var result = ""
		var parameterList = actioninterchange.dataRef.actionFilter.getFilterAttributesAndReferences
		for(var i=0; i<parameterList.size; i++){
			result= result.concat('''
			filters.put("param«i»", new Parameter("«parameterList.get(i).name»", viewContext.getBean("«parameterList.get(i).name»Param«i»")));
			''')
		}
		if(!result.isEmpty){
			result = '''
			IViewContext viewContext = eclipseContext.<IViewContext>get(IViewContext.class);
			HashMap<String, Parameter> filters = new HashMap<String, Parameter>();
			''' + result.concat('''«interchangename».setFilter(filters);''')
		}
		return result
	}
	
	def List<LEntityFeature> getFilterAttributesAndReferences(DataInterchangeFilter filter){
		var results = <LEntityFeature>newArrayList
		if(filter !== null && filter.attrFilter !== null){
			results.addAll(filter.attrFilter.attributes)
		}
		if(filter !== null && filter.refFilter !== null){
			results.addAll(filter.refFilter.refAttributes)
		}
		return results
	}
	
	def List<LEntityFeature> getAttributes(AttributeFilter filter){
		var results = <LEntityFeature>newArrayList
		if(filter !== null && filter.refProperty !== null){
			results.add(filter.refProperty)
			if(filter.subCondition !== null){
				results.addAll(filter.subCondition.attributes)
			}
		}
		return results
	}
	
	def List<LEntityFeature> getRefAttributes(ReferenceFilter filter){
		var results = <LEntityFeature>newArrayList
		if(filter !== null && filter.refEntity !== null){
			if(filter instanceof ReferenceFilterWithAttr){
				if(filter.refProperty !== null) {
					results.add(filter.refProperty)					
				}
			}
			else if(filter instanceof ReferenceFilterWithOutAttr){
				if(filter.refEntity !== null) {
					results.add(filter.refEntity)					
				}
			}
			if(filter.subCondition !== null){
				results.addAll(filter.subCondition.refAttributes)
			}
		}
		return results
	}
	
	
	def String doExecute(ActionCommand command) {
		var String actionEnumStr
		switch command.actionType {
			ActionTask:
				actionEnumStr = (command.actionType as ActionTask).action.getEnumString.toString
			ActionSelectWorkload:
				actionEnumStr = (command.actionType as ActionSelectWorkload).action.getEnumString.toString
			ActionDialog:
				actionEnumStr = (command.actionType as ActionDialog).action.getEnumString.toString
			ActionReport:
				actionEnumStr = (command.actionType as ActionReport).action.getEnumString.toString
			ActionChart:
				actionEnumStr = (command.actionType as ActionChart).action.getEnumString.toString
			ActionTable:
				actionEnumStr = (command.actionType as ActionTable).action.getEnumString.toString
			ActionWorkflow:
				actionEnumStr = (command.actionType as ActionWorkflow).action.getEnumString.toString
			ActionFunction:
				actionEnumStr = "Execute"
			ActionUI:
				actionEnumStr = (command.actionType as ActionUI).action.getEnumString.toString
		}
		if (command.actionType instanceof ActionFunction) {
			var func = command.actionType as ActionFunction
			if (func.hasExecuteImmediate) {
				return '''
				«IF func.hasMessage»boolean result = «ENDIF»«(func.actionGroup.eContainer as FunctionLibraryPackage).fullyQualifiedName».«func.actionGroup.name.toString.toFirstUpper».«func.executeImmediate.name.toString»(eclipseContext);
				«IF func.hasMessage»
					if(!result) {
						Notification.show(«(func.messageCategory.eContainer as MessagePackage).fullyQualifiedName».«func.messageCategory.name»Message.«func.onFailMessage.name.toFirstLower»().getShowMessage(dslMetadataService, user),Notification.Type.ERROR_MESSAGE);
					} «IF func.hasSuccessMessage»else {
							Notification.show(«(func.messageCategory.eContainer as MessagePackage).fullyQualifiedName».«func.messageCategory.name»Message.«func.onSuccessMessage.name.toFirstLower»().getShowMessage(dslMetadataService, user), Notification.Type.HUMANIZED_MESSAGE);
					}«ENDIF»«ENDIF»'''
			}
			if (func.hasExecuteLater) {
				return '''
				«IF func.hasStartedMessage»
					Notification.show(«(func.messageCategory.eContainer as MessagePackage).fullyQualifiedName».«func.messageCategory.name»Message.«func.onStartedMessage.name.toFirstLower»().getShowMessage(dslMetadataService, user),Notification.Type.HUMANIZED_MESSAGE);
				«ENDIF»
				executorService.invokeLater(eclipseContext, new Runnable() {
					@Override
					public void run() {
						«(func.actionGroup.eContainer as FunctionLibraryPackage).fullyQualifiedName».«func.actionGroup.name.toString.toFirstUpper».«func.executeLater.name.toString»(eclipseContext);
					}
				});'''
			}
		} else if (command.actionType instanceof ActionUI &&
			(command.actionType as ActionUI).action == UIActionEnum.NEXT_PART) {
			return '''
			log.debug("execute next part");
			MUIElement newActivePart = E4Helper.getPart(true, getActivePart(), true);
			if(newActivePart != null && newActivePart instanceof MPart) {
				MPart part = (MPart)newActivePart;
				part.getContext().activate();
			}'''
		} else if (command.actionType instanceof ActionUI &&
			(command.actionType as ActionUI).action == UIActionEnum.PREVIOUS_PART) {
			return '''
			log.debug("execute previous part");
			MUIElement newActivePart = E4Helper.getPart(false, getActivePart(), true);
			if(newActivePart != null && newActivePart instanceof MPart) {
				MPart part = (MPart)newActivePart;
				part.getContext().activate();
				IE4Dialog dialog = part.getContext().get(IE4Dialog.class);
				if (dialog != null) {
					ContextInjectionFactory.invoke(dialog, Focus.class, part.getContext());
				}
				IE4Table table = part.getContext().get(IE4Table.class);
				if (table != null) {
					ContextInjectionFactory.invoke(table, Focus.class, part.getContext());
				}
				IE4Focusable focusable = part.getContext().get(IE4Focusable.class);
				if (focusable != null) {
					ContextInjectionFactory.invoke(focusable, Focus.class, part.getContext());
				}
			}'''

		} else if (command.actionType instanceof ActionUI &&
			(command.actionType as ActionUI).action == UIActionEnum.PREVIOUS_PERSPECTIVE) {
			return '''
			log.debug("execute previous perspective");
			if (getActivePart() != null) {
				MUIElement newActivePerspective = getActivePart().getParent();
				if (newActivePerspective != null && newActivePerspective instanceof MPerspectiveStack) {
					MPerspectiveStack stack = (MPerspectiveStack) newActivePerspective;
					int childrenCount = stack.getChildren().size();
					int idx = stack.getChildren().indexOf(getActivePart());
					if (--idx >= 0) {
						newActivePerspective = stack.getChildren().get(idx);
					} else {
						newActivePerspective = stack.getChildren().get(--childrenCount);
					}
					String elementId = newActivePerspective.getElementId();
					IEclipseContext context = ((MPerspective) newActivePerspective).getContext();
					if (elementId.equals(IPerspectiveProvider.toPerspectiveElementId(IPerspectiveProvider.WELCOME_SCREEN_ID))) {
						if (context.containsKey(EModelService.class)) {
							context.get(EModelService.class).bringToTop(newActivePerspective);
						}
					} else {
						HybridVaadinVaaclipseConnector.instance(context).onFocusPerspective(elementId);
					}
				}
			}'''

		} else if (command.actionType instanceof ActionUI &&
			(command.actionType as ActionUI).action == UIActionEnum.NEXT_PERSPECTIVE) {
			return '''
		    log.debug("execute next perspective");
		    if (getActivePart() != null) {
		    	MUIElement newActivePerspective = getActivePart().getParent();
		    	if (newActivePerspective != null && newActivePerspective instanceof MPerspectiveStack) {
		    		MPerspectiveStack stack  = (MPerspectiveStack) newActivePerspective;
		    		int childrenCount = stack.getChildren().size();
		    		int idx = stack.getChildren().indexOf(getActivePart());
		    		if(++idx < childrenCount){
		    			newActivePerspective = stack.getChildren().get(idx);
		    		}else{
		    			newActivePerspective = stack.getChildren().get(0);
		    		}
		    		String elementId = newActivePerspective.getElementId();
		    		IEclipseContext context = ((MPerspective) newActivePerspective).getContext();
		    		if(elementId.equals(IPerspectiveProvider.toPerspectiveElementId(IPerspectiveProvider.WELCOME_SCREEN_ID))){
		    			if (context.containsKey(EModelService.class)) {
		    				context.get(EModelService.class).bringToTop(newActivePerspective);
		    			}
		    		}else{    			
		    			HybridVaadinVaaclipseConnector.instance(context).onFocusPerspective(elementId);
		    		}
		    	}
		    }'''

		} else if (command.actionType instanceof ActionUI &&
			(command.actionType as ActionUI).action == UIActionEnum.MDX_QUERY) {
			return '''
				UI.getCurrent().addWindow(new MDXDialog(eclipseContext));
			'''
		} else {
			return '''
			log.debug("action execute called for «command.name»");
			String uuid = (String)eclipseContext.get("«IToolbarAction.TOOLBAR_UUID»");
			MPerspective perspective = eclipseContext.get(MPerspective.class);
			EventDispatcherEvent evnt = new EventDispatcherEvent(perspective, EventDispatcherCommand.ACTION, uuid, "«command.fullyQualifiedName»");
			evnt.addItem(EventDispatcherDataTag.BUTTON_ID, «actionEnumStr»);
			«IF command.actionType instanceof ActionTask»
				evnt.addItem(EventDispatcherDataTag.TASK_ID, TaskHelper.getTaskId(eclipseContext));
			«ENDIF»
			eventDispatcher.sendEvent(evnt);'''
		}
	}

	def getEnumString(Enumerator actionEnum) '''«actionEnum.class.simpleName».«actionEnum.name»'''

	def canExecute(ActionCommand action) {

		switch action.actionType {
			ActionTask: {
				return '''return TaskHelper.«(action.actionType as ActionTask).action.literal.toFirstLower»CanExecute(eclipseContext);'''
			}
			ActionUI: {
				if ((action.actionType as ActionUI).action == UIActionEnum.DATABASE_INFO) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					boolean result = !(boolean) ContextInjectionFactory.invoke(dialog, IsNew.class, eclipseContext);
					return result;'''
				} else {
					return '''
						return true;
					'''
				}
			}
			ActionDialog: {
				if ((action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_SAVE) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					Object dto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					if (dto == null) {
						return false;
					}
					boolean result1 = (boolean) ContextInjectionFactory.invoke(dialog, IsValid.class, eclipseContext);
					boolean result2 = (boolean) ContextInjectionFactory.invoke(dialog, IsDirty.class, eclipseContext);
					boolean result3 = true;
					if( result1 && result2) {
						String clazzName = dto.getClass().getName();
						String grantKey = clazzName + "###UPDATABLE";
						if( isGranted.containsKey(grantKey)) {
							result3=isGranted.get(grantKey);
						} else {
							result3 = userAccessService.isGranted(Group.DTO, Action.UPDATABLE, clazzName);
							isGranted.put(grantKey,result3);
						}
					}
					return result1 && result2 && result3;'''
				
				} else if (	(action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_SAVE_AND_NEW ) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					Object dto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					if (dto == null) {
						return false;
					}
					boolean result1 = (boolean) ContextInjectionFactory.invoke(dialog, IsValid.class, eclipseContext);
					boolean result2 = (boolean) ContextInjectionFactory.invoke(dialog, IsDirty.class, eclipseContext);
					boolean result3 = true;
					boolean result4 = true;
					if( result1 && result2) {
						String clazzName = dto.getClass().getName();
						String grantKey = clazzName + "###UPDATABLE";
						if( isGranted.containsKey(grantKey)) {
							result3=isGranted.get(grantKey);
						} else {
							result3 = userAccessService.isGranted(Group.DTO, Action.UPDATABLE, clazzName);
							isGranted.put(grantKey,result3);
						}
						if( result3 ) {
							grantKey = clazzName + "###CREATABLE";
							if( isGranted.containsKey(grantKey)) {
								result4=isGranted.get(grantKey);
							} else {
								result4 = userAccessService.isGranted(Group.DTO, Action.CREATABLE, clazzName);
								isGranted.put(grantKey,result4);
							}
						}
					}
					return result1 && result2 && result3 && result4;'''
				
				} else if ( (action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_SAVE_AS_NEW) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					Object dto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					if (dto == null) {
						return false;
					}
					boolean result1 = (boolean) ContextInjectionFactory.invoke(dialog, IsValid.class, eclipseContext);
					boolean result2 = (boolean) ContextInjectionFactory.invoke(dialog, IsDirty.class, eclipseContext);
					boolean result3 = true;
					if( result1 && result2 ) {
						String clazzName = dto.getClass().getName();
						String grantKey = clazzName + "###CREATABLE";
						if( isGranted.containsKey(grantKey)) {
							result3=isGranted.get(grantKey);
						} else {
							result3 = userAccessService.isGranted(Group.DTO, Action.CREATABLE, clazzName);
							isGranted.put(grantKey,result3);
						}
					}
					return result1 && result2 && result3;'''
				} else if ((action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_NEW) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					Object dto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					if (dto == null) {
						return false;
					}
					boolean result = !(boolean) ContextInjectionFactory.invoke(dialog, IsDirty.class, eclipseContext);
					boolean result2 = true;
					if( result ) {
						String clazzName = dto.getClass().getName();
						String grantKey = clazzName + "###CREATABLE";
						if( isGranted.containsKey(grantKey)) {
							result2=isGranted.get(grantKey);
						} else {
							result2=userAccessService.isGranted(Group.DTO, Action.CREATABLE, clazzName);
							isGranted.put(grantKey,result2);
						}
					}
					return result && result2;'''

				} else if ((action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_DELETE) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					Object dto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
					if (dto == null) {
						return false;
					}
					boolean result1 = !(boolean) ContextInjectionFactory.invoke(dialog, IsNew.class, eclipseContext);
					boolean result2 = (boolean) ContextInjectionFactory.invoke(dialog, IsPositioned.class, eclipseContext);
					boolean result3 = true;
					if( result1 && result2 ) {
						String clazzName = dto.getClass().getName();
						String grantKey = clazzName + "###DELETEABLE";
						if( isGranted.containsKey(grantKey)) {
							result3=isGranted.get(grantKey);
						} else {
							result3=userAccessService.isGranted(Group.DTO, Action.DELETEABLE, clazzName);
							isGranted.put(grantKey,result3);
						}
					}
					return result1 && result2 && result3;'''
				} else if ((action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_CANCEL) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					boolean result = (boolean) ContextInjectionFactory.invoke(dialog, IsDirty.class, eclipseContext);
					return result;'''
				} else {
					return '''return true;'''
				}
			}
			ActionFunction: {
				var pkg = (action.actionType as ActionFunction).actionGroup.eContainer as FunctionLibraryPackage
				return '''return «pkg.fullyQualifiedName.toString».«(action.actionType as ActionFunction).actionGroup.name.toString.toFirstUpper».«(action.actionType as ActionFunction).canExecute.name.toString»(eclipseContext);'''
			}
			ActionDatainterchange: {
				return '''return «IF action.actionType instanceof ActionDatainterchange»(dataInterchange!=null)«ELSE»true«ENDIF»;'''
			}
			default:
				return '''return true;'''
		}
	}
	
	def boolean hasFilter(ActionDatainterchange actioninterchange){
		if(actioninterchange !== null && actioninterchange.hasfilter  && actioninterchange.dataRef !== null &&  actioninterchange.dataRef.actionFilter !== null 
		&& (actioninterchange.dataRef.actionFilter.attrFilter !== null || actioninterchange.dataRef.actionFilter.refFilter !== null) ){
			return true
		}
		return false
	}
}
