/**
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 */
package org.eclipse.osbp.xtext.chart.jvmmodel;

import com.vaadin.annotations.JavaScript;
import com.vaadin.shared.ui.JavaScriptComponentState;
import com.vaadin.ui.AbstractJavaScriptComponent;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.emf.common.util.EList;
import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartOption;
import org.eclipse.osbp.xtext.chart.ChartTree;
import org.eclipse.osbp.xtext.chart.jvmmodel.D3JsJavaUtil;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmAnnotationValue;
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.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmStringAnnotationValue;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.common.types.TypesFactory;
import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable;
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor;
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

@SuppressWarnings("all")
public class ChartDSLD3JavaComponentsCreator {
  @Inject
  @Extension
  private JvmTypesBuilder _jvmTypesBuilder;
  
  @Inject
  @Extension
  private D3JsJavaUtil _d3JsJavaUtil;
  
  @Inject
  private TypesFactory typesFactory;
  
  public void createJsJavaComponent(final Chart chart, final IJvmDeclaredTypeAcceptor acceptor) {
    final String stateClassName = this._d3JsJavaUtil.createStateFilename(chart);
    JvmGenericType chart_cls = this._jvmTypesBuilder.toClass(chart, this._d3JsJavaUtil.createfullyQualifiedChartFilename(chart));
    JvmGenericType state_cls = this._jvmTypesBuilder.toClass(chart, this._d3JsJavaUtil.createfullyQualifiedStateFilename(chart));
    ChartOption _charttype = chart.getCharttype();
    if ((_charttype instanceof ChartTree)) {
      ChartOption _charttype_1 = chart.getCharttype();
      final ChartTree chartTree = ((ChartTree) _charttype_1);
      final Procedure1<JvmGenericType> _function = (JvmGenericType it) -> {
        EList<JvmTypeReference> _superTypes = it.getSuperTypes();
        JvmTypeReference _newTypeRef = this._jvmTypesBuilder.newTypeRef(chart, AbstractJavaScriptComponent.class);
        this._jvmTypesBuilder.<JvmTypeReference>operator_add(_superTypes, _newTypeRef);
        JvmAnnotationReference jsAnnotationRef = this._jvmTypesBuilder.toAnnotation(chartTree, JavaScript.class);
        ArrayList<String> jsAnnotationList = CollectionLiterals.<String>newArrayList("d3.min.js", this._d3JsJavaUtil.createChartJsFilename(chart));
        this.addStringValuesToAnnotation(jsAnnotationRef, jsAnnotationList);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, jsAnnotationRef);
        boolean _isMap = chartTree.isMap();
        if (_isMap) {
          this.toTreeMapConstructor(it, chart);
        } else {
          boolean _isCollapsible = chartTree.isCollapsible();
          if (_isCollapsible) {
            this.toChartConstructor(it, chart);
          }
        }
        this.toChartOperations(it, chart, stateClassName);
      };
      acceptor.<JvmGenericType>accept(chart_cls).initializeLater(_function);
      final Procedure1<JvmGenericType> _function_1 = (JvmGenericType it) -> {
        EList<JvmTypeReference> _superTypes = it.getSuperTypes();
        JvmTypeReference _newTypeRef = this._jvmTypesBuilder.newTypeRef(chart, JavaScriptComponentState.class);
        this._jvmTypesBuilder.<JvmTypeReference>operator_add(_superTypes, _newTypeRef);
        boolean _isMap = chartTree.isMap();
        if (_isMap) {
          this.toTreeMapStateFields(it, chart);
        } else {
          boolean _isCollapsible = chartTree.isCollapsible();
          if (_isCollapsible) {
            this.toChartStateFields(it, chart);
          }
        }
      };
      acceptor.<JvmGenericType>accept(state_cls).initializeLater(_function_1);
    }
  }
  
  public void toChartOperations(final JvmDeclaredType type, final Chart chart, final String stateClassName) {
    EList<JvmMember> _members = type.getMembers();
    final Procedure1<JvmOperation> _function = (JvmOperation it) -> {
      final Procedure1<ITreeAppendable> _function_1 = (ITreeAppendable it_1) -> {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("return (");
        _builder.append(stateClassName);
        _builder.append(") super.getState();");
        it_1.append(_builder);
      };
      this._jvmTypesBuilder.setBody(it, _function_1);
    };
    JvmOperation _method = this._jvmTypesBuilder.toMethod(chart, "getState", this._jvmTypesBuilder.newTypeRef(chart, stateClassName), _function);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members, _method);
  }
  
  public CharSequence getD3StateVars() {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("getState().jsonData = _jsonData;");
    _builder.newLine();
    _builder.append("getState().htmlTagId=_htmlTagId;");
    return _builder;
  }
  
  public JvmConstructor getChartConstructor(final JvmDeclaredType type, final Chart chart) {
    final Procedure1<JvmConstructor> _function = (JvmConstructor it) -> {
      EList<JvmFormalParameter> _parameters = it.getParameters();
      JvmFormalParameter _parameter = this._jvmTypesBuilder.toParameter(chart, "_htmlTagId", this._jvmTypesBuilder.newTypeRef(chart, String.class));
      this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
      EList<JvmFormalParameter> _parameters_1 = it.getParameters();
      JvmFormalParameter _parameter_1 = this._jvmTypesBuilder.toParameter(chart, "_jsonData", this._jvmTypesBuilder.newTypeRef(chart, String.class));
      this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters_1, _parameter_1);
      final Procedure1<ITreeAppendable> _function_1 = (ITreeAppendable it_1) -> {
        it_1.append(this.getD3StateVars());
      };
      this._jvmTypesBuilder.setBody(it, _function_1);
    };
    return this._jvmTypesBuilder.toConstructor(chart, _function);
  }
  
  public void toTreeMapConstructor(final JvmDeclaredType type, final Chart chart) {
    JvmConstructor constructor = this.getChartConstructor(type, chart);
    EList<JvmFormalParameter> _parameters = constructor.getParameters();
    JvmFormalParameter _parameter = this._jvmTypesBuilder.toParameter(chart, "dataColumns", this._jvmTypesBuilder.newTypeRef(chart, List.class, this._jvmTypesBuilder.newTypeRef(chart, String.class)));
    this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
    final Procedure1<ITreeAppendable> _function = (ITreeAppendable it) -> {
      StringConcatenation _builder = new StringConcatenation();
      CharSequence _d3StateVars = this.getD3StateVars();
      _builder.append(_d3StateVars);
      _builder.newLineIfNotEmpty();
      _builder.append("getState().dataColumnList = dataColumns;");
      it.append(_builder);
    };
    this._jvmTypesBuilder.setBody(constructor, _function);
    EList<JvmMember> _members = type.getMembers();
    this._jvmTypesBuilder.<JvmConstructor>operator_add(_members, constructor);
  }
  
  public void toChartConstructor(final JvmDeclaredType type, final Chart chart) {
    JvmConstructor constructor = this.getChartConstructor(type, chart);
    EList<JvmMember> _members = type.getMembers();
    this._jvmTypesBuilder.<JvmConstructor>operator_add(_members, constructor);
  }
  
  public void addStringValuesToAnnotation(final JvmAnnotationReference annotationRef, final ArrayList<String> annotationStringList) {
    JvmStringAnnotationValue value = this.typesFactory.createJvmStringAnnotationValue();
    for (final String annotationString : annotationStringList) {
      EList<String> _values = value.getValues();
      this._jvmTypesBuilder.<String>operator_add(_values, annotationString);
    }
    EList<JvmAnnotationValue> _explicitValues = annotationRef.getExplicitValues();
    this._jvmTypesBuilder.<JvmStringAnnotationValue>operator_add(_explicitValues, value);
  }
  
  public void toTreeMapStateFields(final JvmDeclaredType type, final Chart chart) {
    this.toChartStateFields(type, chart);
    EList<JvmMember> _members = type.getMembers();
    final Procedure1<JvmField> _function = (JvmField it) -> {
      it.setVisibility(JvmVisibility.PUBLIC);
      final Procedure1<ITreeAppendable> _function_1 = (ITreeAppendable it_1) -> {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("new ArrayList<String>()");
        it_1.append(_builder);
      };
      this._jvmTypesBuilder.setInitializer(it, _function_1);
    };
    JvmField _field = this._jvmTypesBuilder.toField(chart, "dataColumnList", this._jvmTypesBuilder.newTypeRef(chart, List.class, this._jvmTypesBuilder.newTypeRef(chart, String.class)), _function);
    this._jvmTypesBuilder.<JvmField>operator_add(_members, _field);
  }
  
  public void toChartStateFields(final JvmDeclaredType type, final Chart chart) {
    EList<JvmMember> _members = type.getMembers();
    final Procedure1<JvmField> _function = (JvmField it) -> {
      it.setVisibility(JvmVisibility.PUBLIC);
      final Procedure1<ITreeAppendable> _function_1 = (ITreeAppendable it_1) -> {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("\"\"");
        it_1.append(_builder);
      };
      this._jvmTypesBuilder.setInitializer(it, _function_1);
    };
    JvmField _field = this._jvmTypesBuilder.toField(chart, "jsonData", this._jvmTypesBuilder.newTypeRef(chart, String.class), _function);
    this._jvmTypesBuilder.<JvmField>operator_add(_members, _field);
    EList<JvmMember> _members_1 = type.getMembers();
    final Procedure1<JvmField> _function_1 = (JvmField it) -> {
      it.setVisibility(JvmVisibility.PUBLIC);
      final Procedure1<ITreeAppendable> _function_2 = (ITreeAppendable it_1) -> {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("\"\"");
        it_1.append(_builder);
      };
      this._jvmTypesBuilder.setInitializer(it, _function_2);
    };
    JvmField _field_1 = this._jvmTypesBuilder.toField(chart, "htmlTagId", this._jvmTypesBuilder.newTypeRef(chart, String.class), _function_1);
    this._jvmTypesBuilder.<JvmField>operator_add(_members_1, _field_1);
    EList<JvmMember> _members_2 = type.getMembers();
    final Procedure1<JvmField> _function_2 = (JvmField it) -> {
      it.setVisibility(JvmVisibility.PUBLIC);
      final Procedure1<ITreeAppendable> _function_3 = (ITreeAppendable it_1) -> {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("\"\"");
        it_1.append(_builder);
      };
      this._jvmTypesBuilder.setInitializer(it, _function_3);
    };
    JvmField _field_2 = this._jvmTypesBuilder.toField(chart, "inputValue", this._jvmTypesBuilder.newTypeRef(chart, String.class), _function_2);
    this._jvmTypesBuilder.<JvmField>operator_add(_members_2, _field_2);
  }
  
  public CharSequence createD3Chart(final Chart chart) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("CellSetToD3JsonConverter jsonConverter = new CellSetToD3JsonConverter();");
    _builder.newLine();
    _builder.append("return new ");
    final String d3ChartFileName = this._d3JsJavaUtil.createChartFilename(chart);
    _builder.append(d3ChartFileName);
    _builder.append("(\"");
    _builder.append(d3ChartFileName);
    _builder.append("\", jsonConverter.getD3JsonString(cxCellSet)");
    {
      boolean _isTreeMap = this._d3JsJavaUtil.isTreeMap(chart);
      if (_isTreeMap) {
        _builder.append(", jsonConverter.getDataColumnNameList(cxCellSet)");
      }
    }
    _builder.append(");");
    return _builder;
  }
}
