/**
 *                                                                            
 * 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.chart.jvmmodel

import com.ejt.vaadin.sizereporter.ComponentResizeListener
import com.ejt.vaadin.sizereporter.SizeReporter
import com.vaadin.server.StreamResource
import com.vaadin.shared.ui.JavaScriptComponentState
import com.vaadin.ui.AbstractJavaScriptComponent
import com.vaadin.ui.Component
import com.vaadin.ui.VerticalLayout
import elemental.json.JsonException
import java.util.ArrayList
import java.util.HashMap
import java.util.HashSet
import java.util.List
import java.util.Locale
import java.util.Set
import javax.annotation.PostConstruct
import javax.annotation.PreDestroy
import javax.inject.Inject
import org.dussan.vaadin.dcharts.DCharts
import org.eclipse.e4.core.contexts.IEclipseContext
import org.eclipse.e4.ui.di.Focus
import org.eclipse.e4.ui.model.application.MApplication
import org.eclipse.e4.ui.workbench.IPresentationEngine
import org.eclipse.emf.common.notify.Adapter
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent
import org.eclipse.osbp.runtime.common.event.IEventDispatcher
import org.eclipse.osbp.ui.api.datamart.DatamartFilter
import org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator
import org.eclipse.osbp.ui.api.e4.IE4Focusable
import org.eclipse.osbp.ui.api.layout.IViewLayoutManager
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService
import org.eclipse.osbp.ui.api.themes.EnumCssClass
import org.eclipse.osbp.ui.api.themes.IThemeResourceService
import org.eclipse.osbp.ui.api.user.IUser
import org.eclipse.osbp.xtext.action.ActionPackage
import org.eclipse.osbp.xtext.chart.Chart
import org.eclipse.osbp.xtext.chart.ChartAxis
import org.eclipse.osbp.xtext.chart.ChartBar
import org.eclipse.osbp.xtext.chart.ChartBubble
import org.eclipse.osbp.xtext.chart.ChartDatamart
import org.eclipse.osbp.xtext.chart.ChartDonut
import org.eclipse.osbp.xtext.chart.ChartGauge
import org.eclipse.osbp.xtext.chart.ChartHighlighter
import org.eclipse.osbp.xtext.chart.ChartLegend
import org.eclipse.osbp.xtext.chart.ChartLine
import org.eclipse.osbp.xtext.chart.ChartNumberInterval
import org.eclipse.osbp.xtext.chart.ChartPackage
import org.eclipse.osbp.xtext.chart.ChartPie
import org.eclipse.osbp.xtext.chart.ChartSegmentColor
import org.eclipse.osbp.xtext.chart.ChartTree
import org.eclipse.osbp.xtext.cubedsl.CubeLevel
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCellSet
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute
import org.eclipse.osbp.xtext.datamartdsl.DatamartCube
import org.eclipse.osbp.xtext.datamartdsl.DatamartCubeAxis
import org.eclipse.osbp.xtext.datamartdsl.DatamartDerivedMeasure
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity
import org.eclipse.osbp.xtext.datamartdsl.DatamartMeasure
import org.eclipse.osbp.xtext.datamartdsl.DatamartMember
import org.eclipse.osbp.xtext.datamartdsl.DatamartOwner
import org.eclipse.osbp.xtext.datamartdsl.DatamartPackage
import org.eclipse.osbp.xtext.datamartdsl.ValueScaleEnum
import org.eclipse.osbp.xtext.datamartdsl.jvmmodel.DatamartDSLJvmModelInferrer
import org.eclipse.osbp.xtext.table.common.PropertyLookup
import org.eclipse.xtext.common.types.JvmAnnotationReference
import org.eclipse.xtext.common.types.JvmConstructor
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmOperation
import org.eclipse.xtext.common.types.JvmStringAnnotationValue
import org.eclipse.xtext.common.types.JvmVisibility
import org.eclipse.xtext.common.types.TypesFactory
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.event.EventHandler
import org.slf4j.Logger
import com.vaadin.annotations.JavaScript
import java.util.stream.Collectors
import org.eclipse.osbp.xtext.chart.CanvasFontFamilyEnum

/**
 * <p>
 * This inferrer infers models of extension .chart and generates code to be used by a e4 application as view. Underlying components
 * are from the vaadin component repository and especially the vaadin addon dChart.
 * </p>
 * 
 * @author Joerg Riegel
 */

/**
 * <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 ChartDSLJvmModelInferrer extends AbstractModelInferrer {

	@Inject extension JvmTypesBuilder
	@Inject extension IQualifiedNameProvider
	@Inject extension DatamartDSLJvmModelInferrer datamartInferrer
	@Inject extension D3JsJavaUtil
	@Inject	private TypesFactory typesFactory
	
	/**
	 * <p>infer method dispatches the necessary routines to build fields, setter, getter, constructors and methods of the generated code.</p> 
	 *
	 */
	def dispatch void infer(ChartPackage pckg, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
		for (chart:pckg.charts) {
			var cls = chart.toClass(pckg.fullyQualifiedName+"."+chart.name+"Chart")
	        cls.superTypes.add(_typeReferenceBuilder.typeRef(AbstractHybridVaaclipseView))
			cls.superTypes.add(_typeReferenceBuilder.typeRef(IUser.UserLocaleListener))
			cls.superTypes.add(_typeReferenceBuilder.typeRef(IDatamartFilterGenerator.FilterChangeListener))
			cls.superTypes.add(_typeReferenceBuilder.typeRef(IEventDispatcher.Receiver))
			cls.superTypes.add(_typeReferenceBuilder.typeRef(IE4Focusable))
	   		acceptor.accept(cls,
	   			[
	   				it.fileHeader = pckg.documentation
	   				it.toFields(chart)
	   				it.toConstructor(chart)
					it.toGetterSetter(chart)
					it.toOperations(chart)
	   			])
	   		if ((chart.charttype instanceof ChartTree)) {
	   			chart.createJsJavaComponent(acceptor)
	   		}
		}
   	}

	/**
	 * <p>build the constructors to be used by an e4 application.</p> 
	 *
	 */
	def void toConstructor(JvmDeclaredType type, Chart chart) {
		type.members += chart.toConstructor([
			annotations += _annotationTypesBuilder.annotationRef(Inject)
   			parameters += chart.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout))
   			parameters += chart.toParameter("context", _typeReferenceBuilder.typeRef(IEclipseContext))
   			parameters += chart.toParameter("app", _typeReferenceBuilder.typeRef(MApplication))
			body = [ append(
				'''
				super(parent,context,app);''')]
		])
	}
	
	/**
	 * <p>build the class variables.</p> 
	 *
	 */
	def void toFields(JvmDeclaredType type, Chart chart) {
   		var JvmField field = null
   		// create logger
		field = chart.toField("log", _typeReferenceBuilder.typeRef(Logger))[setInitializer([append('''org.slf4j.LoggerFactory.getLogger("charts")''')])]
   		field.static = true
   		field.visibility = JvmVisibility::PRIVATE
		type.members += field
		field = chart.toField("user", _typeReferenceBuilder.typeRef(IUser)) [annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		field = chart.toField("eclipseContext", _typeReferenceBuilder.typeRef(IEclipseContext)) [annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		field = chart.toField("coordinateSystem", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(Integer)))
		type.members += field
		field = chart.toField("filterGenerator", _typeReferenceBuilder.typeRef(IDatamartFilterGenerator))
		type.members += field
		field = chart.toField("layoutManager", _typeReferenceBuilder.typeRef(IViewLayoutManager))
		type.members += field
		// the package name of the referenced datamart
		if (getSourceDataMartRefName(chart) !== null) {
			var packageName = (chart.source.datamartRef.eContainer as DatamartPackage).fullyQualifiedName.toString
			field = chart.toField("datamartInstance", _typeReferenceBuilder.typeRef('''«packageName».«chart.source.datamartRef.name.toString»Datamart'''))
			type.members += field
		}
		field = chart.toField("dataComponent", _typeReferenceBuilder.typeRef(Component))
		type.members += field
		field = chart.toField("attributeLookupMap", _typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(PropertyLookup)))
		type.members += field
		field = chart.toField("charts", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(DCharts)))
		type.members += field
		field = chart.toField("refreshView", _typeReferenceBuilder.typeRef(EventHandler))
		type.members += field
		field = chart.toField("dslMetadataService", _typeReferenceBuilder.typeRef(IDSLMetadataService)) [annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		field = chart.toField("eventDispatcher", _typeReferenceBuilder.typeRef(IEventDispatcher))[annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		field = chart.toField("renderingEngine", _typeReferenceBuilder.typeRef(IPresentationEngine))[annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		field = chart.toField("themeResourceService", _typeReferenceBuilder.typeRef(IThemeResourceService))[annotations += _annotationTypesBuilder.annotationRef(Inject)]
		type.members += field
		if (chart.toolbar !== null && chart.toolbar.eContainer !== null) {
			var packageName = (chart.toolbar.eContainer as ActionPackage).fullyQualifiedName.toString
			field = chart.toField("toolbarUUID", _typeReferenceBuilder.typeRef(String))
			type.members += field
			field = chart.toField("toolbarClass", _typeReferenceBuilder.typeRef('''«packageName».«chart.toolbar.name.toString.toFirstUpper»Toolbar'''))
			type.members += field
		}
		field = chart.toField("panelWidth", _typeReferenceBuilder.typeRef(int))
		type.members += field
		field = chart.toField("panelHeight", _typeReferenceBuilder.typeRef(int))
		type.members += field
		field = chart.toField("splitAdapter", _typeReferenceBuilder.typeRef(Adapter.Internal))
		type.members += field
		field = chart.toField("resizeListener", _typeReferenceBuilder.typeRef(ComponentResizeListener))
		type.members += field
		field = chart.toField("sizeReporter", _typeReferenceBuilder.typeRef(SizeReporter));
		type.members += field
	}

	/**
	 * <p>build the getters and setters from class variables.</p> 
	 *
	 */
	def void toGetterSetter(JvmDeclaredType type, Chart chart) {
  		var JvmOperation operation = null 
  		operation = chart.toGetter("coordinateSystem", _typeReferenceBuilder.typeRef(ArrayList, _typeReferenceBuilder.typeRef(Integer)))
  		operation.visibility = JvmVisibility::PUBLIC
  		type.members += operation
	}
	
	/**
	 * <p>build the methods.</p> 
	 *
	 */
	def void toOperations(JvmDeclaredType type, Chart chart) {
		// activate
		type.members += chart.toMethod("activate", _typeReferenceBuilder.typeRef(Void::TYPE),
			[
				annotations += _annotationTypesBuilder.annotationRef(PostConstruct)
				body = [append(
				'''
				super.initView();
				user.addUserLocaleListener(this);
				filterGenerator.addFilterChangeListener(this);
				// to resize the chart according to split positions of partsashcontainer - setContainerData is tracked
				((EObject)getPart()).eAdapters().add(splitAdapter);
				sizeReporter.addResizeListener(resizeListener);
				eventDispatcher.addEventReceiver(this);''')]
			])

		// deactivate
		type.members += chart.toMethod("deactivate", _typeReferenceBuilder.typeRef(Void::TYPE),
			[
				annotations += _annotationTypesBuilder.annotationRef(PreDestroy)
				body = [append(
				'''
				user.removeUserLocaleListener(this);
				filterGenerator.removeFilterChangeListener(this);
				((EObject)getPart()).eAdapters().remove(splitAdapter);
				sizeReporter.removeResizeListener(resizeListener);
				eventDispatcher.removeEventReceiver(this);
				super.destroyView();''')]
			])
   		// create view
   		type.members += chart.toMethod("createView", _typeReferenceBuilder.typeRef(Void::TYPE), [
   			parameters += chart.toParameter("parent", _typeReferenceBuilder.typeRef(VerticalLayout))
   			body = [ append('''«chart.createView»''')]
   		])
   		// create components
   		type.members += chart.toMethod("createComponents", _typeReferenceBuilder.typeRef(Void::TYPE), [
   			body = [ append('''«chart.createComponents»''')]
   		])
   		// create tab
   		type.members += chart.toMethod("createTabSheet", _typeReferenceBuilder.typeRef(Component), [
   			parameters += chart.toParameter("cellSet", _typeReferenceBuilder.typeRef(DerivedCellSet))
   			parameters += chart.toParameter("axisNo", _typeReferenceBuilder.typeRef(Integer))
   			body = [ append('''«chart.createTabSheet»''')]
   		])
   		// create chart
   		if (!((chart.charttype instanceof ChartTree))) {
	   		type.members += chart.toMethod("createChart", _typeReferenceBuilder.typeRef(Component), [
	   			parameters += chart.toParameter("cellSet", _typeReferenceBuilder.typeRef(DerivedCellSet))
	   			body = [ append('''«chart.createChart»''')]
	   		])
   		}
   		// create D3 chart
		if ((chart.charttype instanceof ChartTree)) {
		   		type.members += chart.toMethod("createD3Chart", _typeReferenceBuilder.typeRef(Component), [
	   			exceptions += _typeReferenceBuilder.typeRef(JsonException)
	   			parameters += chart.toParameter("cxCellSet", _typeReferenceBuilder.typeRef(DerivedCellSet))
	   			body = [ append('''«chart.createD3Chart»''')]
	   		])
   		}
		// focus
		type.members += chart.toMethod("setFocus", _typeReferenceBuilder.typeRef(Void::TYPE),
			[
				annotations += _annotationTypesBuilder.annotationRef(Focus)
				body = [append(
				'''
				Component parent = getParent();
				while(!(parent instanceof Panel) && parent != null) {
					parent = parent.getParent();
				}
				if(parent != null) {
					((Panel)parent).focus();
				}''')]
				
			])
		// locale notification
		type.members += chart.toMethod("localeChanged", _typeReferenceBuilder.typeRef(Void::TYPE), [
			visibility = JvmVisibility.PUBLIC
			annotations += _annotationTypesBuilder.annotationRef(Override)
			parameters += chart.toParameter("locale", _typeReferenceBuilder.typeRef(Locale))
			body = [append('''«chart.localeChanged»''')]
		])
		// filter notification
		type.members += chart.toMethod("filterChanged", _typeReferenceBuilder.typeRef(Void::TYPE),
			[
				parameters += chart.toParameter("changedFilter", _typeReferenceBuilder.typeRef(DatamartFilter))
				visibility = JvmVisibility.PUBLIC
				annotations += _annotationTypesBuilder.annotationRef(Override)
				body = [append('''renderData();''')]
			])
		// event notification
		type.members += chart.toMethod("receiveEvent", _typeReferenceBuilder.typeRef(Void::TYPE),
			[
				visibility = JvmVisibility.PUBLIC
				annotations += _annotationTypesBuilder.annotationRef(Override)
				parameters += chart.toParameter("event", _typeReferenceBuilder.typeRef(EventDispatcherEvent))
				body = [append('''«chart.receiveEvent»''')]
			])
		// getChartResource
		type.members += chart.toMethod("getChartResource", _typeReferenceBuilder.typeRef(StreamResource),
			[
				visibility = JvmVisibility.PRIVATE
				parameters += chart.toParameter("chart", _typeReferenceBuilder.typeRef(DCharts))
				parameters += chart.toParameter("layoutManager", _typeReferenceBuilder.typeRef(IViewLayoutManager))
				body = [append('''«chart.chartResource»''')]
			])
	}
	
	def String getSourceDataMartRefName(Chart chart) {
		if (chart.source !== null && chart.source.datamartRef !== null && chart.source.datamartRef.name !== null) {
			return chart.source.datamartRef.name.toString
		}
		else {
			return null;
		}		
	}
	
	/**
	 * <p>build the main method to be called from e4.</p> 
	 *
	 */
	def String createView(Chart chart) {
		var body = 
		'''
		eclipseContext.set(IE4Focusable.class, this);
		charts = new ArrayList<DCharts>();
		coordinateSystem = new ArrayList<Integer>();
		parent.setPrimaryStyleName("osbp"); // <== is THIS necessary any more???
		parent.addStyleName("«EnumCssClass.VIEW.styleName»");
		parent.addStyleName("«EnumCssClass.CHART_VIEW.styleName»");
		parent.setSizeFull();
		layoutManager = new ViewLayoutManager();
		layoutManager.init(parent);
		splitAdapter = new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				if (notification.getEventType()==Notification.SET && 
						notification.getFeatureID(UIElementImpl.class) == UiPackageImpl.UI_ELEMENT__CONTAINER_DATA)
				{
					log.debug("render due to split position changed");
					renderData();
				}
			}
		};
		sizeReporter = new SizeReporter(layoutManager.getDataArea());
		resizeListener = new ComponentResizeListener() {
			@Override
			public void sizeChanged(ComponentResizeEvent event) {
				boolean changed = false;
				if (panelWidth != event.getWidth()) {
					changed = true;
					panelWidth = event.getWidth();
				}
				if (panelHeight != event.getHeight()) {
					changed = true;
					panelHeight = event.getHeight();
				}
				if (changed) {
					log.debug("Panel size changed : " + event.getWidth() + " x " + event.getHeight());
					renderData();
				}
			}
		};
		datamartInstance = new «getSourceDataMartRefName(chart)»Datamart();
		datamartInstance.setUser(user);
		filterGenerator = new DatamartFilterGenerator(datamartInstance, eclipseContext, «chart.source.datamartRef.showCaption.booleanValue», «Integer.max(10,chart.source.datamartRef.numMultiRows)»);
		filterGenerator.createUIFilters(layoutManager);
		attributeLookupMap = new HashMap<String,PropertyLookup>();
		'''
		if (chart.toolbar !== null) {
			body = '''
			«body»
			toolbarUUID = UUID.randomUUID().toString();
			toolbarClass = new «chart.toolbar.name.toString.toFirstUpper»Toolbar();
			toolbarClass.createToolbar(eclipseContext, renderingEngine, themeResourceService, toolbarUUID);'''
		}
		body = '''
		«body»
		refreshView = «chart.refreshView»
		'''
		return body
	}
	
	/**
	 * <p>create a handler for external triggered refresh requests.</p> 
	 *
	 */
	def String refreshView(Chart chart) {
		var body = ""
		body = '''
		«body»
		new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				renderData();
			}
		};
		'''
		return body
	}
	
	/**
	 * <p>build the data components.</p> 
	 *
	 */
	def String createComponents(Chart chart) {
		var body = ""
		if (chart.source !== null) {
			var isCube = ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartCube)
			body = '''
			«body»// get the results
			if (panelWidth == 0 && panelHeight == 0) {
				return;
			}
			final DerivedCellSet cellSet = datamartInstance.getResults(«IF !isCube»false, getTaskOperativeDtoClass(), getTaskInitialOperativeDtos()«ENDIF»);
			getCoordinateSystem().clear();
			charts.clear();
			if (cellSet == null) {
				promptSecurityMessage(dslMetadataService.translate(user.getLocale().toLanguageTag(), "securityMessage"), layoutManager.getDataArea());
				return;
			} else {
				layoutManager.getDataArea().removeAllComponents();
			}
			// generate a new result component
			if (cellSet != null) {
				// create a multidimensional coordinate system against the cellSet
				for	(int axis = 0; axis < cellSet.getAxes().size(); axis++) {
					getCoordinateSystem().add(0);
				}
				// remove any previous component
				if	(dataComponent != null) {
					layoutManager.getDataArea().removeComponent(dataComponent);
					dataComponent = null;
				}
				if (cellSet.getAxes().size() < 2) {
					log.error("at least 2 axes from referenced datamart «chart.source.datamartRef.name» are needed to render «chart.name»");
				} else {
					dataComponent = createTabSheet(cellSet, cellSet.getAxes().size());
					if(dataComponent != null) {
						dataComponent.setSizeFull();
						dataComponent.setId("dataComponent");
						dataComponent.addStyleName("«EnumCssClass.DATA_COMPONENT.styleName»");
						layoutManager.getDataArea().addComponent(dataComponent);
						layoutManager.getDataArea().setExpandRatio(dataComponent, 1);
					}
				}
				getParent().markAsDirtyRecursive();
			}
			else {
				log.error("referenced datamart «chart.source.datamartRef.name» generates no results");
			}
			'''
		} else {
			body = '''
			«body»
			// generate a new result component
			try {
				// remove any previous component
				if	(dataComponent != null) {
					layoutManager.getDataArea().removeComponent(dataComponent);
					dataComponent = null;
				}				
				dataComponent = createTabSheet(null, 2);
				dataComponent.setSizeFull();
				dataComponent.setId("dataComponent");
				dataComponent.addStyleName("«EnumCssClass.DATA_COMPONENT.styleName»");
				layoutManager.getDataArea().addComponent(dataComponent);
				layoutManager.getDataArea().setExpandRatio(dataComponent, 1);
			} catch (DerivedOlapException e) {
				log.error(e.getLocalizedMessage());
			}
			'''
		}
		return body
	}

	/**
	 * <p>if more than 2 axes (dimensions) are found in the cellSet, build recursive tabsheets as long as the remaining axes are more than 2.</p> 
	 *
	 */
	def String createTabSheet(Chart chart) {
		var body = 
		'''
		// either create a recursive tabsheet or a chart
		Component component = null;
		if	(axisNo == 2) {
		'''
		if ((chart.charttype instanceof ChartTree)) {
			body = '''
			«body»
				try {
					component = createD3Chart(cellSet);
				} catch (JsonException e) {
					log.error(e.getLocalizedMessage());
				}
			'''
		}
		else {
			body = '''
			«body»
				component = createChart(cellSet);
			'''
		}
		body = '''
		«body»
		}
		else {		
			Integer axis = axisNo-1;
			TabSheet tabsheet = new TabSheet();
			tabsheet.setSizeFull();
			DerivedAxis tabAxis = cellSet.getAxes().get(axis);
			// create a tab page for all tab axis members
			int tabNo = 0;
			for	(DerivedPosition column : tabAxis.getPositions()) {
				// create the title for the axis
				String title = null;
				for (DerivedMember member : column.getMembers()) {
					if	(title == null) {
						title = dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption());
					}
					else {
						title += " / "+dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption());
					}
				}
				// position the data to this coordinate
				getCoordinateSystem().set(axis, tabNo);
				component = createTabSheet(cellSet, axis);
				// set the caption
				if (component != null) {
					component.setCaption(title);
					// add the component as a tab page
					tabsheet.addComponent(component);
				}
				tabNo++;
			}
			component = tabsheet;
		}
		return component;'''
		return body
	}

	/**
	 * <p>build the chart components.</p> 
	 *
	 */
	def String createChart(Chart chart) {
		var body = ""
		var postfix = ""
		var chartType = ""
		var hasAxis = true
		var multipleAxes = <String, String>newHashMap
		var ChartAxis category_axis = null 
		var ChartAxis data_axis = null 
		var ChartAxis inner_axis = null
		var ChartAxis outer_axis = null 
		var axisSwitch = false;
		var axisPrefix = 'XY'
		var CanvasFontFamilyEnum fontFamily = (chart.eContainer as ChartPackage).defaultFontFamily
		
		if (chart.charttype instanceof ChartBar) {
			if ((chart.charttype as ChartBar).swapped) {
				axisPrefix = 'YX'
				axisSwitch = true; 
			}
		}
		for (element : chart.source.elements) {
			if (element instanceof ChartAxis) {
				var axis = element as ChartAxis
				if (axis.axis.name.getName.equals('COLUMNS') || axis.axis.name.getName.equals('ROWS')) {
					if ((axis.renderType.getName.equals("LOG") || axis.renderType.getName.equals("LINEAR") || axis.renderType.getName.equals("PYRAMID"))) {
						data_axis = axis
					}
					if ((axis.renderType.getName.equals("CATEGORY") || axis.renderType.getName.equals("DATE"))) {
						category_axis = axis
					}
				}
			}
		}
		if (chart.charttype instanceof ChartBar) {
			chartType = "BAR"			
			postfix = '''_«chartType»'''
			inner_axis = category_axis
			outer_axis = data_axis 
		}
		else if (chart.charttype instanceof ChartBubble) {
			chartType = "BUBBLE"			
			postfix = '''_«chartType»'''
			hasAxis = true
			inner_axis = data_axis
			outer_axis = category_axis 
		}
		else if (chart.charttype instanceof ChartDonut) {
			chartType = "DONUT"			
			hasAxis = false
			inner_axis = category_axis
			outer_axis = data_axis 
		}
		else if (chart.charttype instanceof ChartLine) {
			chartType = "LINE"			
			inner_axis = category_axis
			outer_axis = data_axis 
		}
		else if (chart.charttype instanceof ChartPie) {
			chartType = "PIE"			
			hasAxis = false
			inner_axis = data_axis
			outer_axis = category_axis 
		}
		else if (chart.charttype instanceof ChartGauge) {
			chartType = "METER_GAUGE"			
			hasAxis = false
			inner_axis = data_axis
			outer_axis = category_axis 
		}

		body = 
		'''
		List<Integer> coordinate = new ArrayList<Integer>(getCoordinateSystem());
		'''
		body = '''
		«body»// create a label series
		List<String> «data_axis.axis.name.literal»TitlesArray = new ArrayList<String>();
		for	(DerivedPosition pos : cellSet.getAxes().get(«data_axis.axis.name.value»).getPositions()) {
		'''
		body = '''
		«body»
			String title = null;
			for (DerivedMember member : pos.getMembers()) {
				if(member.getType() == MemberType.MEASURE) {
					if	(title == null) {
						title = dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption());
					}
					else {
						title += " "+dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getCaption());
					}
				}
			}
			if(title != null) {
				«data_axis.axis.name.literal»TitlesArray.add(title);
			}
		}
		'''
		if (hasAxis) {
			body = '''
			«body»Series «data_axis.axis.name.literal»Series = new Series();
			'''
			body = '''
			«body»if («data_axis.axis.name.literal»TitlesArray.size() > 0) {
			'''
			// evaluate multiple scales
			var showMarker = false
			if (chart.charttype instanceof ChartLine) {
				showMarker = (chart.charttype as ChartLine).showMarker
			}
			body = '''«body»«chart.createLabelSeries(data_axis, multipleAxes, axisPrefix, showMarker)»'''
			body = '''
			«body»}
			'''
		}	
		body = '''
		«body»// create the data series ticks
		String «category_axis.axis.name.literal»AxisLabel = "";
		Boolean «category_axis.axis.name.literal»AxisLabelSet = false;
		List<String> «category_axis.axis.name.literal»TitlesArray = new ArrayList<String>();
		for	(DerivedPosition pos : cellSet.getAxes().get(«category_axis.axis.name.value»).getPositions()) {
			String title = "";
			for (DerivedMember member : pos.getMembers()) {
				if(member.getType() == MemberType.REGULAR) {
			    	String[] tokens = member.getUniqueName().split("\\]\\.\\[");
			    	if (!«category_axis.axis.name.literal»AxisLabelSet) {
			    		if («category_axis.axis.name.literal»AxisLabel.length() > 0) {
			    			«category_axis.axis.name.literal»AxisLabel += " / ";
			    		}
			    		«category_axis.axis.name.literal»AxisLabel += dslMetadataService.translate(user.getLocale().toLanguageTag(), member.getLevel().getName());
			    	}
			    	int start = 1;
			    	// if shortlabel is configured, use only last level name
			    	if («category_axis.shortLabel.booleanValue») {
			    		start = tokens.length-1;
			    	}
			    	for	(int token = start; token < tokens.length; token++) {
			    		title += dslMetadataService.translate(user.getLocale().toLanguageTag(), tokens[token])+" ";
			    	}
			    }
			}
			if(title != null) {
				«category_axis.axis.name.literal»AxisLabelSet = true;
				«category_axis.axis.name.literal»TitlesArray.add(title.trim().replace("[", "").replace("]", ""));
			}
		}
		'''
		if (hasAxis) {
			body = '''
			«body»Ticks «category_axis.axis.name.literal»Ticks = new Ticks();
			«category_axis.axis.name.literal»Ticks.add(«category_axis.axis.name.literal»TitlesArray.toArray());
			'''
		}
		
		body = '''
		«body»
		if(«category_axis.axis.name.literal»TitlesArray.isEmpty()) {
			return null;
		}
		// copy cellset data to data series
		DataSeries dataSeries = new DataSeries();
		'''
		if (chart.charttype instanceof ChartBubble) {
			body = '''
			«body»dataSeries.newSeries();
			'''
		}
		body = '''
		«body»int «outer_axis.axis.name.literal»No = 0;
		'''
		body = '''
		«body»for	(DerivedPosition «outer_axis.axis.name.literal»Pos : cellSet.getAxes().get(«outer_axis.axis.name.value»).getPositions()) {
		'''
		body = '''
		«body»	coordinate.set(«outer_axis.axis.name.value», «outer_axis.axis.name.literal»No);
		'''
		if (chart.charttype instanceof ChartDonut) {
			body = '''
			«body»	dataSeries.newSeries();
			'''
		}
		if (!(chart.charttype instanceof ChartPie) && !(chart.charttype instanceof ChartDonut)) {
			body = '''
			«body»	ArrayList<Object> «inner_axis.axis.name.literal»DataSeries = new ArrayList<Object>();
			'''				 	
		}
		body = '''
		«body»	if(«outer_axis.axis.name.literal»Pos.getMembers().get(0).getType() == MemberType.«IF outer_axis==data_axis»MEASURE«ELSE»REGULAR«ENDIF») {
		'''
		body = '''
		«body»		int «inner_axis.axis.name.literal»No = 0;
		'''
		body = '''
		«body»		for	(DerivedPosition «inner_axis.axis.name.literal»Pos : cellSet.getAxes().get(«inner_axis.axis.name.value»).getPositions()) {
		'''
		body = '''
		«body»			if(«inner_axis.axis.name.literal»Pos.getMembers().get(0).getType() == MemberType.«IF inner_axis==data_axis»MEASURE«ELSE»REGULAR«ENDIF») {
		'''
		if (chart.charttype instanceof ChartPie) {
			body = '''
			«body»				dataSeries.newSeries();
			'''
		}
		body = '''
		«body»				coordinate.set(«inner_axis.axis.name.value», «inner_axis.axis.name.literal»No);
		'''
		body = '''
		«body»
						Object value = null;
						DerivedCell cell = cellSet.getCell(coordinate);
						if (cell != null) {
							value = cell.getValue();
						}
		'''
		if (chart.charttype instanceof ChartPie || chart.charttype instanceof ChartDonut) {
			body = '''
			«body»				dataSeries.add(«outer_axis.axis.name.literal»TitlesArray.get(«outer_axis.axis.name.literal»No),(value == null ? 0.0 : value));
			'''
		}
		else {
			body = '''
			«body»				«inner_axis.axis.name.literal»DataSeries.add(value == null ? 0.0 : value);
			'''
		}
		body = '''
		«body»				«inner_axis.axis.name.literal»No ++;
					}
				}
		'''
		if (!(chart.charttype instanceof ChartPie) && !(chart.charttype instanceof ChartDonut)) {
			if (chart.charttype instanceof ChartBubble) {
				body = '''
				«body»			«inner_axis.axis.name.literal»DataSeries.add(«outer_axis.axis.name.literal»TitlesArray.get(«outer_axis.axis.name.literal»No));
				'''
			}
			body = '''
			«body»		dataSeries.add(«inner_axis.axis.name.literal»DataSeries.toArray());
			'''
		}
		body = '''
		«body»	}
			«outer_axis.axis.name.literal»No ++;
		}
		'''
		body = '''
		«body»SeriesDefaults seriesDefaults = new SeriesDefaults()
			.setRenderer(SeriesRenderers.«chartType»);
		'''
		if (chart.charttype instanceof ChartLine) {
			body = '''
			«body»seriesDefaults.setFillToZero(«(chart.charttype as ChartLine).fillToZero.booleanValue.toString»).setFill(«(chart.charttype as ChartLine).fillArea.toString»);
			'''
			if ((chart.charttype as ChartLine).trendLine) {
				body = '''
				«body»seriesDefaults.setTrendline(
					new Trendline().setShow(true).setLineWidth(1));
				'''
			} 
		}
		// options
		body = '''
		«body»Options options = new Options()
			.setSeriesDefaults(seriesDefaults);
		'''
		if (chart.charttype instanceof ChartPie) {
			body = '''
			«body»seriesDefaults.setRendererOptions(new PieRenderer()
				.setShowDataLabels(true).setFill(«(!(chart.charttype as ChartPie).empty).toString»));
			'''
		}
		else if (chart.charttype instanceof ChartDonut) {
			body = '''
			«body»seriesDefaults.setRendererOptions(new DonutRenderer()
				.setShowDataLabels(true)
				.setStartAngle(-90)
				.setSliceMargin(3));
			'''
		}
		else if (chart.charttype instanceof ChartBubble) {
			body = '''
			«body»seriesDefaults.setRendererOptions(new BubbleRenderer()
				.setVaryBubbleColors(true)
				«IF (chart.charttype as ChartBubble).multiplier».setAutoscaleMultiplier(«(chart.charttype as ChartBubble).multiplierValue»f)«ENDIF»
			    «IF (chart.charttype as ChartBubble).transparent».setHighlightAlpha(0.8f).setBubbleAlpha(0.6f)«ENDIF»
				«IF (chart.charttype as ChartBubble).gradient».setBubbleGradients(true)«ENDIF»
				.setShowLabels(false)
				.setAutoscaleBubbles(true));
			'''
		}
		else if (chart.charttype instanceof ChartGauge) {
			var intervalValues = ""
			var intervalColors = ""
			if ((chart.charttype as ChartGauge).hasIntervals) {
				for (interval : (chart.charttype as ChartGauge).intervals) {
					if (interval instanceof ChartNumberInterval) {
						intervalValues = '''«intervalValues»«IF intervalValues.length>0»,«ENDIF»«(interval as ChartNumberInterval).numberIntervalValue»f'''
						if ((interval as ChartNumberInterval).numberRange instanceof ChartSegmentColor) {
							intervalColors = '''«intervalColors»«IF intervalColors.length>0»,«ENDIF»"«((interval as ChartNumberInterval).numberRange as ChartSegmentColor).rgb.toHex»"'''
						} 
					}
				}
			}
			body = '''
			«body»seriesDefaults.setRendererOptions(new MeterGaugeRenderer()
				.setShowTickLabels(«(chart.charttype as ChartGauge).hasTicks.toString»)
				«IF (chart.charttype as ChartGauge).labeled».setLabel("«(chart.charttype as ChartGauge).labelValue»")«ENDIF»
				«IF (chart.charttype as ChartGauge).hasIntervals».setIntervals(«intervalValues»)«ENDIF»
				«IF (chart.charttype as ChartGauge).hasIntervals».setIntervalColors(«intervalColors»)«ENDIF»);
			'''
		}
		else if (chart.charttype instanceof ChartBar) {
			body = '''
			«body»seriesDefaults.setFillToZero(true);
			seriesDefaults.setRendererOptions(new BarRenderer()
			    «IF axisSwitch».setBarDirection(BarDirections.HOTIZONTAL));«ELSE».setBarDirection(BarDirections.VERTICAL));«ENDIF»
			'''
			if ((chart.charttype as ChartBar).stacked) {
				body = '''
				«body»options.setStackSeries(true);
				'''
			}
			if ((chart.charttype as ChartBar).shadow) {
				body = '''
				«body»seriesDefaults.setShadow(true).setShadowAlpha(0.05f);
				'''			
			}
			if ((chart.charttype as ChartBar).animated) {
				body = '''
				«body»options.setAnimate(true);
				'''
			}
		}
		if((chart.eContainer as ChartPackage).hasColors) {
			body = '''
			«body»
			String[] seriesColors = «(chart.eContainer as ChartPackage).colors.stream.map['''"«it.rgb.toHex»"'''].collect(Collectors.joining(",", "{", "}"))»;
			options.setSeriesColors(seriesColors);
			'''
		} 
		if (hasAxis) {
			// axes
			body = '''
			«body»Axes axes = new Axes();
			'''
			if (chart.charttype instanceof ChartBubble) {
				// x
				body = '''
				«body»
				«data_axis.canvasAxisRenderer("x", "Tick", fontFamily)»
				«data_axis.canvasAxisRenderer("x", "Label", fontFamily)»
				if («data_axis.axis.name.literal»TitlesArray.size() > 0) {
					axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(0)»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(0)).setTickOptions(xTickRenderer).setLabelOptions(xLabelRenderer));
					axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(1)).setTickOptions(xTickRenderer).setLabelOptions(xLabelRenderer));
					axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»2).setLabel(«data_axis.axis.name.literal»TitlesArray.get(2)).setTickOptions(xTickRenderer).setLabelOptions(xLabelRenderer));
				}
				'''							
			}
			else {
				// x
				body = '''
				«body»
				«category_axis.canvasAxisRenderer("x", "Tick", fontFamily)»
				«category_axis.canvasAxisRenderer("x", "Label", fontFamily)»
				axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(0)»)
					.setRenderer(AxisRenderers.«category_axis.renderType.name().toString»)
					.setLabel(«category_axis.axis.name.literal»AxisLabel)
					.setTicks(«category_axis.axis.name.literal»Ticks)
					.setTickOptions(xTickRenderer)
					.setLabelOptions(xLabelRenderer));
				'''							
				// y .. y9
				body = '''
				«body»
				«data_axis.canvasAxisRenderer("y", "Tick", fontFamily)»
				axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»)
					.setPad(1.05f)
					.setTickOptions(yTickRenderer));
				'''
				// additional axes
				for (axisKey : multipleAxes.keySet) {
					if (!axisKey.equals("1")) {
						body = '''«body»«multipleAxes.get(axisKey)»'''
					}
				}
				if (multipleAxes.keySet.size > 0) {
					body = '''
					«body»LinearAxisRenderer linearAxisRenderer = new LinearAxisRenderer();
					linearAxisRenderer.setAlignTicks(true);
					AxesDefaults axesDefaults = new AxesDefaults()
						.setUseSeriesColor(true)
						.setBorderWidth(3)	
						.setRendererOptions(linearAxisRenderer);
					options.setAxesDefaults(axesDefaults);
					'''
				}
			}
			body = '''
			«body»options.setAxes(axes);
			'''
		}		
		// legend
		var hadLegend = false 
		for (element : chart.source.elements) {
			if (element instanceof ChartLegend) {
				var legend = element as ChartLegend
				if(legend.noLegend) {
					hadLegend = true
				} else {
					hadLegend = true
					body = '''
					«body»
					Legend legend = new Legend().setShow(«(legend !== null).booleanValue.toString»);
					legend.setPlacement(LegendPlacements.«legend.placement.name()»);
					'''
					if (legend.toggle) {
						body = '''
						«body»
						EnhancedLegendRenderer renderer = new EnhancedLegendRenderer();
						renderer.setSeriesToggle(SeriesToggles.«legend.toggleType.getName»);
						renderer.setSeriesToggleReplot(«legend.replot.booleanValue.toString»);
						legend.setRendererOptions(renderer);
						«IF legend.textColor !== null»legend.setTextColor("«legend.textColor.toHex»");«ENDIF»
						«IF legend.fontSize !== 0»legend.setFontSize("«legend.fontSize»pt");«ENDIF»
						«IF !fontFamily.equals(CanvasFontFamilyEnum.DEFAULT)»legend.setFontFamily("«fontFamily.literal»");«ENDIF»
						'''
					}
					body = '''
					«body»options.setLegend(legend);
					'''
				}
			}
		}
		if(!hadLegend) {
			body = '''
			«body»
			Legend legend = new Legend().setShow(true);
			legend.setPlacement(LegendPlacements.OUTSIDE_GRID);
			EnhancedLegendRenderer renderer = new EnhancedLegendRenderer();
			renderer.setSeriesToggle(SeriesToggles.FAST);
			renderer.setSeriesToggleReplot(true);
			legend.setRendererOptions(renderer);
			«IF !fontFamily.equals(CanvasFontFamilyEnum.DEFAULT)»legend.setFontFamily("«fontFamily.literal»");«ENDIF»
			options.setLegend(legend);
			'''
		}
			
		// highlighter
		var hadHighlighter = false
		for (element : chart.source.elements) {
			if (element instanceof ChartHighlighter) {
				hadHighlighter = true
				var highlighter = element as ChartHighlighter
				body = '''
				«body»
				Highlighter highlighter = new Highlighter().setShow(«(highlighter !== null).booleanValue.toString»);
				highlighter.setShowTooltip(true)
					.setTooltipAlwaysVisible(«highlighter.tooltipAlways.booleanValue.toString»)
					.setKeepTooltipInsideChart(«highlighter.insideChart.booleanValue.toString»)
					.setTooltipLocation(TooltipLocations.«highlighter.location.name()»)
					.setBringSeriesToFront(true)
					.setFadeTooltip(true)
					.setShowMarker(true);
				highlighter.setTooltipAxes(TooltipAxes.«axisPrefix»«postfix»);
				options.setHighlighter(highlighter);
				'''
			}
		}
		if(!hadHighlighter) {
				body = '''
				«body»
				Highlighter highlighter = new Highlighter().setShow(true);
				highlighter.setShowTooltip(true)
					.setTooltipAlwaysVisible(true)
					.setKeepTooltipInsideChart(true)
					.setTooltipLocation(TooltipLocations.NORTH_EAST)
					.setBringSeriesToFront(true)
					.setFadeTooltip(true)
					.setShowMarker(true);
				highlighter.setTooltipAxes(TooltipAxes.«axisPrefix»«postfix»);
				options.setHighlighter(highlighter);
				'''
		}
		
		// cursor
		if (chart.charttype instanceof ChartLine) {
			if ((chart.charttype as ChartLine).cursor) {
				body = '''
				«body»Cursor cursor = new Cursor()
					.setShow(true)
					.setZoom(«(chart.charttype as ChartLine).zoom.toString»)
					.setShowTooltip(«(chart.charttype as ChartLine).tooltip.toString»);
				options.setCursor(cursor);
				'''
			}
			if ((chart.charttype as ChartLine).animated) {
				body = '''
				«body»options.setAnimate(true);
				'''
			}
		}
		if (hasAxis) {
			// series
			body = '''
			«body»options.setSeries(«data_axis.axis.name.literal»Series);
			'''
		}
		body = '''
		«body»DCharts chart = new DCharts();
		chart.setDataSeries(dataSeries);
		chart.setOptions(options);
		chart.setEnableChartImageChangeEvent(true);
		'''
		body = '''
		«body»chart.setId("chart");
		chart.setImmediate(true);
		chart.show();
		charts.add(chart);
		'''
		if (chart.toolbar !== null && chart.toolbar.eContainer !== null) {
			body = '''
			«body»
			for (MToolBarElement element : toolbarClass.getToolBar().getChildren()) {
				Object widget = element.getWidget();
				if (widget instanceof Button) {
					List<String> tags = element.getTags();
					if (tags.contains(ChartActionEnum.CHART_ACTION_DOWNLOAD.getLiteral())) {
						FileDownloader fileDownloader = new FileDownloader(getChartResource(chart, layoutManager));
						fileDownloader.extend((Button) widget);
					}
				}
			}'''
		}
		body = '''
		«body»return chart;'''			
		return body
	}
	
	def canvasAxisRenderer(ChartAxis axis, String axisName, String typeName, CanvasFontFamilyEnum fontFamily)
		'''
		CanvasAxis«typeName»Renderer «axisName»«typeName»Renderer = new CanvasAxis«typeName»Renderer();
		«IF "Tick".equals(typeName)»
		«axisName»«typeName»Renderer.setTextColor(«IF axis.tickTextColor !== null»"«axis.tickTextColor.toHex»"«ELSE»"#202020"«ENDIF»);
		«IF axis.tickFontSize !== 0»«axisName»«typeName»Renderer.setFontSize("«axis.tickFontSize»pt");«ENDIF»
		«IF axis.tickAngle!=0»«axisName»«typeName»Renderer.setAngle(«axis.tickAngle»);«ENDIF»
		«ELSE»
		«axisName»«typeName»Renderer.setTextColor(«IF axis.labelTextColor !== null»"«axis.labelTextColor.toHex»"«ELSE»"#202020"«ENDIF»);
		«IF axis.labelFontSize !== 0»«axisName»«typeName»Renderer.setFontSize("«axis.labelFontSize»pt");«ENDIF»
		«IF axis.labelAngle!=0»«axisName»«typeName»Renderer.setAngle(«axis.labelAngle»);«ENDIF»
		«ENDIF»
		«IF !fontFamily.equals(CanvasFontFamilyEnum.DEFAULT)»
		«axisName»«typeName»Renderer.setEnableFontSupport(true);
		«axisName»«typeName»Renderer.setFontFamily("«fontFamily.literal»");
		«ENDIF»
		'''
	
	/**
	 * <p>helper method to convert a rgb string to a hex string.</p> 
	 *
	 */
	def String toHex(String rgb) {
		var colorHex = "#"
		for (color : rgb.split(",")) {
			var i = new Integer(color);
			colorHex = '''«colorHex»«String::format("%02x", i)»'''
		}
		return colorHex
	}
	
	/**
	 * <p>build the label series. Create multiple y-axes when the underlying datamart presents different scales.</p> 
	 *
	 * <p>scales are used to display line charts together for comparison reason but they are of different scalings.</p> 
	 */
	def String createLabelSeries(Chart chart, ChartAxis data_axis, HashMap<String,String>multipleAxes, String axisPrefix, boolean showMarker) {
		var body = ""
		var msrCnt = 0
		// find multiple axes defined in datamart
		if ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartCube) {
			for (axisOrSlicer : ((chart.source as ChartDatamart).datamartRef.source as DatamartCube).axisslicer) {
				if (axisOrSlicer instanceof DatamartCubeAxis) {
					for (element : (axisOrSlicer as DatamartCubeAxis).elements) {
						if (element instanceof DatamartDerivedMeasure) {
							if ((element as DatamartDerivedMeasure).scaled) {
								body = '''«body»«(element as DatamartDerivedMeasure).scale.createScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»'''
								msrCnt = msrCnt + 1 
							}
						}
						if (element instanceof DatamartMeasure) {
							if ((element as DatamartMeasure).scaled) {
								body = '''«body»«(element as DatamartMeasure).scale.createScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»'''
								msrCnt = msrCnt + 1 
							}
						}
					}
				}
			}
		}
		else if ((chart.source as ChartDatamart).datamartRef.source instanceof DatamartEntity) {
			var entity = ((chart.source as ChartDatamart).datamartRef.source as DatamartEntity)
			body = '''«body»«entity.entityScale(data_axis, multipleAxes, msrCnt, axisPrefix, showMarker)»'''
		}
		// no multiple axes defined in datamart
		if (multipleAxes.keySet.size == 0) {
			body = '''
			«body»	for (String title : «data_axis.axis.name.literal»TitlesArray) {
					«data_axis.axis.name.literal»Series.addSeries(new XYseries().setLabel(title).setShowMarker(«showMarker.toString»));
				}
			'''			
		}
		return body
	}
	
	/**
	 * <p>helper method for scales coming from datamart entities not from cubes.</p> 
	 *
	 */
	def String entityScale(DatamartEntity entity, ChartAxis data_axis, HashMap<String,String> multipleAxes, int msrCnt, String axisPrefix, boolean showMarker) {
		var counter = msrCnt
		var body = ""
		for (attribute : entity.attributes) {
			if (attribute instanceof DatamartAttribute) {
				if (attribute.scaled) {
					body = '''«body»«attribute.scale.createScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»'''
					counter = counter + 1
				}
			}
		}
		for (navigation : entity.navigations) {
			if (navigation instanceof DatamartMember) {
				body = '''«body»«(navigation as DatamartMember).datamartEntity.entityScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»'''
			}
			if (navigation instanceof DatamartOwner) {
				body = '''«body»«(navigation as DatamartOwner).datamartEntity.entityScale(data_axis, multipleAxes, counter, axisPrefix, showMarker)»'''
			}
		}
		return body
	}
	
	/**
	 * <p>helper method for scales.</p> 
	 *
	 */
	def String createScale(ValueScaleEnum scale, ChartAxis data_axis, HashMap<String,String> multipleAxes, int msrCnt, String axisPrefix, boolean showMarker) {
		var multipleBody = ""
		var body = ""
		var scaleOrdinal = scale.ordinal
		var scaleName = scale.toString
		body = '''
		«body»
			«data_axis.axis.name.literal»Series.addSeries(new XYseries(«axisPrefix.charAt(1)»axes.«axisPrefix.charAt(1)»«IF scaleOrdinal != 0»«(scaleOrdinal+1)»«ENDIF»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(«msrCnt»)).setShowMarker(«showMarker.toString»));
		'''
		if (!multipleAxes.keySet.contains(scaleName)) {
			// axis 1 is never expressed, but 2..9
			multipleBody = 
			'''axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»«IF scaleOrdinal != 0»«(scaleOrdinal+1)»«ENDIF»).setTickOptions(yTickRenderer«IF data_axis.tickAngle!=0».setAngle(«data_axis.tickAngle»)«ENDIF»));
			'''
			multipleAxes.put(scaleName, multipleBody)
		}
		return body
	}
	
	/**
	 * <p>helper method to get a attribute name or its alias if present of a entity's attribute object.</p> 
	 *
	 */
	def String getAttributeName(DatamartAttribute attribute) {
		return (attribute.attributeRef as LAttribute).name.toUpperCase 
	}
 
	/**
	 * <p>helper method to get a level name of a hierarchy's level object.</p> 
	 *
	 */
	def String getLevelName(CubeLevel level) {
		return level.name
	}
	
	def String filterChanged(Chart chart) {
		var body = ""
		body = '''
		«body»
		if(changedFilter != null) {
			MPerspective perspective = getContext().get(MPerspective.class);
			EventDispatcherEvent evnt = new EventDispatcherEvent(perspective, EventDispatcherCommand.SELECT, changedFilter.getName(), "«chart.name»");
			evnt.addData(changedFilter.getSelectedData());
			eventDispatcher.sendEvent(evnt);
		}
		renderData();
		'''
		return body
	}
	
	def Set<LEntity> findRequestedEntities(Chart chart) {
		var entities = new HashSet<LEntity>()
		entities.addAll((chart.source as ChartDatamart).datamartRef.findAllEntities())
		return entities
	}

	def String receiveEvent(Chart chart) {
		var body = ""
		body = '''
		«body»
		switch(event.getCommand()) {
			case SELECT:
				MPerspective perspective = getContext().get(MPerspective.class);
				if(event.getPerspective() == null || (perspective != null && event.getPerspective().equals(perspective))){
					if(!event.getSender().equals("«chart.fullyQualifiedName»")) {
						if(filterGenerator.selectItem(event, «chart.selectById.booleanValue»)) {
							renderData();
						}
					}
				}
				break;
			case SAVE:
			case DELETE:
				if(!event.getSender().equals("«chart.fullyQualifiedName»")) {
					«FOR e:findRequestedEntities(chart)»
					if(event.getTopic().equals("«e.fullyQualifiedName»")){
						datamartInstance.clearCache();
						renderData();
					}
					«ENDFOR»
				}
				break;
			case REFRESH:
				if(!event.getSender().equals("«chart.fullyQualifiedName»")) {
					«FOR e:findRequestedEntities(chart)»
					if(event.getTopic().equals("«e.fullyQualifiedName»")){
						datamartInstance.clearCache();
						renderData();
					}
					«ENDFOR»
				}
				/* must be activated if sure that the filter is to be refreshed
				if (filterGenerator != null) {
					filterGenerator.updateFilter();
				}*/
				break;
		}
		'''
		return body
	}
	
	def localeChanged(Chart chart)
		'''
		if(charts != null) {
			for(DCharts chart:charts) {
				chart.setLocale(locale);
				«IF chart.source.datamartRef.description && 
					chart.source.datamartRef.descriptionValue !== null»
					chart.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "«chart.source.datamartRef.descriptionValue»"));
«««					chart.setDownloadButtonCaption(dslMetadataService.translate(locale.toLanguageTag(), "download"));
				«ENDIF»
			}
		}
		if(layoutManager != null) {
			layoutManager.setLabelValue(dslMetadataService.translate(locale.toLanguageTag(), "«chart.name»"));
		}
		'''
		
	def chartResource(Chart chart)
		'''
		return new StreamResource(new StreamSource() {
			private static final long serialVersionUID = -6463786579404065302L;
			@Override
			public InputStream getStream() {
				try {
					ByteArrayOutputStream bos = new ByteArrayOutputStream();
					ImageIO.write(chart.getChartImage(), chart.getChartImageFormat()
							.getFormat(), bos);
					return new ByteArrayInputStream(bos.toByteArray());
				} catch (Exception e) {
					return new ByteArrayInputStream("".getBytes());
				}
			}
		}, layoutManager.getCaption() + chart.getChartImageFormat().getFormatExtension());
		'''

	def void createJsJavaComponent(Chart chart, IJvmDeclaredTypeAcceptor acceptor){
		val stateClassName = chart.createStateFilename
		var chart_cls = chart.toClass(chart.createfullyQualifiedChartFilename)
		// JavaScript-Java-State-Component creation
		var state_cls = chart.toClass(chart.createfullyQualifiedStateFilename)
		if (chart.charttype instanceof ChartTree){
			val ChartTree chartTree = chart.charttype as ChartTree
			// JavaScript-Java-Component creation
	   		acceptor.accept(chart_cls)
	   			.initializeLater([
	   				superTypes += _typeReferenceBuilder.typeRef(AbstractJavaScriptComponent)
					var JvmAnnotationReference jsAnnotationRef = chartTree.toAnnotation(typeof(JavaScript))
					var jsAnnotationList = newArrayList(
						"theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3.js",
						"theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3-scale-chromatic.js", 
						chart.createChartJsFilename
					)
					jsAnnotationRef.addStringValuesToAnnotation(jsAnnotationList)
					annotations += jsAnnotationRef
					if (chartTree.map){
	   					it.toTreeMapConstructor(chart)
					} else if (chartTree.collapsible) {
	   					it.toChartConstructor(chart)
					}
					it.toChartOperations(chart, stateClassName)
	   			])
			// JavaScript-Java-State-Component creation
	   		acceptor.accept(state_cls)
	   			.initializeLater([
	   				superTypes += _typeReferenceBuilder.typeRef(JavaScriptComponentState)
					if (chartTree.map){
						it.toTreeMapStateFields(chart)
					} else if (chartTree.collapsible) {
	   					it.toChartStateFields(chart)
					}
	   			])
		}
	}
	
	def void toChartOperations(JvmDeclaredType type, Chart chart, String stateClassName){
		// create view
   		type.members += chart.toMethod("getState", _typeReferenceBuilder.typeRef(stateClassName), [
   			body = [ append('''return («stateClassName») super.getState();''')]
   		])
		
	}

	def getD3StateVars()
		'''
		getState().jsonData = _jsonData;
		getState().htmlTagId=_htmlTagId;
		getState().panelWidth = new Integer(width).toString();
		getState().panelHeight = new Integer(height).toString();
		'''

	def JvmConstructor getChartConstructor(JvmDeclaredType type, Chart chart) {
		return chart.toConstructor([
			parameters += chart.toParameter("_htmlTagId", _typeReferenceBuilder.typeRef(String))
			parameters += chart.toParameter("_jsonData", _typeReferenceBuilder.typeRef(String))
			parameters += chart.toParameter("width", _typeReferenceBuilder.typeRef(int))
			parameters += chart.toParameter("height", _typeReferenceBuilder.typeRef(int))
			body = [ append(getD3StateVars)]
		])
	}
		
	def void toTreeMapConstructor(JvmDeclaredType type, Chart chart) {
		var JvmConstructor constructor = type.getChartConstructor(chart)
		constructor.parameters += chart.toParameter("dataColumns", _typeReferenceBuilder.typeRef(List, _typeReferenceBuilder.typeRef(String)))
		constructor.body = [ append(
		'''
		«d3StateVars»
		getState().dataColumnList = dataColumns;''')]
		type.members += constructor
	}
	
	def void toChartConstructor(JvmDeclaredType type, Chart chart) {
		var JvmConstructor constructor = type.getChartConstructor(chart)
		type.members += constructor
	}
	
	def void addStringValuesToAnnotation(JvmAnnotationReference annotationRef, ArrayList<String> annotationStringList){
		var JvmStringAnnotationValue value = typesFactory.createJvmStringAnnotationValue
		for (annotationString : annotationStringList){
			value.values += annotationString
		}
		annotationRef.explicitValues += value
	}
		
	def void toTreeMapStateFields(JvmDeclaredType type, Chart chart){
		type.toChartStateFields(chart)
		type.members += chart.toField("dataColumnList", _typeReferenceBuilder.typeRef(List, _typeReferenceBuilder.typeRef(String)))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''new ArrayList<String>()''')])]
	}

	def void toChartStateFields(JvmDeclaredType type, Chart chart){
		type.members += chart.toField("jsonData", _typeReferenceBuilder.typeRef(String))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])]
		type.members += chart.toField("htmlTagId", _typeReferenceBuilder.typeRef(String))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])]
		type.members += chart.toField("panelWidth", _typeReferenceBuilder.typeRef(String)) [
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])
		]
		type.members += chart.toField("panelHeight", _typeReferenceBuilder.typeRef(String)) [
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])
		]
		type.members += chart.toField("inputValue", _typeReferenceBuilder.typeRef(String))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])]
	}

	def createD3Chart(Chart chart)
		'''
		CellSetToD3JsonConverter jsonConverter = new CellSetToD3JsonConverter();
		return new «val d3ChartFileName = chart.createChartFilename»«d3ChartFileName»("«d3ChartFileName»", jsonConverter.getD3JsonString(cxCellSet, «IF chart.charttype instanceof ChartTree && (chart.charttype as ChartTree).collapsible»true«ELSE»false«ENDIF»), panelWidth, panelHeight«IF chart.treeMap», jsonConverter.getDataColumnNameList(cxCellSet)«ENDIF»);'''
}
