/**
 * generated by Xtext
 */
package de.ugoe.cs.swe.bnftools.generator;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import de.ugoe.cs.swe.bnftools.ebnf.Atom;
import de.ugoe.cs.swe.bnftools.ebnf.BnfEntry;
import de.ugoe.cs.swe.bnftools.ebnf.DefinitionList;
import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf;
import de.ugoe.cs.swe.bnftools.ebnf.GroupedSequence;
import de.ugoe.cs.swe.bnftools.ebnf.OptionalSequence;
import de.ugoe.cs.swe.bnftools.ebnf.RepeatedSequence;
import de.ugoe.cs.swe.bnftools.ebnf.Rule;
import de.ugoe.cs.swe.bnftools.ebnf.RuleReference;
import de.ugoe.cs.swe.bnftools.ebnf.SingleDefinition;
import de.ugoe.cs.swe.bnftools.ebnf.StringRule;
import de.ugoe.cs.swe.bnftools.ebnf.Term;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.IteratorExtensions;

/**
 * Generates code from your model files on save.
 * 
 * see http://www.eclipse.org/Xtext/documentation.html#TutorialCodeGeneration
 */
@SuppressWarnings("all")
public class EbnfGenerator implements IGenerator {
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
    TreeIterator<EObject> _allContents = resource.getAllContents();
    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
    Iterable<EtsiBnf> _filter = Iterables.<EtsiBnf>filter(_iterable, EtsiBnf.class);
    for (final EtsiBnf e : _filter) {
      EList<BnfEntry> _bnfEntry = e.getBnfEntry();
      int _size = _bnfEntry.size();
      boolean _notEquals = (_size != 0);
      if (_notEquals) {
        String _name = e.getName();
        String _plus = (_name + ".fo");
        CharSequence _compile = this.compile(e);
        fsa.generateFile(_plus, _compile);
      }
    }
  }
  
  public CharSequence compile(final EtsiBnf bnf) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("<?xml version=\"1.0\"?>");
    _builder.newLine();
    _builder.append("<!-- fop hello.xml -rtf hello.rtf -->");
    _builder.newLine();
    _builder.append("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">");
    _builder.newLine();
    _builder.newLine();
    _builder.append("\t");
    _builder.append("<fo:layout-master-set>");
    _builder.newLine();
    _builder.append("  \t\t");
    _builder.append("<fo:simple-page-master master-name=\"A4\" page-width=\"210mm\" page-height=\"297mm\">");
    _builder.newLine();
    _builder.append("    \t\t");
    _builder.append("<fo:region-body region-name=\"xsl-region-body\"  margin=\"2cm\"/>");
    _builder.newLine();
    _builder.append("     \t");
    _builder.append("</fo:simple-page-master>");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("</fo:layout-master-set>");
    _builder.newLine();
    _builder.newLine();
    _builder.append("\t");
    _builder.append("<fo:page-sequence  master-reference=\"A4\">");
    _builder.newLine();
    _builder.append("\t\t");
    _builder.append("<fo:flow flow-name=\"xsl-region-body\" font-family=\"verdana\">");
    _builder.newLine();
    {
      EList<BnfEntry> _bnfEntry = bnf.getBnfEntry();
      for(final BnfEntry bnfentry : _bnfEntry) {
        _builder.append("\t\t\t");
        CharSequence _compile = this.compile(bnfentry);
        _builder.append(_compile, "\t\t\t");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("\t\t");
    _builder.append("</fo:flow>");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("</fo:page-sequence>");
    _builder.newLine();
    _builder.append("</fo:root>");
    return _builder;
  }
  
  public CharSequence compile(final BnfEntry bnfEntry) {
    StringConcatenation _builder = new StringConcatenation();
    {
      Rule _rule = bnfEntry.getRule();
      boolean _notEquals = (!Objects.equal(_rule, null));
      if (_notEquals) {
        Rule _rule_1 = bnfEntry.getRule();
        CharSequence _compile = this.compile(_rule_1);
        _builder.append(_compile, "");
        _builder.newLineIfNotEmpty();
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final Rule rule) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("<fo:block><fo:inline id=\"");
    String _name = rule.getName();
    _builder.append(_name, "");
    _builder.append("\"\tcolor=\"purple\">");
    String _name_1 = rule.getName();
    _builder.append(_name_1, "");
    _builder.append("</fo:inline>\t::=\t");
    DefinitionList _definitionList = rule.getDefinitionList();
    CharSequence _compile = this.compile(_definitionList);
    _builder.append(_compile, "");
    _builder.append("</block>");
    return _builder;
  }
  
  public CharSequence compile(final DefinitionList dList) {
    StringConcatenation _builder = new StringConcatenation();
    {
      EList<SingleDefinition> _singleDefinition = dList.getSingleDefinition();
      for(final SingleDefinition sDef : _singleDefinition) {
        CharSequence _compile = this.compile(sDef);
        _builder.append(_compile, "");
        {
          EList<SingleDefinition> _singleDefinition_1 = dList.getSingleDefinition();
          SingleDefinition _last = IterableExtensions.<SingleDefinition>last(_singleDefinition_1);
          boolean _equals = sDef.equals(_last);
          boolean _not = (!_equals);
          if (_not) {
            _builder.append(" | ");
          }
        }
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final SingleDefinition sDefinition) {
    StringConcatenation _builder = new StringConcatenation();
    {
      EList<Term> _terms = sDefinition.getTerms();
      for(final Term term : _terms) {
        CharSequence _compile = this.compile(term);
        _builder.append(_compile, "");
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final Term term) {
    StringConcatenation _builder = new StringConcatenation();
    {
      Atom _termAtom = term.getTermAtom();
      boolean _notEquals = (!Objects.equal(_termAtom, null));
      if (_notEquals) {
        Atom _termAtom_1 = term.getTermAtom();
        CharSequence _compile = this.compile(_termAtom_1);
        _builder.append(_compile, "");
      }
    }
    {
      OptionalSequence _termOptionalSequence = term.getTermOptionalSequence();
      boolean _notEquals_1 = (!Objects.equal(_termOptionalSequence, null));
      if (_notEquals_1) {
        OptionalSequence _termOptionalSequence_1 = term.getTermOptionalSequence();
        CharSequence _compile_1 = this.compile(_termOptionalSequence_1);
        _builder.append(_compile_1, "");
      }
    }
    {
      RepeatedSequence _termRepeatedSequence = term.getTermRepeatedSequence();
      boolean _notEquals_2 = (!Objects.equal(_termRepeatedSequence, null));
      if (_notEquals_2) {
        RepeatedSequence _termRepeatedSequence_1 = term.getTermRepeatedSequence();
        CharSequence _compile_2 = this.compile(_termRepeatedSequence_1);
        _builder.append(_compile_2, "");
      }
    }
    {
      GroupedSequence _termGroupedSequence = term.getTermGroupedSequence();
      boolean _notEquals_3 = (!Objects.equal(_termGroupedSequence, null));
      if (_notEquals_3) {
        GroupedSequence _termGroupedSequence_1 = term.getTermGroupedSequence();
        CharSequence _compile_3 = this.compile(_termGroupedSequence_1);
        _builder.append(_compile_3, "");
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final GroupedSequence gSequ) {
    StringConcatenation _builder = new StringConcatenation();
    {
      EList<DefinitionList> _definitionList = gSequ.getDefinitionList();
      for(final DefinitionList d : _definitionList) {
        Object _compile = this.compile(d);
        _builder.append(_compile, "");
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final RepeatedSequence rSequ) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{");
    {
      EList<DefinitionList> _definitions = rSequ.getDefinitions();
      for(final DefinitionList d : _definitions) {
        Object _compile = this.compile(d);
        _builder.append(_compile, "");
      }
    }
    _builder.append("}");
    {
      boolean _isMorethanonce = rSequ.isMorethanonce();
      if (_isMorethanonce) {
        _builder.append("+");
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final OptionalSequence oSequ) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("(");
    {
      EList<DefinitionList> _definitionList = oSequ.getDefinitionList();
      for(final DefinitionList d : _definitionList) {
        Object _compile = this.compile(d);
        _builder.append(_compile, "");
      }
    }
    _builder.append(")");
    return _builder;
  }
  
  public CharSequence compile(final Atom atom) {
    StringConcatenation _builder = new StringConcatenation();
    {
      RuleReference _atomRuleReference = atom.getAtomRuleReference();
      boolean _notEquals = (!Objects.equal(_atomRuleReference, null));
      if (_notEquals) {
        RuleReference _atomRuleReference_1 = atom.getAtomRuleReference();
        CharSequence _compile = this.compile(_atomRuleReference_1);
        _builder.append(_compile, "");
      }
    }
    {
      StringRule _atomStringRule = atom.getAtomStringRule();
      boolean _notEquals_1 = (!Objects.equal(_atomStringRule, null));
      if (_notEquals_1) {
        StringRule _atomStringRule_1 = atom.getAtomStringRule();
        CharSequence _compile_1 = this.compile(_atomStringRule_1);
        _builder.append(_compile_1, "");
      }
    }
    return _builder;
  }
  
  public CharSequence compile(final RuleReference rRef) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("<fo:basic-link internal-destination=\"");
    Rule _ruleref = rRef.getRuleref();
    String _name = _ruleref.getName();
    _builder.append(_name, "");
    _builder.append("\" text-decoration=\"underline\" color=\"blue\">");
    Rule _ruleref_1 = rRef.getRuleref();
    String _name_1 = _ruleref_1.getName();
    _builder.append(_name_1, "");
    _builder.append("</fo:basic-link>");
    return _builder;
  }
  
  public CharSequence compile(final StringRule sRule) {
    StringConcatenation _builder = new StringConcatenation();
    {
      String _colon = sRule.getColon();
      boolean _notEquals = (!Objects.equal(_colon, null));
      if (_notEquals) {
        String _colon_1 = sRule.getColon();
        _builder.append(_colon_1, "");
      }
    }
    {
      String _literal = sRule.getLiteral();
      boolean _notEquals_1 = (!Objects.equal(_literal, null));
      if (_notEquals_1) {
        String _literal_1 = sRule.getLiteral();
        _builder.append(_literal_1, "");
      }
    }
    return _builder;
  }
}
