/* Generated by JTB 1.5.1 */
package examples.java.ex3jtb.visitor;

import static examples.java.ex3jtb.syntaxtree.NodeConstants.*;
import examples.java.ex3jtb.Token;
import examples.java.ex3jtb.syntaxtree.*;
import examples.java.ex3jtb.visitor.signature.NodeFieldsSignature;

/**
 * Provides default methods which visit each node in the tree in depth-first order.<br>
 * In your "Gen" visitors extend this class and override part or all of these methods.
 *
 */
public class DepthFirstGenVisitor implements IGenVisitor {

  /** The depth level (0, 1, ...) */
  int depthLevel = 0;

  /*
   * Base nodes classes visit methods (to be overridden if necessary)
   */

  /**
   * Visits a {@link NodeChoice} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final NodeChoice n, final String argu) {
    ++depthLevel;
    n.choice.accept(this, argu);
    --depthLevel;
    return;
  }

  /**
   * Visits a {@link NodeList} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final NodeList n, final String argu) {
    for (INode e : n.nodes) {
      ++depthLevel;
      e.accept(this, argu);
      --depthLevel;
    }
    return;
  }

  /**
   * Visits a {@link NodeListOptional} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final NodeListOptional n, final String argu) {
    if (n.present()) {
      for (INode e : n.nodes) {
        ++depthLevel;
        e.accept(this, argu);
        --depthLevel;
      }
      return;
    }
    return;
  }

  /**
   * Visits a {@link NodeOptional} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final NodeOptional n, final String argu) {
    if (n.present()) {
      ++depthLevel;
      n.node.accept(this, argu);
      --depthLevel;
      return;
    }
    return;
  }

  /**
   * Visits a {@link NodeSequence} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final NodeSequence n, final String argu) {
    for (INode e : n.nodes) {
      ++depthLevel;
      e.accept(this, argu);
      --depthLevel;
    }
    return;
  }

  /**
   * Visits a {@link Token} node.
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  public void visit(final Token n, @SuppressWarnings("unused") final String argu) {
    @SuppressWarnings("unused")
    final String tkIm = n.image;
    return;
  }

  /*
   * User grammar generated visit methods (to be overridden if necessary)
   */

  /**
   * Visits a {@link ASTStart} node, whose children are the following :
   * <p>
   * f0 -> Expression()<br>
   * f1 -> ";"<br>
   * s: 1859009853<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ 1859009853, JTB_SIG_ASTSTART, JTB_USER_ASTSTART })
  public void visit(final ASTStart n, final String argu) {
    // f0 -> Expression()
    final ASTExpression n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
    // f1 -> ";"
    final Token n1 = n.f1;
    ++depthLevel;
    n1.accept(this, argu);
    --depthLevel;
  }

  /**
   * Visits a {@link ASTExpression} node, whose child is the following :
   * <p>
   * f0 -> AdditiveExpression()<br>
   * s: -762347234<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ -762347234, JTB_SIG_ASTEXPRESSION, JTB_USER_ASTEXPRESSION })
  public void visit(final ASTExpression n, final String argu) {
    // f0 -> AdditiveExpression()
    final ASTAdditiveExpression n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
  }

  /**
   * Visits a {@link ASTAdditiveExpression} node, whose children are the following :
   * <p>
   * f0 -> MultiplicativeExpression()<br>
   * f1 -> ( #0 ( %0 "+"<br>
   * .. .. . .. | %1 "-" )<br>
   * .. .. . #1 MultiplicativeExpression() )*<br>
   * s: -1807059397<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ -1807059397, JTB_SIG_ASTADDITIVEEXPRESSION, JTB_USER_ASTADDITIVEEXPRESSION })
  public void visit(final ASTAdditiveExpression n, final String argu) {
    // f0 -> MultiplicativeExpression()
    final ASTMultiplicativeExpression n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
    // f1 -> ( #0 ( %0 "+"
    // .. .. . .. | %1 "-" )
    // .. .. . #1 MultiplicativeExpression() )*
    final NodeListOptional n1 = n.f1;
    if (n1.present()) {
      for (int i = 0; i < n1.size(); i++) {
        final INode nloeai = n1.elementAt(i);
        final NodeSequence seq = (NodeSequence) nloeai;
        //#0 ( %0 "+"
        //.. | %1 "-" )
        final INode nd = seq.elementAt(0);
        final NodeChoice nch = (NodeChoice) nd;
        final INode ich = nch.choice;
        switch (nch.which) {
          case 0:
            //%0 "+"
            ++depthLevel;
            ich.accept(this, argu);
            --depthLevel;
            break;
          case 1:
            //%1 "-"
            ++depthLevel;
            ich.accept(this, argu);
            --depthLevel;
            break;
          default:
            // should not occur !!!
            throw new ShouldNotOccurException(nch);
        }
        //#1 MultiplicativeExpression()
        final INode nd1 = seq.elementAt(1);
        ++depthLevel;
        nd1.accept(this, argu);
        --depthLevel;
      }
    }
  }

  /**
   * Visits a {@link ASTMultiplicativeExpression} node, whose children are the following :
   * <p>
   * f0 -> UnaryExpression()<br>
   * f1 -> ( #0 ( %0 "*"<br>
   * .. .. . .. | %1 "/"<br>
   * .. .. . .. | %2 "%" )<br>
   * .. .. . #1 UnaryExpression() )*<br>
   * s: 853643830<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ 853643830, JTB_SIG_ASTMULTIPLICATIVEEXPRESSION, JTB_USER_ASTMULTIPLICATIVEEXPRESSION })
  public void visit(final ASTMultiplicativeExpression n, final String argu) {
    // f0 -> UnaryExpression()
    final ASTUnaryExpression n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
    // f1 -> ( #0 ( %0 "*"
    // .. .. . .. | %1 "/"
    // .. .. . .. | %2 "%" )
    // .. .. . #1 UnaryExpression() )*
    final NodeListOptional n1 = n.f1;
    if (n1.present()) {
      for (int i = 0; i < n1.size(); i++) {
        final INode nloeai = n1.elementAt(i);
        final NodeSequence seq = (NodeSequence) nloeai;
        //#0 ( %0 "*"
        //.. | %1 "/"
        //.. | %2 "%" )
        final INode nd = seq.elementAt(0);
        final NodeChoice nch = (NodeChoice) nd;
        final INode ich = nch.choice;
        switch (nch.which) {
          case 0:
            //%0 "*"
            ++depthLevel;
            ich.accept(this, argu);
            --depthLevel;
            break;
          case 1:
            //%1 "/"
            ++depthLevel;
            ich.accept(this, argu);
            --depthLevel;
            break;
          case 2:
            //%2 "%"
            ++depthLevel;
            ich.accept(this, argu);
            --depthLevel;
            break;
          default:
            // should not occur !!!
            throw new ShouldNotOccurException(nch);
        }
        //#1 UnaryExpression()
        final INode nd1 = seq.elementAt(1);
        ++depthLevel;
        nd1.accept(this, argu);
        --depthLevel;
      }
    }
  }

  /**
   * Visits a {@link ASTUnaryExpression} node, whose child is the following :
   * <p>
   * f0 -> . %0 #0 "(" #1 Expression() #2 ")"<br>
   * .. .. | %1 MyID()<br>
   * .. .. | %2 Integer()<br>
   * s: 953155740<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ 953155740, JTB_SIG_ASTUNARYEXPRESSION, JTB_USER_ASTUNARYEXPRESSION })
  public void visit(final ASTUnaryExpression n, final String argu) {
    // f0 -> . %0 #0 "(" #1 Expression() #2 ")"
    // .. .. | %1 MyID()
    // .. .. | %2 Integer()
    final NodeChoice nch = n.f0;
    final INode ich = nch.choice;
    switch (nch.which) {
      case 0:
        //%0 #0 "(" #1 Expression() #2 ")"
        final NodeSequence seq = (NodeSequence) ich;
        //#0 "("
        final INode nd = seq.elementAt(0);
        ++depthLevel;
        nd.accept(this, argu);
        --depthLevel;
        //#1 Expression()
        final INode nd1 = seq.elementAt(1);
        ++depthLevel;
        nd1.accept(this, argu);
        --depthLevel;
        //#2 ")"
        final INode nd2 = seq.elementAt(2);
        ++depthLevel;
        nd2.accept(this, argu);
        --depthLevel;
        break;
      case 1:
        //%1 MyID()
        ++depthLevel;
        ich.accept(this, argu);
        --depthLevel;
        break;
      case 2:
        //%2 Integer()
        ++depthLevel;
        ich.accept(this, argu);
        --depthLevel;
        break;
      default:
        // should not occur !!!
        throw new ShouldNotOccurException(nch);
    }
  }

  /**
   * Visits a {@link ASTMyID} node, whose child is the following :
   * <p>
   * f0 -> < IDENTIFIER ><br>
   * s: -1580059612<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ -1580059612, JTB_SIG_ASTMYID, JTB_USER_ASTMYID })
  public void visit(final ASTMyID n, final String argu) {
    // f0 -> < IDENTIFIER >
    final Token n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
  }

  /**
   * Visits a {@link ASTInteger} node, whose children are the following :
   * <p>
   * f0 -> < INTEGER_LITERAL ><br>
   * f1 -> jc_1()<br>
   * s: 640957941<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @Override
  @NodeFieldsSignature({ 640957941, JTB_SIG_ASTINTEGER, JTB_USER_ASTINTEGER })
  public void visit(final ASTInteger n, final String argu) {
    // f0 -> < INTEGER_LITERAL >
    final Token n0 = n.f0;
    ++depthLevel;
    n0.accept(this, argu);
    --depthLevel;
    // f1 -> jc_1()
    final ASTjc_1 n1 = n.f1;
    ++depthLevel;
    n1.accept(this, argu);
    --depthLevel;
  }

  /**
   * Visits a {@link ASTjc_1} node, with no child :
   * <p>
   * s: 0<br>
   *
   * @param n - the node to visit
   * @param argu - the user argument 0
   */
  @SuppressWarnings("unused")
  @Override
  @NodeFieldsSignature({ 0, JTB_SIG_ASTJC_1, JTB_USER_ASTJC_1 })
  public void visit(final ASTjc_1 n, final String argu) {
    /* empty node, nothing that can be generated so far */
  }

  /**
   * Class handling a programmatic exception. Static for generic outer classes.
   */
  public static class ShouldNotOccurException extends RuntimeException {

    /** Default serialVersionUID */
    private static final long serialVersionUID = 1L;

    /**
     * Constructor with no message.
     */
    public ShouldNotOccurException() {
      super();
    }

    /**
     * Constructor which outputs a message.
     *
     * @param ch - a NodeChoice whose which value is invalid or lead to a fall-through
     */
    public ShouldNotOccurException(final NodeChoice ch) {
      super("Invalid switch value (" + ch.which + ") or fall-through");
    }

  }

}
