/*
 * $Id$
 *
 * JSDAI(TM), a way to implement STEP, ISO 10303
 * Copyright (C) 1997-2008, LKSoftWare GmbH, Germany
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License
 * version 3 as published by the Free Software Foundation (AGPL v3).
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * JSDAI is a registered trademark of LKSoftWare GmbH, Germany
 * This software is also available under commercial licenses.
 * See also http://www.jsdai.net/
 */

// %modified: 1016210368578 %

/* Generated By:JJTree: Do not edit this line. X_RepeatStmt.java */
package jsdai.expressCompiler;

import java.util.*;

public class X_RepeatStmt
  extends StatementNode {

  // public class X_RepeatStmt extends SimpleNode {
  //   static boolean print2string_activated;
  String all_str;
  String bound1_str;
  String bound2_str;
  String increment_str;
  String while_str;
  String until_str;
  String stmt_str;
  String step_str;
  String end_str;

	String variable_uid;

  public X_RepeatStmt(int id) {
    super(id);
    bound1_str = "";
    bound2_str = "";
    increment_str = "";
    while_str = "";
    until_str = "";
    step_str = "";
    end_str = "";
  }

  public X_RepeatStmt(Compiler2 p, int id) {
    super(p, id);
    bound1_str = "";
    bound2_str = "";
    increment_str = "";
    while_str = "";
    until_str = "";
    step_str = "";
    end_str = "";
  }

  /** Accept the visitor. **/
  public Object jjtAccept(Compiler2Visitor visitor, Object data)
                   throws jsdai.lang.SdaiException {
    return visitor.visit(this, data);
  }

  public Object childrenAccept(Compiler2Visitor visitor, Object data)
                        throws jsdai.lang.SdaiException {
    JavaClass jc = ( JavaClass )data;
    boolean first_time = true;

    if (children != null) {

      // for contained statements
      variable_names = new Vector();
      variable_declarations = new Vector();
      statements = new Vector();
      initializing_code = new Vector();
      variable_names_tmp = new Vector();
      variable_declarations_tmp = new Vector();
      statements_tmp = new Vector();
      initializing_code_tmp = new Vector();


      stmt_str = "";
      increment_str = ";;";

      for (int i = 0; i < children.length; ++i) {
        children[i].jjtAccept(visitor, data);

        if (jc != null) {
          if (jc.active) {
            if (children[i] instanceof X_IncrementControl) {

               if ((( SimpleNode )children[i]).java_contains_statements) {
                java_contains_statements = true;
								printDDebug("XPOORR B1: " + java_contains_statements, jc);

                // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
                for (int j = 0; j < (( SimpleNode )children[i]).variable_names.size(); j++) {
                  variable_names.add((( SimpleNode )children[i]).variable_names.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).variable_declarations.size(); j++) {
                  variable_declarations.add((( SimpleNode )children[i]).variable_declarations.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).statements.size(); j++) {
                  statements.add((( SimpleNode )children[i]).statements.elementAt(j));
                }

                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
                for (int j = 0; j < (( SimpleNode )children[i]).initializing_code.size(); j++) {
                  initializing_code.add((( SimpleNode )children[i]).initializing_code.elementAt(j));
                }
              }


             // integer case
              //                     increment_str = jc.java_str2 + ".getInteger();" + jc.java_str3 + ".getInteger();" + jc.java_str4;
              // Value case

							/*
									ok, making some changes:
									java_str2 - remains as it was
									java_str3 - the condition has to be generated here, 
									   java_str3 now will return only the bound2 expression to be assigned to a special variable before the loop
									   and to be used as for second parameter part
									java_str4 - has to be generated here, it will return now only the increment expression to be assigned to a spec variable
									before the loop and to be used  as for second and third parameter part, something like that:
									
									Value var_unique_id_end = java_str3;
									Value var_unique_id_step = java_str4;
									for (int j = start_expression; var_unique_id_step > 0 ? j <= var_unique_id_end : j >= var_unique_id_end; j += var_unique_id_step) {
									}
									
									  
							*/

							variable_uid = ((X_IncrementControl)children[i]).getVariable_uid();  
							boolean step_present = ((X_IncrementControl)children[i]).increment_present;
							String end_name = "_end" + (++uid);
							String step_name = "_step" + (uid);  // let's use the same UID
					    end_str = "Value " + end_name + " = Value.alloc(ExpressTypes.NUMBER_TYPE).set(" + jc.java_str3 + ");";
					    if (jc.java_str4.equals("")) {
					    	step_str = "Value " + step_name + " = Value.alloc(ExpressTypes.INTEGER_TYPE).set(_context, 1);";
					    } else {
					    	step_str = "Value " + step_name + " = Value.alloc(ExpressTypes.NUMBER_TYPE).set(" + jc.java_str4 + ");";
					    }


//              jc.java_str3 = "Value.alloc(ExpressTypes.LOGICAL_TYPE).lequal(_context, " + variable_uid + ", " + jc.generated_java + ").getLogical() == 2";
//                jc.java_str4 = variable_uid + ".inc(" + jc.generated_java + ")";


						// we can treat some integer literal cases as if step is not present, if we know that the step is > 0, for examlpe, when it is = 1

							if (step_str.endsWith(" = Value.alloc(ExpressTypes.NUMBER_TYPE).set(Value.alloc(ExpressTypes.INTEGER_TYPE).set(_context, 1));")) {
								step_present = false;
							}
							if (step_str.endsWith(" = Value.alloc(ExpressTypes.INTEGER_TYPE).set(_context, 1);")) {
								step_present = false;
							}



							if (step_present) {
							increment_str = jc.java_str2 + ";" + 
							
							"Value.alloc(ExpressTypes.LOGICAL_TYPE).greater(_context, " + step_name + ", Value.alloc(ExpressTypes.INTEGER_TYPE).set(_context, 0)).getLogical() == 2 ? " // step_name > 0 ? 
							+ "Value.alloc(ExpressTypes.LOGICAL_TYPE).lequal(_context, " + variable_uid + ", " + end_name + ").getLogical() == 2 : "  // j <= end_name : 
							+ "Value.alloc(ExpressTypes.LOGICAL_TYPE).gequal(_context, " + variable_uid + ", " + end_name + ").getLogical() == 2;" // j >= end_name;							
							+ variable_uid + ".inc(" + step_name + ")";
							} else {
							  // when step is not present, assume 1, it is non-negative, and old style code perhaps could be used.
//               increment_str = jc.java_str2 + ";" + jc.java_str3 + ";" + jc.java_str4;  // old stuff
               increment_str = jc.java_str2 + ";" + 
               
							"Value.alloc(ExpressTypes.LOGICAL_TYPE).lequal(_context, " + variable_uid + ", " + end_name + ").getLogical() == 2;" +
							 variable_uid + ".inc(" + step_name + ")";
               
						  }
              jc.java_str2 = "";
              jc.java_str3 = "";
              jc.java_str4 = "";
            } else if (children[i] instanceof X_WhileControl) {
              if ((( SimpleNode )children[i]).java_contains_statements) {
                java_contains_statements = true;

                // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
                for (int j = 0; j < (( SimpleNode )children[i]).variable_names.size(); j++) {
                  variable_names.add((( SimpleNode )children[i]).variable_names.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).variable_declarations.size(); j++) {
                  variable_declarations.add((( SimpleNode )children[i]).variable_declarations.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).statements.size(); j++) {
                  statements.add((( SimpleNode )children[i]).statements.elementAt(j));
                }

                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
                for (int j = 0; j < (( SimpleNode )children[i]).initializing_code.size(); j++) {
                  initializing_code.add((( SimpleNode )children[i]).initializing_code.elementAt(j));
                }
	              }

              while_str = "if (!(" + jc.generated_java + ".getLogical() == 2)) break;";
            } else if (children[i] instanceof X_UntilControl) {	
              if ((( SimpleNode )children[i]).java_contains_statements) {
                java_contains_statements = true;

                // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
                for (int j = 0; j < (( SimpleNode )children[i]).variable_names.size(); j++) {
                  variable_names.add((( SimpleNode )children[i]).variable_names.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).variable_declarations.size(); j++) {
                  variable_declarations.add((( SimpleNode )children[i]).variable_declarations.elementAt(j));
                }

                for (int j = 0; j < (( SimpleNode )children[i]).statements.size(); j++) {
                  statements.add((( SimpleNode )children[i]).statements.elementAt(j));
                }

                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
                for (int j = 0; j < (( SimpleNode )children[i]).initializing_code.size(); j++) {
                  initializing_code.add((( SimpleNode )children[i]).initializing_code.elementAt(j));
                }
              }

              until_str = "if (" + jc.generated_java + ".getLogical() == 2) break;";
            }else {
              // must be a statement
							printDDebug("XPOORR B1A repeat - statements: " + children[i], jc);
							stmt_str += ((SimpleNode)children[i]).forwarded_java;
							printDDebug("XPOORR B1AA repeat - statements: " + ((SimpleNode)children[i]).forwarded_java, jc);
							((SimpleNode)children[i]).forwarded_java = "";

							if ((( SimpleNode )children[i]).java_contains_statements) {

								printDDebug("XPOORR B1B repeat - statements: " + java_contains_statements, jc);
                  for (int j = 0; j < (( SimpleNode )children[i]).variable_names.size(); j++) {
                    variable_names_tmp.add((( SimpleNode )children[i]).variable_names.elementAt(j));
                  }

                  for (int j = 0; j < (( SimpleNode )children[i]).variable_declarations.size(); j++) {
                    variable_declarations_tmp.add((( SimpleNode )children[i]).variable_declarations.elementAt(j));
                    stmt_str += "\n" + jc.print_tabs + ( String )(( SimpleNode )children[i]).variable_declarations.elementAt(j);
                  }

                  for (int j = 0; j < (( SimpleNode )children[i]).statements.size(); j++) {
                    statements_tmp.add((( SimpleNode )children[i]).statements.elementAt(j));
                    stmt_str += "\n" + jc.print_tabs + ( String )(( SimpleNode )children[i]).statements.elementAt(j);
                  }

                  for (int j = 0; j < (( SimpleNode )children[i]).initializing_code.size(); j++) {
                    initializing_code_tmp.add((( SimpleNode )children[i]).initializing_code.elementAt(j));
                  }
                } // if contains statements
              // stmt_str += jc.generated_java + ";\n";
              if (first_time) {

                //                        stmt_str += jc.print_tabs + jc.print_string;
//                stmt_str += jc.print_string;
                stmt_str += ((SimpleNode)children[i]).generated_java;
								((SimpleNode)children[i]).generated_java = "";
//                jc.print_string = "";
                first_time = false;
              } else {
                stmt_str += jc.print_tabs + ((SimpleNode)children[i]).generated_java;
//                stmt_str += jc.print_tabs + jc.print_string;
								((SimpleNode)children[i]).generated_java = "";
//                jc.print_string = "";
              }
            }
          }
        }
      }
    }

    return data;
  }
}
