/**
 *                                                                            
 *  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
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */

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

import javax.inject.Inject
import javax.inject.Named
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.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.runtime.common.event.IEventDispatcher
import org.eclipse.osbp.ui.api.contextfunction.ICommandsProvider
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.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.ActionTask
import org.eclipse.osbp.xtext.action.ActionToolbar
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.DataInterchange
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
import org.eclipse.osbp.ui.api.customfields.IBlobService

/**
 * <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
	@Inject

	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
		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 including the uuid.</p> 
	 * 
	 */
	def void toToolbarConstructor(JvmGenericType type, ActionToolbar toolbar) {
		type.members += toolbar.toConstructor(
		[
			parameters += toolbar.toParameter("uuid", _typeReferenceBuilder.typeRef(String))
			body = [
				append(
					'''
				super();
				this.uuid = uuid;''')
			]
		])
	}

	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))
			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;''')]
		])
		// 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»
			MenuFactoryImpl factory = MenuFactoryImpl.eINSTANCE;
			MHandledToolItem toolItem = 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, ActionButton action) '''
		
			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»
	'''

	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
	}

	// 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
		// 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) {
			return;
		}
		if(activePart != null && activePart.getWidget() instanceof Panel) {
			((Panel)activePart.getWidget()).removeStyleName(EnumCssClass.HAS_FOCUS.styleName());
		}
		if(part.getWidget() instanceof Panel) {
			activePart = part;
			((Panel)activePart.getWidget()).addStyleName(EnumCssClass.HAS_FOCUS.styleName());
			   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»''')]
			])
		}
		// 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))
				ActionReport: {
				}
				ActionChart: {
				}
				ActionWorkflow: {
				}
				ActionDatainterchange: {
					parameters += action.toParameter("dataInterchange", _typeReferenceBuilder.typeRef(IDataInterchange))
				}
				ActionFunction: {
					parameters += action.toParameter("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext))
				}
				ActionUI: {
				}
			}
			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))
				}
				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))
				}
				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: {
				}
			}
			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) '''
	«data.getBasicRunConfiguration(dataInterchange, true, data.getFileURL(dataInterchange), (action.actionType as ActionDatainterchange).action.literal)»
	«dataInterchange.getDefaultVariableName()».setDirection(WorkerThreadRunnable.Direction.«(action.actionType as ActionDatainterchange).action.literal.toUpperCase»);
	«dataInterchange.getDefaultVariableName()».setEventDispatcher(eventDispatcher);
	«dataInterchange.getDefaultVariableName()».setBlobService(blobService);
	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 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
			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)newActivePart).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)newActivePart).getContext().activate();
				}'''
		} else {
			return '''
			log.debug("action execute called for «command.name»");
			String uuid = (String)eclipseContext.get("«IToolbarAction.TOOLBAR_UUID»");
			EventDispatcherEvent evnt = new EventDispatcherEvent(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);'''
			}
			ActionDialog: {
				if ((action.actionType as ActionDialog).action == DialogActionEnum.DIALOG_ACTION_SAVE) {
					return '''
					IE4Dialog dialog = eclipseContext.get(IE4Dialog.class);
					if (dialog == null) {
						return false;
					}
					boolean result = (boolean) ContextInjectionFactory.invoke(dialog, IsValid.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;'''
		}
	}
}
