/**
 *                                                                            
 *  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.data.Property.ValueChangeListener
import com.vaadin.server.Page
import com.vaadin.server.Page.Styles
import com.vaadin.ui.HorizontalLayout
import com.vaadin.ui.JavaScriptFunction
import com.vaadin.ui.Label
import com.vaadin.ui.Panel
import com.vaadin.ui.TabSheet
import com.vaadin.ui.UI
import elemental.json.JsonArray
import elemental.json.JsonException
import elemental.json.JsonObject
import java.util.ArrayList
import java.util.Collection
import java.util.Date
import java.util.HashMap
import java.util.List
import java.util.Locale
import java.util.Map
import java.util.ResourceBundle
import java.util.concurrent.Executors
import javax.inject.Inject
import mondrian.olap.Member.MemberType
import org.dussan.vaadin.dcharts.DCharts
import org.dussan.vaadin.dcharts.DownloadButtonLocation
import org.dussan.vaadin.dcharts.base.elements.Trendline
import org.dussan.vaadin.dcharts.base.elements.XYaxis
import org.dussan.vaadin.dcharts.base.elements.XYseries
import org.dussan.vaadin.dcharts.data.DataSeries
import org.dussan.vaadin.dcharts.data.Ticks
import org.dussan.vaadin.dcharts.metadata.LegendPlacements
import org.dussan.vaadin.dcharts.metadata.PyramidSides
import org.dussan.vaadin.dcharts.metadata.SeriesToggles
import org.dussan.vaadin.dcharts.metadata.TooltipAxes
import org.dussan.vaadin.dcharts.metadata.XYaxes
import org.dussan.vaadin.dcharts.metadata.Xaxes
import org.dussan.vaadin.dcharts.metadata.Yaxes
import org.dussan.vaadin.dcharts.metadata.directions.BarDirections
import org.dussan.vaadin.dcharts.metadata.locations.TooltipLocations
import org.dussan.vaadin.dcharts.metadata.renderers.AxisRenderers
import org.dussan.vaadin.dcharts.metadata.renderers.SeriesRenderers
import org.dussan.vaadin.dcharts.options.Axes
import org.dussan.vaadin.dcharts.options.AxesDefaults
import org.dussan.vaadin.dcharts.options.Cursor
import org.dussan.vaadin.dcharts.options.Highlighter
import org.dussan.vaadin.dcharts.options.Legend
import org.dussan.vaadin.dcharts.options.Options
import org.dussan.vaadin.dcharts.options.Series
import org.dussan.vaadin.dcharts.options.SeriesDefaults
import org.dussan.vaadin.dcharts.options.Title
import org.dussan.vaadin.dcharts.renderers.axis.LinearAxisRenderer
import org.dussan.vaadin.dcharts.renderers.legend.EnhancedLegendRenderer
import org.dussan.vaadin.dcharts.renderers.series.BarRenderer
import org.dussan.vaadin.dcharts.renderers.series.BubbleRenderer
import org.dussan.vaadin.dcharts.renderers.series.DonutRenderer
import org.dussan.vaadin.dcharts.renderers.series.MeterGaugeRenderer
import org.dussan.vaadin.dcharts.renderers.series.PieRenderer
import org.dussan.vaadin.dcharts.renderers.series.PyramidRenderer
import org.dussan.vaadin.dcharts.renderers.tick.AxisTickRenderer
import org.dussan.vaadin.dcharts.renderers.tick.CanvasAxisTickRenderer
import org.eclipse.e4.core.di.extensions.EventUtils
import org.eclipse.e4.ui.model.application.ui.MUIElement
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack
import org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl
import org.eclipse.emf.common.notify.Notification
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.osbp.eventbroker.EventBrokerMsg
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent
import org.eclipse.osbp.ui.api.datamart.DatamartFilter
import org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator
import org.eclipse.osbp.utils.vaadin.ViewLayoutManager
import org.eclipse.osbp.xtext.basic.generator.BasicDslGeneratorUtils
import org.eclipse.osbp.xtext.chart.Chart
import org.eclipse.osbp.xtext.chart.ChartModel
import org.eclipse.osbp.xtext.chart.ChartTree
import org.eclipse.osbp.xtext.datamart.common.DatamartFilterGenerator
import org.eclipse.osbp.xtext.datamart.common.olap.CellSetToD3JsonConverter
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedAxis
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCell
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedHierarchy
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedLevel
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedMember
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedPosition
import org.eclipse.osbp.xtext.i18n.I18NModelGenerator
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.compiler.GeneratorConfig
import org.eclipse.xtext.xbase.compiler.ImportManager
import org.osgi.service.event.Event
import org.osgi.service.event.EventHandler

class ChartModelGenerator extends I18NModelGenerator {
	@Inject extension IQualifiedNameProvider
	@Inject extension D3JsJavaUtil
	@Inject extension BasicDslGeneratorUtils
	
	override createAppendable(EObject context, ImportManager importManager, GeneratorConfig config) {
		// required to initialize the needed builder to avoid deprecated methods
		builder = context.eResource
		// ---------
		importManager.addImportFor(_typeReferenceBuilder.typeRef(HashMap, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(String)).type)
		importManager.addImportFor(_typeReferenceBuilder.typeRef(Map, _typeReferenceBuilder.typeRef(String), _typeReferenceBuilder.typeRef(String)).type)
		importManager.addImportFor(_typeReferenceBuilder.typeRef(Collection, _typeReferenceBuilder.typeRef(String)).type)
		addImportFor(importManager, _typeReferenceBuilder
			, ValueChangeListener
			, DCharts
			, Label
			, List
			, ArrayList
			, Page
			, Styles
			, DerivedAxis
			, DerivedCell
			, DerivedPosition
			, DerivedMember
			, HorizontalLayout
			, TabSheet
			, Series
			, XYseries
			, Ticks
			, DataSeries
			, SeriesDefaults
			, SeriesRenderers
			, CanvasAxisTickRenderer
			, DonutRenderer
			, PieRenderer
			, BubbleRenderer
			, BarRenderer
			, BarDirections
			, MeterGaugeRenderer
			, PyramidRenderer
			, PyramidSides
			, Trendline
			, Cursor
			, Legend
			, LegendPlacements
			, EnhancedLegendRenderer
			, SeriesToggles
			, Highlighter
			, Title
			, TooltipLocations
			, TooltipAxes
			, Axes
			, XYaxes
			, XYaxis
			, Xaxes
			, Yaxes
			, AxisTickRenderer
			, AxisRenderers
			, LinearAxisRenderer
			, AxesDefaults
			, DownloadButtonLocation
			, Options
			, DerivedHierarchy
			, DerivedLevel
			, CellSetToD3JsonConverter
			, Date
			, JavaScriptFunction
			, JsonArray
			, JsonObject
			, JsonException
			, EventHandler
			, Event
			, EventUtils
			, EventBrokerMsg
			, Executors
			, Notification
			, EObject
			, UIElementImpl
			, UiPackageImpl
			, MUIElement
			, MPartStack
			, UI
			, ResourceBundle
			, Locale
			, DatamartFilterGenerator
			, ViewLayoutManager
			, IDatamartFilterGenerator.FilterChangeListener
			, EventDispatcherEvent
			, EventDispatcherEvent.EventDispatcherDataTag
			, EventDispatcherEvent.EventDispatcherCommand
			, DatamartFilter
			, MemberType
			, Panel
			, MPerspective
		)
		super.createAppendable(context, importManager, config)
	}
	
	override void doGenerate(Resource input, IFileSystemAccess fsa) {
		super.addTranslatables("download")
		super.doGenerate(input, fsa )
		for (obj : input.contents) {
			obj.internalDoGenerate(fsa)
		}
	}
	
	def dispatch void internalDoGenerate(ChartModel chartModel, IFileSystemAccess fsa) { 
   		for (pkg : chartModel.packages) {
   			for (chart : pkg.charts) {
   				if ((chart.charttype instanceof ChartTree)) {
   					var pckgName = pkg.fullyQualifiedName.toString
//					println(pckgName)
					var strBuilder = new StringBuilder
					var pckgNamePath = pckgName.replaceAll("\\.","/")
//					var propOutputFile = '''«pckgNamePath»/«chart.createChartJsFilename(chartTree)»'''
					var propOutputFile = '''«pckgNamePath»/«chart.createChartJsFilename»'''
//					println("********************* Property-Output *********************")
					chart.generateJsFile(strBuilder)
					if (strBuilder.length > 0){
						fsa.generateFile(propOutputFile, strBuilder)
//						println(strBuilder.toString)
					}
   				}
   			}
   		}
   	}
	
	def void generateJsFile(Chart chart,StringBuilder strBuilder){
		var chartFilePath = chart.createfullyQualifiedChartFilename.replaceAll("\\.","_")
   		if (chart.charttype instanceof ChartTree){
   			var chartTree = chart.charttype as ChartTree
			if (chartTree.map){
				strBuilder.generateTreeMapJsFile(chartFilePath)
			} else if (chartTree.collapsible) {
				strBuilder.generateCollTreeJsFile(chartFilePath)
			}
   		}
	}
	
	def void generateTreeMapJsFile(StringBuilder strBuilder, String chartJavaFileName){
		strBuilder.append('''«chartJavaFileName» = function() {
	
		var margin = {
		    top: 40,
		    right: 10,
		    bottom: 10,
		    left: 10
		},
		    width = 960 - margin.left - margin.right,
		    height = 500 - margin.top - margin.bottom;

		var color = d3.scale.category20c();

		function position() {
		    this.style("left", function (d) {
		        return d.x + "px";
		    })
		        .style("top", function (d) {
		            return d.y + "px";
		        })
		        .style("width", function (d) {
		            return Math.max(0, d.dx - 1) + "px";
		        })
		        .style("height", function (d) {
		            return Math.max(0, d.dy - 1) + "px";
		        });
		}

		var cxD3TreeMapJsHTMLRootComponent = this.getElement();
		var cxD3TreeMapJsComponentHtmlTagId = this.getState().htmlTagId;
		var checked = "";
		var connector = this;
		var dataColumn = "";

		var preValueLabel = "";

		for (var i=0;i < this.getState().dataColumnList.length;i++) {
			if (i == 0){
				checked = " checked";
				preValueLabel = this.getState().dataColumnList[0];
			} else {
				checked = "";
			}
			dataColumn = dataColumn + "\t<label><input id=\""+this.getState().htmlTagId+"_input\" type=\"radio\" name=\"mode\" value=\""+ this.getState().dataColumnList[i] + "\"" + checked + "> "+ this.getState().dataColumnList[i] + "</label>\n";
		}
		var treemap = d3.layout.treemap()
		.size([width, height])
		.sticky(true)
		.value(function (d) {
			return eval("d." + preValueLabel);
		});
//		alert("dataColumn: " + dataColumn);
		cxD3TreeMapJsHTMLRootComponent.innerHTML = 	"<form>\n" +
						dataColumn +
						"</form>\n" +
						"<div id=\""+this.getState().htmlTagId+"_div\">" + "</div>";
			var cxD3TreeMapJsHTMLRootComponentSelection = d3.select(cxD3TreeMapJsHTMLRootComponent).select("#"+this.getState().htmlTagId+"_div");
//			alert("selection: " + selection);
			var cxD3TreeMapJsHTMLRootComponentDiv = cxD3TreeMapJsHTMLRootComponentSelection.append("div")
							    .style("position", "relative")
								.style("width", (width + margin.left + margin.right) + "px")
								.style("height", (height + margin.top + margin.bottom) + "px")
							    .style("left", margin.left + "px")
							    .style("top", margin.top + "px");
			
			jsonTreeMapFunction = function(jsonObj) {
				var node = cxD3TreeMapJsHTMLRootComponentDiv.datum(jsonObj).selectAll(".node")
				.data(treemap.nodes)
				.enter().append("div")
				.attr("class", "node")
				.attr("title", function(d) { return d.children ? "" : d.tooltipName + "\n" + preValueLabel + ": " + eval("d." + preValueLabel); })
				.call(position)
				.style("background", function(d) { return d.children ? color(d.name) : null; })
//					      .style("background", function(d) { return d.children ? d3.rgb("red") : null; })
				.text(function(d) { return d.children ? null : d.name; });
				
				d3.select(cxD3TreeMapJsHTMLRootComponent).selectAll("#"+cxD3TreeMapJsComponentHtmlTagId+"_input").on("change", function change() {
					var valueLabel = this.value;
//				    alert("valueOut: " + valueOut);
				    var value = this.value === "count"
				        ? function() { return 1; }
				        : function (d) { return eval("d." + valueLabel); };
		//				        : function (d) { return d.size; };
					  
					    node.data(treemap.value(value).nodes)
					      	.attr("title", function(d) { return d.children ? "" : d.tooltipName + "\n" + valueLabel + ": " + eval("d." + valueLabel); })
					      	.transition()
					        .duration(1500)
					        .call(position);
					  });
			}
			
			var jsonString = this.getState().jsonData;
			jsonTreeMapFunction(JSON.parse(jsonString));
	}
		''')
	}
	
	def void generateCollTreeJsFile(StringBuilder strBuilder, String chartJavaFileName){
		strBuilder.append('''«chartJavaFileName» = function() {
	
	var margin = {top: 20, right: 120, bottom: 20, left: 120},
    width = 1460 - margin.right - margin.left,
    height = 1000 - margin.top - margin.bottom;
    
	var i = 0,
	    duration = 750,
	    cxD3TreeJsComponent_jsonRoot;
	
	var tree = d3.layout.tree()
	    .size([height, width]);
	
	var diagonal = d3.svg.diagonal()
	    .projection(function(d) { return [d.y, d.x]; });
	
	var cxD3TreeJsHTMLRootComponent = this.getElement();
	cxD3TreeJsHTMLRootComponent.innerHTML = 	
					"<label><input id=\""+this.getState().htmlTagId+"_input\" type=\"radio\" name=\"mode\" value=\"expand\">Expand</label>\n" +
					"<label><input id=\""+this.getState().htmlTagId+"_input\" type=\"radio\" name=\"mode\" value=\"collapse\" checked>Collapse</label>\n" +
					"<div id=\""+this.getState().htmlTagId+"_div\">" + "</div>";	
	
	var cxD3TreeJsHTMLRootComponentSelection = d3.select(cxD3TreeJsHTMLRootComponent).select("#"+this.getState().htmlTagId+"_div");
	
	var cxD3TreeJsHTMLRootComponentSvg = cxD3TreeJsHTMLRootComponentSelection.append("svg")
	    .attr("width", width + margin.right + margin.left)
	    .attr("height", height + margin.top + margin.bottom)
	  .append("g")
	    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

	function collapse(d) {
		if (d.children) {
			d._children = d.children;
			d._children.forEach(collapse);
			d.children = null;
		}
	}
	
	function expand(d) {
		if (d._children) {
			d.children = d._children;
			d.children.forEach(expand);
			d._children = null;
		}
	}
	
	jsonTreeFunction = function(jsonData) {
		cxD3TreeJsComponent_jsonRoot = jsonData;
		cxD3TreeJsComponent_jsonRoot.x0 = height / 2;
		cxD3TreeJsComponent_jsonRoot.y0 = 0;
		
		
		  cxD3TreeJsComponent_jsonRoot.children.forEach(collapse);
		  update(cxD3TreeJsComponent_jsonRoot);
		}
	
	jsonTreeFunction(JSON.parse(this.getState().jsonData));

	d3.select(cxD3TreeJsHTMLRootComponent).select(self.frameElement).style("height", "800px");
	
	d3.select(cxD3TreeJsHTMLRootComponent).selectAll("#"+this.getState().htmlTagId+"_input").on("change", function change() {
//		alert("this.value = " + this.value);
	    if (this.value === "expand"){
	    	cxD3TreeJsComponent_jsonRoot.children.forEach(expand);
	    } else {
	    	cxD3TreeJsComponent_jsonRoot.children.forEach(collapse);
	    }
	    update(cxD3TreeJsComponent_jsonRoot);
	});

	function update(source) {

	  // Compute the new tree layout.
	  var nodes = tree.nodes(cxD3TreeJsComponent_jsonRoot).reverse(),
	      links = tree.links(nodes);

	  // Normalize for fixed-depth.
	  nodes.forEach(function(d) { d.y = d.depth * 180; });

	  // Update the nodes€¦
	  var node = cxD3TreeJsHTMLRootComponentSvg.selectAll("g.node")
	      .data(nodes, function(d) { return d.id || (d.id = ++i); });

	  // Enter any new nodes at the parent's previous position.
	  var nodeEnter = node.enter().append("g")
	      .attr("class", "node")
	      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
	      .on("click", click);

	  nodeEnter.append("circle")
	      .attr("r", 1e-6)
	      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

	  nodeEnter.append("text")
	      .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
	      .attr("dy", ".35em")
	      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
	      .text(function(d) { return d.name; })
	      .style("fill-opacity", 1e-6);

	  // Transition nodes to their new position.
	  var nodeUpdate = node.transition()
	      .duration(duration)
	      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

	  nodeUpdate.select("circle")
	      .attr("r", 4.5)
	      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

	  nodeUpdate.select("text")
	      .style("fill-opacity", 1);

	  // Transition exiting nodes to the parent's new position.
	  var nodeExit = node.exit().transition()
	      .duration(duration)
	      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
	      .remove();

	  nodeExit.select("circle")
	      .attr("r", 1e-6);

	  nodeExit.select("text")
	      .style("fill-opacity", 1e-6);

	  // Update the links€¦
	  var link = cxD3TreeJsHTMLRootComponentSvg.selectAll("path.link")
	      .data(links, function(d) { return d.target.id; });

	  // Enter any new links at the parent's previous position.
	  link.enter().insert("path", "g")
	      .attr("class", "link")
	      .attr("d", function(d) {
	        var o = {x: source.x0, y: source.y0};
	        return diagonal({source: o, target: o});
	      });

	  // Transition links to their new position.
	  link.transition()
	      .duration(duration)
	      .attr("d", diagonal);

	  // Transition exiting nodes to the parent's new position.
	  link.exit().transition()
	      .duration(duration)
	      .attr("d", function(d) {
	        var o = {x: source.x, y: source.y};
	        return diagonal({source: o, target: o});
	      })
	      .remove();

	  // Stash the old positions for transition.
	  nodes.forEach(function(d) {
	    d.x0 = d.x;
	    d.y0 = d.y;
	  });
	}

	// Toggle children on click.
	function click(d) {
	  if (d.children) {
	    d._children = d.children;
	    d.children = null;
	  } else {
	    d.children = d._children;
	    d._children = null;
	  }
	  update(d);
	}

}
''')
	}
		
}
