/*
 * $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/
 */

/* Generated By:JJTree: Do not edit this line. X_MapCall.java */

package jsdai.expressCompiler;

import java.util.*;
import jsdai.SExtended_dictionary_schema.*;
import jsdai.lang.*;

public class X_MapCall extends SimpleNode {

	EMap_definition map_definition;
	boolean target_parameter_present;
	ETarget_parameter target_parameter;
	boolean partition_present;
	EMap_or_view_partition partition;
	EEntity scope;
	int argument_count;
  int actual_count;

  Vector actual_parameters; 
  String target_parameter_str;


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

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


  /** 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 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();
			target_parameter_str = "";

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

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

        if (jc != null) {
          if (jc.active) {
            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));
              }
            } // if contains statements

            if (children[i] instanceof X_TargetParameterRef) {
          		
              if (jc.print_string.length() == 0) {
                target_parameter_str = jc.generated_java;
              } else {
                target_parameter_str = jc.print_string;
              }

          	} else 
          	if (children[i] instanceof X_Expression) {

              if (jc.print_string.length() == 0) {
                actual_parameters.addElement(jc.generated_java);
              } else {
                actual_parameters.addElement(jc.print_string);
              }

							// could use it here if needed
//              jc.current_function_parameter = actual_count;
              actual_count++;

            } else {
              // something may be for partition
            }
          }
        }
      } // for children

      if (jc != null) {
        if (jc.active) {
          // old - in one file               String tmp_str = constructFunctionSchemaClass(jc) + getName() + "(";
          //          is_builtin = true;
          String tmp_str = getName(jc) + ".call";

          //                String express_parameter = "new Express(null, null, null)";
          String express_parameter = "_context";

//         tmp_str += express_parameter;
         if (target_parameter_present) {
         	// could do it also with info from the parser directly
         	 tmp_str += "Target_" + target_parameter_str;
         }
				 if (partition_present) {
         	 tmp_str += "Partition_" + partition.getName(null);
				 }
         tmp_str += "(" + express_parameter;

          boolean first_time = false;


          for (int i = 0; i < actual_count; i++) {
            String tmp_argument = (String) actual_parameters.elementAt(i);

            if (first_time) {
//              if (tmp_str.equals("typeOfV(_context, ")) { // 
              if (tmp_str.equals("typeOfV(_context")) { // 
                tmp_str = tmp_argument + "." + tmp_str;
                first_time = false;
              } else {
                tmp_str += tmp_argument;
                first_time = false;
              }
            } else {
              tmp_str += (", " + tmp_argument);
            }
          }

          tmp_str += ")";
          jc.generated_java = tmp_str;
          printDDebug("### X_MapCall - generated java: " + jc.generated_java, jc);

        } // jc.active
      } // jc != null
    }

    return data;
  }




  String getName(JavaClass jc) throws SdaiException {

    String name = "NAME_NOT_KNOWN";

    //      String built_in_package = "Express.";
    //    String built_in_package = "Value.alloc(ExpressTypes.GENERIC_TYPE).";
    String built_in_package = "Value.alloc(ExpressTypes.";

      if (map_definition == null) {
        name = "NullError.";
      } else {


      
      String a_name = constructMapClassName(map_definition);
      name = constructMapSchemaClass(jc, a_name);

		// currently - invoked method is static, if made non-static, may need something like that
		/*
			String constructor_argument = "";
		
    	EEntity pfd = Support.getParentFunctionProcedureRuleDefinition(fd);
    	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(";

		*/

	 } // not null


// System.out.println("map call name: " + name);
    return name;
  }

	String constructMapClassName (EMap_definition md) throws SdaiException {
	  String result = "";
		
		
		if (md == null) {
			result = "_NULL_map_definition_";
			return result;
		}

		
		result = md.getName(null);
		result = "M" + result.substring(0, 1).toUpperCase() + result.substring(1).toLowerCase();
		
	
		return result;	
	
	
	}

  String constructMapSchemaClass(JavaClass jc, String map_name)
                               throws SdaiException {
    // very exprensive call!!!
    SdaiModel current_model = map_definition.findEntityInstanceSdaiModel();

    //SdaiModel current_model = jc.model;
    String model_name = current_model.getName();

    //		System.out.println("function_name: " + function_name +"model_name: " + model_name);
    String schema_map_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_map_name = model_name.substring(0, model_name.length() - 16);
      } else {
        schema_map_name = model_name;
      }
    } else {
      schema_map_name = model_name;
    }

    //     String type_schema_class = "jsdai.S" + schema_name.substring(0,1).toUpperCase() + schema_name.substring(1).toLowerCase() + ".class";
    String type_schema_map_class = "jsdai.S" + schema_map_name.substring(0, 1).toUpperCase() + 
                               schema_map_name.substring(1).toLowerCase() + "." + map_name;

    return type_schema_map_class;
  }


}
