/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */

package cx2x.translator.common;

import cx2x.translator.language.common.ClawDimension;
import cx2x.xcodeml.xnode.XcodeProgram;
import cx2x.xcodeml.xnode.Xname;
import cx2x.xcodeml.xnode.Xnode;
import cx2x.xcodeml.xnode.Xscope;

import java.util.ArrayList;
import java.util.List;

/**
 * Class holding information about nested do statements.
 * <p>
 * Created by clementval on 20/05/16.
 */
public class NestedDoStatement {

  private final List<Xnode> _statements;

  /**
   * Constructs a group of nested do statements from a list of dimension
   * objects. The outer statement represents the first element of the list and
   * the inner statement represents the last element of the list.
   *
   * @param dimensions A list of dimension objects.
   * @param xcodeml    The current XcodeML program unit in which the elements
   *                   will be created.
   */
  public NestedDoStatement(List<ClawDimension> dimensions,
                           XcodeProgram xcodeml)
  {
    _statements = new ArrayList<>();
    for(ClawDimension dim : dimensions) {
      Xnode induction = xcodeml.createVar(Xname.TYPE_F_INT, dim.getIdentifier(),
          Xscope.LOCAL);
      Xnode range = dim.generateIndexRange(xcodeml, true);
      Xnode doSt = xcodeml.createDoStmt(induction, range);
      if(_statements.size() != 0) {
        _statements.get(_statements.size() - 1).body().
            append(doSt, false);
      }
      _statements.add(doSt);
    }
  }

  /**
   * Get the outer do statements. First do statement in the nested group.
   *
   * @return XdoStatement holding information about the outer do statement.
   */
  public Xnode getOuterStatement() {
    return _statements.isEmpty() ? null : _statements.get(0);
  }

  /**
   * Get the inner do statements. Last do statement in the nested group.
   *
   * @return XdoStatement holding information about the inner do statement.
   */
  public Xnode getInnerStatement() {
    return _statements.isEmpty() ?
        null : _statements.get(_statements.size() - 1);
  }

  /**
   * Get the size of the group of nested do statements.
   *
   * @return Size of the group.
   */
  public int getGroupSize() {
    return _statements.size();
  }

}

@@ -205,92 +205,24 @@
 eml.
-xnode.XcodeProgram;%0Aimport cx2x.xcodeml.xnode.Xname;%0Aimport cx2x.xcodeml.xnode.Xnode
+helper.XnodeUtil
 ;%0Aim
@@ -245,22 +245,17 @@
 l.xnode.
-Xscope
+*
 ;%0A%0Aimpor
@@ -485,16 +485,601 @@
 tements;
+%0A  private List%3CString%3E _inductionVariables = null;%0A%0A  /**%0A   * Constructs a group of nested do statements from the outer statement.%0A   *%0A   * @param outerDoStatement Do statement on the outer level.%0A   */%0A  public NestedDoStatement(Xnode outerDoStatement) %7B%0A    _statements = new ArrayList%3C%3E();%0A    if(outerDoStatement.opcode() == Xcode.FDOSTATEMENT) %7B%0A      _statements.add(outerDoStatement);%0A      List%3CXnode%3E childDoStatements =%0A          outerDoStatement.matchAll(Xcode.FDOSTATEMENT);%0A      _statements.addAll(childDoStatements);%0A      // TODO do only truly nested group%0A    %7D%0A  %7D
 %0A%0A  /**%0A
@@ -2261,32 +2261,32 @@
 erStatement() %7B%0A
-
     return _stat
@@ -2328,32 +2328,686 @@
 ts.get(0);%0A  %7D%0A%0A
+  /**%0A   * Get statement at level i%0A   *%0A   * @param i Level index starts at 0 for outer do statement.%0A   * @return The do statement at level i.%0A   */%0A  public Xnode get(int i) %7B%0A    return _statements.get(i);%0A  %7D%0A%0A  /**%0A   * Get all the induction variable in the nested do statement group.%0A   *%0A   * @return List of induction variable as string.%0A   */%0A  public List%3CString%3E getInductionVariables() %7B%0A    if(_inductionVariables == null) %7B%0A      _inductionVariables = new ArrayList%3C%3E();%0A      for(Xnode doStmt : _statements) %7B%0A        _inductionVariables.add(XnodeUtil.extractInductionVariable(doStmt));%0A      %7D%0A    %7D%0A    return _inductionVariables;%0A  %7D%0A%0A
   /**%0A   * Get t

Add Xnode ctor and induction var retrieval