/**
 *                                                                            
 *  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.annotations.JavaScript
import com.vaadin.shared.ui.JavaScriptComponentState
import com.vaadin.ui.AbstractJavaScriptComponent
import org.eclipse.osbp.xtext.chart.Chart
import org.eclipse.osbp.xtext.chart.ChartTree
import java.util.ArrayList
import java.util.List
import javax.inject.Inject
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.JvmStringAnnotationValue
import org.eclipse.xtext.common.types.JvmVisibility
import org.eclipse.xtext.common.types.TypesFactory
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder

class ChartDSLD3JavaComponentsCreator {
		
		@Inject extension JvmTypesBuilder
		@Inject extension D3JsJavaUtil
		@Inject
		private TypesFactory typesFactory
		
		
		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 += chart.newTypeRef(typeof(AbstractJavaScriptComponent))
						var JvmAnnotationReference jsAnnotationRef = chartTree.toAnnotation(typeof(JavaScript))
						var jsAnnotationList = newArrayList("theme://plugin/org.eclipse.osbp.utils.js/org/eclipse/osbp/utils/js/d3.min.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 += chart.newTypeRef(typeof(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", chart.newTypeRef(stateClassName), [
   			body = [ append('''return («stateClassName») super.getState();''')]
   		])
		
	}

	def getD3StateVars()
		'''
		getState().jsonData = _jsonData;
		getState().htmlTagId=_htmlTagId;'''

	def JvmConstructor getChartConstructor(JvmDeclaredType type, Chart chart) {
		return chart.toConstructor([
			parameters += chart.toParameter("_htmlTagId", chart.newTypeRef(typeof(String)))
			parameters += chart.toParameter("_jsonData", chart.newTypeRef(typeof(String)))
			body = [ append(getD3StateVars)]
		])
	}
		
	def void toTreeMapConstructor(JvmDeclaredType type, Chart chart) {
		var JvmConstructor constructor = type.getChartConstructor(chart)
		constructor.parameters += chart.toParameter("dataColumns", chart.newTypeRef(typeof(List), chart.newTypeRef(typeof(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", chart.newTypeRef(List, chart.newTypeRef(String)))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''new ArrayList<String>()''')])]
	}

	def void toChartStateFields(JvmDeclaredType type, Chart chart){
		type.members += chart.toField("jsonData", chart.newTypeRef(String))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])]
		type.members += chart.toField("htmlTagId", chart.newTypeRef(String))[
			visibility = JvmVisibility::PUBLIC
			setInitializer([append('''""''')])]
		type.members += chart.toField("inputValue", chart.newTypeRef(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.treeMap», jsonConverter.getDataColumnNameList(cxCellSet)«ENDIF»);'''
}
