package strucTypes3;

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

import com.sun.org.apache.xalan.internal.xsltc.runtime.Parameter;

import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.strucTypes3.ConstraintAbstract;
import de.dhbwstuttgart.strucTypes3.FieldConstraint;
import de.dhbwstuttgart.strucTypes3.MethodConstraint;
import de.dhbwstuttgart.strucTypes3.MyTypeVar;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.typecheck.JavaClassName;

public class Construct {
	
	
	public static ClassOrInterface constructInterfaces(ConstraintAbstract constraint) {
		
		if (constraint.getClass().equals(FieldConstraint.class)) {
			FieldConstraint fieldConstraint = (FieldConstraint) constraint;
			return Construct.constructInterfaceField(fieldConstraint); 						
		}
		else if (constraint.getClass().equals(MethodConstraint.class)) {
			MethodConstraint methodConstriant = (MethodConstraint) constraint; 
			return Construct.constructInterfaceMethod(methodConstriant); 
			
		}
		else {
			// Fehlerfall 
			return null; 
		}
	}
	
	
	public static ClassOrInterface constructInterfaceField(FieldConstraint fieldConstriant) {
		
		Field field = new Field(fieldConstriant.getName_of_field() , fieldConstriant.getAttribut() , 0 , null); 
		List<Field> fielddecl = new ArrayList<>(); 
		fielddecl.add(field); 
		JavaClassName name = new JavaClassName(fieldConstriant.getReveiver().toString());	
		
		
		//Erstellen der Generics 
		List<GenericTypeVar> genericTypeVarList = new ArrayList<>(); 				
		String type_of_field = fieldConstriant.getAttribut().toString(); 
		// TODO Einkommentieren
		//genericTypeVarList.add(new GenericTypeVar(type_of_field, null, new NullToken(), new NullToken())); 
		GenericDeclarationList genericDeclaraitonList = new GenericDeclarationList(genericTypeVarList, new NullToken()); 
		
		
		// methods
		List<Method> methods = new ArrayList<Method>(); 
		
		
		ClassOrInterface face = new ClassOrInterface(0, name, fielddecl, methods, genericDeclaraitonList, null, true, null , null); 
		
		return face; 		
		
	}
	
	
	public static ClassOrInterface constructInterfaceMethod(MethodConstraint methodConstraint) {
		
		System.out.println("Generiere Method-Interface");
		
		// Erstellen der Argumente der Methode 	
		List<FormalParameter> formalParameterList = new ArrayList<>(); 
		ParameterList params = new ParameterList(formalParameterList, new NullToken()); 
		for (MyTypeVar typeVar :  methodConstraint.getArgumentTypeVars()) {
			params.getFormalparalist().add(new FormalParameter(typeVar.toString() , typeVar.getTypevar(), new NullToken()  ));
		}
		
		// Erstellen der Methode 
		Method method = new Method(methodConstraint.getMethodName() ,methodConstraint.getReturnType(), 0, params, null, null, null); 
		List<Method> methodlist = new ArrayList<>(); 
		methodlist.add(method); 		
		
		// Name des neuen Interfaces 
		JavaClassName name = new JavaClassName(methodConstraint.getReceiver().toString()); 
		
		//Erstellen der Generics 
		List<GenericTypeVar> genericTypeVarList = new ArrayList<>(); 
		GenericDeclarationList genericDeclaraitonList = new GenericDeclarationList(genericTypeVarList, new NullToken()); 
		for (MyTypeVar tv : methodConstraint.getArgumentTypeVars()) {
			// TODO Einkoommentieren
			//genericTypeVarList.add(new GenericTypeVar(tv.toString(), null, new NullToken(), new NullToken())); 
		}
		
		
		ClassOrInterface face = new ClassOrInterface(0, name, null, methodlist, genericDeclaraitonList, null, true, null, null); 
		return face;  		
	}
	
	
	
	
	
	
	
	
	

}
