/**
 *                                                                            
 * 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.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.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.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.user.IUser
import org.eclipse.osbp.utils.vaadin.PropertyLookup
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.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmOperation
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.event.EventHandler
import org.slf4j.Logger

/**
 * <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 ChartDSLD3JavaComponentsCreator
	
	/**
	 * <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
	}

	/**
	 * <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(
				'''
				user.addUserLocaleListener(this);
				filterGenerator.addFilterChangeListener(this);
				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);
				eventDispatcher.removeEventReceiver(this);''')]
			])
   		// 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»''')]
			])
	}
	
	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);
		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>();
		'''
		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) {
			body = '''
			«body»// get the results
			final DerivedCellSet cellSet = datamartInstance.getResults(getTaskOperativeDtoClass(), getTaskInitialOperativeDtos());
			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'
		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)+" "+«inner_axis.axis.name.literal»TitlesArray.get(«inner_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);
				'''
			}
		}
		body = '''
		«body»
		String[] seriesColors = {"#98E958","#3090F0","#EC6464","#F9DD51","#24DCD4","#EC64A5","#685CB0","#FF7D42","#AA514D","#7FB053","#BBA85B","#247981"};
«««		String[] seriesColors = {"#0000FF","#FF0000","#00FF00","#FFFF00","#FF00FF","#00FFFF","#FF4500","#008000","#00BFFF","#FF69B4","#FFD700","#000080"};
		options.setSeriesColors(seriesColors);
		'''
		if (hasAxis) {
			// axes
			body = '''
			«body»Axes axes = new Axes();
			'''
			if (chart.charttype instanceof ChartBubble) {
				// x
				body = '''
				«body»CanvasAxisTickRenderer axisTickRenderer = new CanvasAxisTickRenderer();
				axisTickRenderer.setTextColor("#202020");
				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(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»));
					axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»).setLabel(«data_axis.axis.name.literal»TitlesArray.get(1)).setTickOptions(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»));
					axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»2).setLabel(«data_axis.axis.name.literal»TitlesArray.get(2)).setTickOptions(axisTickRenderer«IF category_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»));
				}
				'''							
			}
			else {
				// x
				body = '''
				«body»CanvasAxisTickRenderer tickRenderer = new CanvasAxisTickRenderer();
				tickRenderer.setTextColor("#202020");
				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(tickRenderer«IF category_axis.angle!=0».setAngle(«category_axis.angle»)«ENDIF»));
				'''							
				// y .. y9
				body = '''
				«body»CanvasAxisTickRenderer axisTickRenderer = new CanvasAxisTickRenderer();
				axisTickRenderer.setTextColor("#202020");
				axes.addAxis(new XYaxis(XYaxes.«axisPrefix.charAt(1)»)
					.setPad(1.05f)
					.setTickOptions(axisTickRenderer«IF data_axis.angle!=0».setAngle(«data_axis.angle»)«ENDIF»));
				'''
				// 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
		for (element : chart.source.elements) {
			if (element instanceof ChartLegend) {
				var legend = element as ChartLegend
				body = '''
				«body»Legend legend = new Legend().setShow(«(legend !== null).booleanValue.toString»);
				'''
				body = '''
				«body»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);
					'''
				}
				body = '''
				«body»options.setLegend(legend);
				'''
			}
		}
			
		// highlighter
		for (element : chart.source.elements) {
			if (element instanceof ChartHighlighter) {
				var highlighter = element as ChartHighlighter
				body = '''
				«body»Highlighter highlighter = new Highlighter().setShow(«(highlighter !== null).booleanValue.toString»);
				'''
				body = '''
				«body»highlighter.setShowTooltip(true)
				.setTooltipAlwaysVisible(«highlighter.tooltipAlways.booleanValue.toString»)
				.setKeepTooltipInsideChart(«highlighter.insideChart.booleanValue.toString»)
				.setTooltipLocation(TooltipLocations.«highlighter.location.name()»)
				.setBringSeriesToFront(true)
				.setFadeTooltip(true)
				.setShowMarker(true);
				'''
				body = '''
				«body»highlighter.setTooltipAxes(TooltipAxes.«axisPrefix»«postfix»);
				'''
				body = '''
				«body»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.setEnableDownload(true);
		chart.setDownloadButtonCaption(dslMetadataService.translate(user.getLocale().toLanguageTag(), "download"));
		chart.setDownloadFilename("«chart.name»");
		chart.setDownloadButtonLocation(DownloadButtonLocation.TOP_RIGHT);
		'''
		body = '''
		«body»chart.setId("chart");
		chart.setImmediate(true);
		chart.show();
		charts.add(chart);
		return chart;'''			
		return body
	}
	
	/**
	 * <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(axisTickRenderer«IF data_axis.angle!=0».setAngle(«data_axis.angle»)«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) {
			EventDispatcherEvent evnt = new EventDispatcherEvent(EventDispatcherCommand.SELECT, changedFilter.getName(), "«chart.name»");
			PerspectiveImpl perspective = (PerspectiveImpl) getContext().get(MPerspective.class);
			if(perspective != null){evnt.setPerspective(perspective);}
			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:
				PerspectiveImpl perspective = (PerspectiveImpl) 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»
				}
				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»"));
		}
		'''	
}
