// ino.module.ClassBody.8554.package 
package de.dhbwstuttgart.syntaxtree;
// ino.end
// ino.module.ClassBody.8554.import 
import java.util.Enumeration;
import java.util.Hashtable;
import de.dhbwstuttgart.typeinference.Menge;

import de.dhbwstuttgart.logger.Logger;
// ino.end


import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.myexception.SCClassBodyException;
import de.dhbwstuttgart.myexception.SCExcept;
import de.dhbwstuttgart.myexception.SCMethodException;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;




// ino.class.ClassBody.23143.declaration 
public class ClassBody
{
    // ino.attribute.fielddecl.23146.declaration 
    private Menge<Field>fielddecl             = new Menge<Field>();
    // ino.end
    // ino.attribute.kill.23155.declaration 
    public Hashtable<Type,Type> kill       = new Hashtable<Type,Type>();
    // ino.end

    // ino.attribute.parserlog.23158.declaration 
    protected static Logger parserlog = Logger.getLogger("parser");
    // ino.end
    
    

// ino.method.complete_parahashtable.23173.defdescription type=block
/*    public void set_paratype(Menge classlist, UsedId superclass, Menge        
pl,Hashtable ph,boolean ext){     DeclId decl;
    FieldDecl field;
    System.out.println("++ ParaCheck:  Fielddecl's: "+fielddecl.toString());

    for(Enumeration e=fielddecl.elements();e.hasMoreElements();){
        field = (FieldDecl)e.nextElement();
        for(Enumeration e1=field.get_Name().elements();e1.hasMoreElements();){
        decl=(DeclId)e1.nextElement();

        if(superclass != null){
            System.out.println("superclass.get_ParaList: "                      
+superclass.get_ParaList().toString()); 
            for(Enumeration e2 =                                                
superclass.get_ParaList().elements();e2.hasMoreElements();){                    
System.out.println("paralist.elements:: "+((Type)e2.nextElement()).get_Type()); 
           }
            }
        if(decl.get_Paratyp()!=null){
            System.out.println("++ ParaCheck:  Name:                            
"+decl.get_Name()+"\tParatyp: "+decl.get_Paratyp());         }
        else System.out.println("++ ParaCheck:  Name: "+decl.get_Name()+"\tkein 
Paratyp gesetzt.");         }
    }
    }
*/
// ino.end

    
    
    
    public Menge<Field> getFields()
    {
        return fielddecl;
    }

    /**
     * @author Andreas Stadelmeier, a10023
     * Fügt der Klasse eine Feld hinzu.
     * @param feld
     */
    public void addField(Field i)
    {
    fielddecl.addElement(i);
    }
    
// ino.method.is_declared.23188.defdescription type=line
//                                                                                 
// ********************************************************************************************
// 
// ino.end

// ino.method.is_declared.23188.definition 
public boolean is_declared(Type t, Menge<Class> classlist)
throws SCClassBodyException
// ino.end
// ino.method.is_declared.23188.body 
{
    boolean flag=false;
    for(Enumeration<Class> e = classlist.elements();e.hasMoreElements();)
    {
        flag = false;
        Class c = e.nextElement();

//      System.out.println("is_init:  vergleiche "+t.get_Type_()+" mit "+c.getName());
        if(c.getName().equals(t.getName())){
//      System.out.println("Klasse "+t.get_Type()+"im Menge classlist gefunden.");
        flag = true;
        break;
        }
    }

    if( t instanceof RefType && ((RefType)t).get_ParaList()!=null)
    {
        if( ((RefType)t).get_ParaList().size() > 0 )
        {
            for(Enumeration e1 = ((RefType)t).get_ParaList().elements(); e1.hasMoreElements(); )
            {
                try
                {
                    is_declared((Type)e1.nextElement(),classlist);
                }
                catch(SCClassBodyException ex)
                {
                    throw ex;
                }
            }
        }
    }

    if(flag)
        return true;
    else
    {
        SCClassBodyException ex = new SCClassBodyException();
        SCExcept e = new SCExcept();
        e.set_error("unbekannte Klasse "+t.getName()+".");
        e.set_function("complete_parahashtable() --> is_declared()");
        e.set_statement(t.getName().toString());
        ex.addException(e);
        throw ex;
    }
}
// ino.end

// ino.method.string_rec.23191.definition 
static String string_rec(Hashtable ht)
// ino.end
// ino.method.string_rec.23191.body 
{
    String record=("[");
    for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){
        String s = (String)k.nextElement();
        Object o = e.nextElement();

        record=record.concat(" "+s);

        if(o instanceof Type){
            record=record.concat(" = "+((Type)o).getName());
        }

        else if(o instanceof Hashtable){
            record=record.concat("= ");
        record=record.concat(string_rec((Hashtable)o));
        if(e.hasMoreElements())
            record=record.concat(", ");
        }
        else if(o instanceof String){
            record=record.concat(" = "+o);
        if(e.hasMoreElements())
            record=record.concat(", ");
        }
        else {
            record=("[FEHLER: string_rec: unbekannter Typ!!!!!!");
        }
    }
        record=record.concat("]");
        return(record);
    }
// ino.end

    // ino.method.string_rec.23194.defdescription type=block
    /*static void string_rec(Menge v){
    String record=("{");
    for(Enumeration e=v.elements();e.hasMoreElements();){
        Type t = (Type)e.nextElement();
        record=record.concat(" "+t.getName());
    
        if(e.hasMoreElements())
        record=record.concat(",");
    }
    record=record.concat("}");
    parserlog.debug(record);
    }*/
    // ino.end
    // ino.method.string_rec.23194.definition 
    static String string_rec(String st, Hashtable ht)
    // ino.end
    // ino.method.string_rec.23194.body 
    {
    String record=(st);
    record=record.concat("[");
    for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){
        String s = (String)k.nextElement();
        Object o = e.nextElement();
    
        record=record.concat(" "+s);
    
        if(o instanceof Type){
            record=record.concat(" = "+((Type)o).getName());
        }
    
        else if(o instanceof Hashtable){
            record=record.concat("= ");
            record=record.concat(string_rec((Hashtable)o));
        if(e.hasMoreElements())
            record=record.concat(", ");
        }
        else if(o instanceof String){
            record=record.concat(" = "+o);
        if(e.hasMoreElements())
            record=record.concat(", ");
        }
        else {
            record=("FEHLER: string_rec: unbekannter Typ!!!!!! " +o);
        }
    }
    record=record.concat("]");
    return(record);
    }
    // ino.end

// ino.method.string_rec.23197.definition 
static String string_rec(String st,Menge v)
// ino.end
// ino.method.string_rec.23197.body 
{
    String record=(st);
    record=record.concat("{");
    for(Enumeration e=v.elements();e.hasMoreElements();){
        Type t = (Type)e.nextElement();
        record=record.concat(" "+t.getName());
        if(e.hasMoreElements())
            record=record.concat(", ");
    }
    record=record.concat("}");
    return(record);
    }
// ino.end
// ino.method.istParameterOK.23200.defdescription type=line
//                                                                                 
// ********************************************************************************************
// 
// ino.end
/*
// ino.method.istParameterOK.23200.definition 
public void istParameterOK( Menge Parameter, Menge<Class> KlassenVektor  )
// ino.end
// ino.method.istParameterOK.23200.body 
{
    // otth: prueft rekursiv, ob Parameter im Klassenvektor vorkommt, falls RefType, oder ob TypePlaceholder nicht vorkommt

    for( int i = 0; i < Parameter.size();  i++)
    {
        Type TempParameter = (Type)(Parameter.elementAt(i));

        // an dieser Stelle: Parametername
        if ( TempParameter instanceof RefType )
        {
            // t im Klassenvektor suchen --> muss deklariert sein
            boolean bGefunden = false;
            for( int k = 0; k < KlassenVektor.size();  k++)
            {
                if( KlassenVektor.elementAt(k).getName().equals(((RefType)TempParameter).getTypeName()) )
                {
                    // Namen gleich --> Parameterliste rekursiv pruefen
                    if( ((RefType)TempParameter).get_ParaList() != null )
                    {
                        if( ((RefType)TempParameter).get_ParaList().size() != KlassenVektor.elementAt(k).get_ParaList().size() )
                        {
                            parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameteranzahl von\n" + TempParameter.getName() + " stimmt mit der Klassendefinition\n" + KlassenVektor.elementAt(k).getName() + " nicht �berein.", Section.OLD );
                            System.exit( 1 );
                        }
                        else
                        {
                            istParameterOK( ((RefType)TempParameter).get_ParaList(), KlassenVektor );
                            bGefunden = true;
                            break;
                        }
                    }
                    else
                    {
                        // OK ...
                        bGefunden = true;
                        break;
                    }
                }
            }
            // Parameter wurde nicht gefunden: 
            if( !bGefunden )
            {
                parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " ist noch nicht als Klasse definiert." );
                System.exit( 1 );
            }
        } 
        else
        {
            // Tylose Variablen d�rfen nicht deklariert sein
            for( int k = 0; k < KlassenVektor.size();  k++)
            {
                if( KlassenVektor.elementAt(k).getName().equals(TempParameter.getName()) )
                {
                    parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " ist bereits als Klasse definiert." );
                    System.exit( 1 );
                }
            }
            // nicht gefunden
        }
    } // end otth; end if: t = RefType
}
// ino.end
*/

    // ino.method.toString.23203.defdescription type=javadoc
    /**
     * <br/>Author: Martin Pl�micke
     * @return
     */
    // ino.end
    // ino.method.toString.23203.definition 
    public String toString()
    // ino.end
    // ino.method.toString.23203.body 
    {
        return fielddecl.toString();
    }
    // ino.end



	public JavaCodeResult printJavaCode(ResultSet resultSet) {
		JavaCodeResult ret = new JavaCodeResult("{\n");
		for(Field field : this.fielddecl)ret.attach( field.printJavaCode(resultSet) ).attach( "\n" );
		return ret.attach("}\n");

	}
	

    
}
// ino.end