/*
 * $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: 1016210368586 %

/* Generated By:JJTree: Do not edit this line. X_ProcedureCallStmt.java */
package jsdai.expressCompiler;
import jsdai.lang.*;
import jsdai.SExtended_dictionary_schema.*;

import java.util.*;

public class X_ProcedureCallStmt
  extends SimpleNode {

  boolean is_builtin = true;
  int built_in_id;
  int argument_count;
  int actual_count;
  EProcedure_definition pd;
  EEntity scope;
  Vector arguments; // probably not needed - vector from the parser
  Vector actual_parameters; // strings with argument expressions from the parse tree

  public X_ProcedureCallStmt(int id) {
    super(id);
  }

  public X_ProcedureCallStmt(Compiler2 p, int id) {
    super(p, id);
  }

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

  //Functions imported from X_FunctionCall.java

  String getName(JavaClass jc) throws SdaiException {
	
    String name = "NAME_NOT_KNOWN";



    String built_in_package = "Value.alloc().";

    switch (built_in_id) {
      case 1:
        name = built_in_package + "insert(_context, ";
        break;

      case 2:
        name = built_in_package + "remove(";
        break;


      case -1: // user defined - not implemented yet
        if (pd == null) {

          // error
	        name = "NullError.";
//          name = built_in_package + "NullError.";
          break;
        }

        is_builtin = false;

//        String the_name = pd.getName(null);
//        String a_name = "P" + the_name.substring(0, 1).toUpperCase() + the_name.substring(1).toLowerCase() + ".";

      	String a_name = constructProcedureClassName(pd);
      	name = constructProcedureSchemaClass(jc, a_name);

				String constructor_argument = "";

	    	EEntity pfd = Support.getParentFunctionProcedureRuleDefinition(pd);
  	  	if (pfd != null) {
					if (pfd == scope) {
						constructor_argument = "this";
					} else 
					if (scope instanceof EAlgorithm_definition) {
						if (Support.getParentFunctionProcedureRuleDefinition((EAlgorithm_definition)scope) == pfd) {
							constructor_argument = "parent";
						} else {
//						constructor_argument = "weird";
						}
					} else {
					}				
				}

  	    name = "(new " + name + "(" + constructor_argument + ")).run(";
//        name = constructProcedureSchemaClass(jc, a_name);
//        name = name + "run(";
        break;

      default:
        name = "_fDefault_error";
        break; // error
    }

    return name;
  }

	// better to put such methods in one place  
	String constructProcedureClassName (EProcedure_definition fd4) throws SdaiException {
	  String result = "";
		EAlgorithm_definition fd2 = null;
		EEntity fd3 = null;
		String f_name = null;
		
		
		if (fd4 == null) {
			result = "_NULL_function_definition_";
			return result;
		}

		fd2 = (EAlgorithm_definition)fd4;
		
		result = fd2.getName(null);
		result = result.substring(0, 1).toUpperCase() + result.substring(1).toLowerCase();
		
		for (;;) {
			if (fd2 == null) {
				fd3 = null;
			} else {
				fd3 = Support.getParentFunctionProcedureRuleDefinition(fd2);
			}
			if (fd3 == null) {
				result = "P" + result;
				break;
			} else {
				// still inner function, add names
				if (fd3 instanceof EAlgorithm_definition) {
					f_name = ((EAlgorithm_definition)fd3).getName(null);
					fd2 = (EAlgorithm_definition)fd3;
				} else 
				if (fd3 instanceof EGlobal_rule) {
					f_name = ((EGlobal_rule)fd3).getName(null);
					fd2 = null;
				} else {
					// should not happen
					fd2 = null;
				}
				result = f_name.substring(0, 1).toUpperCase() + f_name.substring(1).toLowerCase() + "$" + result;
			}
		}
	
		return result;	
	
	
	}
  
  



  String constructProcedureSchemaClass(JavaClass jc, String procedure_name)
                               throws SdaiException {

		SdaiModel current_model = pd.findEntityInstanceSdaiModel(); 
    String model_name = current_model.getName();
    String schema_name;

    if (model_name.length() > 16) {
      String part_model_name = model_name.substring(model_name.length() - 16);

      if (part_model_name.equalsIgnoreCase("_DICTIONARY_DATA")) {
        schema_name = model_name.substring(0, model_name.length() - 16);
      } else {
        schema_name = model_name;
      }
    } else {
      schema_name = model_name;
    }

    String type_schema_class = "jsdai.S" + schema_name.substring(0, 1).toUpperCase() + 
      schema_name.substring(1).toLowerCase() + "." + procedure_name;

    return type_schema_class;
  }

  public Object childrenAccept(Compiler2Visitor visitor, Object data)
                        throws SdaiException {

    JavaClass jc = ( JavaClass )data;

    if (children != null) {
      // for contained statements
      variable_names = new Vector();
      variable_declarations = new Vector();
      statements = new Vector();
      initializing_code = new Vector();
      actual_count = 0;
      actual_parameters = new Vector();

      for (int i = 0; i < children.length; ++i) {

				if (children[i] instanceof X_Parameter) {
						jc.current_function_parameter = actual_count+1;
				}

        children[i].jjtAccept(visitor, data);

        if (jc != null) {
          if (jc.active) {
						printDDebug("XPOORR B0 in procedure_call: " + children[i], jc);
            if ((( SimpleNode )children[i]).java_contains_statements) {
              java_contains_statements = true;
							printDDebug("XPOORR B2 in procedure_call: true", 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));
              }
            } // if contains statements

            if (children[i] instanceof X_Parameter) {
              if (jc.print_string.length() == 0) {
								printDDebug("child: " +i +"gen java: " +jc.generated_java, jc);
                actual_parameters.addElement(jc.generated_java);
              } else {
								printDDebug("child: " +i +"print string: " +jc.print_string, jc);
								actual_parameters.addElement(jc.print_string);
              }
							jc.current_function_parameter = actual_count;
              actual_count++;
            } else {
              // must be an error
            }
          }
        }
      } // for children

      if (jc != null) {
        if (jc.active) {
          String tmp_str = getName(jc);
          String express_parameter = "_context";
          boolean first_time = false;

          if (!is_builtin) {
            tmp_str += express_parameter;
          }

          if (is_builtin) {
            first_time = true;
          }

          for (int i = 0; i < actual_count; i++) {
            String tmp_argument = ( String )actual_parameters.elementAt(i);
						printActive("In X_ProcedureCallStmt: i: " +i +" tmp_argument: " +tmp_argument, jc);
            if (first_time) {
              tmp_str += tmp_argument;
              first_time = false;
            } else {
              tmp_str += ", " + tmp_argument;
            }
          }

          tmp_str += ");";
          jc.generated_java = tmp_str;
          printActive("### X_ProcedureCallStmt - generated java lalala: " + jc.generated_java, jc);

          switch (built_in_id) {
            case 1:
              break;

            case 2:
              break;

            case -1: // user defined
              if (pd == null) {

                // error
                break;
              }

              // here goes the type of user-defined function
              break;

            default:
              break; // error
          }
        } // jc.active

      } // jc != null

    }

    return data;
  }


}
