package de.dhbwstuttgart.strucTypes4.syntaxtree;

import de.dhbwstuttgart.strucTypes4.algo.ConstraintAbstract;
import de.dhbwstuttgart.strucTypes4.typeVars.TypeVar;
import de.dhbwstuttgart.strucTypes4.typeVars.TypeVarAbstract;
import de.dhbwstuttgart.strucTypes4.typeVars.TypeVarStore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by sebastian on 07.04.17.
 */
public class Class extends  SyntaxNode{


    String name;
    List<Field> felder;
    List<Method> methoden;
    public TypeVarStore typeVarStore = new TypeVarStore();

    List<Interface> interfaces;
    List<TypeVar> generics;
    List<ConstraintAbstract> constraintSet;


    public Class(String name, List<Field> felder , List<Method> methoden) {
        this.name = name;
        this.felder = felder;
        this.methoden = methoden;
    }


    public Map<String,TypeVarAbstract> makeAssumptions() {

        // Name bei Feldern feld, name bei methoden methode()
        Map<String, TypeVarAbstract> ass = new HashMap<>();
        // felder
        for (Field f : felder) {
            TypeVarAbstract tv = typeVarStore.storeTPH(f.getTypePlaceHolder());
            ass.put(f.getVar_name() , tv);
        }

        // methoden
        for (Method m : methoden) {
            TypeVarAbstract tv = typeVarStore.storeTPH(m.getTypePlaceHolder());
            ass.put(m.getName()+"()", tv);
        }

        // This einfügen
        TypeVarAbstract tv = typeVarStore.storeTPH(getTypePlaceHolder());
        ass.put("this" ,  tv);

        return ass;
    }


    public Method mType(String name) {
        for (Method m : methoden) {
            if (m.getName().equals(name))  {
                return m;
            }
        }
        return null;
    }



    public TypeVarStore getTypeVarStore() {
        return typeVarStore;
    }

    public void setTypeVarStore(TypeVarStore typeVarStore) {
        this.typeVarStore = typeVarStore;
    }

    public List<Interface> getInterfaces() {
        return interfaces;
    }

    public void setInterfaces(List<Interface> interfaces) {
        this.interfaces = interfaces;
    }

    public List<TypeVar> getGenerics() {
        return generics;
    }

    public void setGenerics(List<TypeVar> generics) {
        this.generics = generics;
    }

    public List<ConstraintAbstract> getConstraintSet() {
        return constraintSet;
    }

    public void setConstraintSet(List<ConstraintAbstract> constraintSet) {
        this.constraintSet = constraintSet;
    }

    public List<Field> getFelder() {
        return felder;
    }

    public void setFelder(List<Field> felder) {
        this.felder = felder;
    }

    public List<Method> getMethoden() {
        return methoden;
    }

    public void setMethoden(List<Method> methoden) {
        this.methoden = methoden;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        String res = "class " + name + " \n";
        for (Field f : felder) {
            res = res.concat(f.toString() + "\n");
        }

        for (Method m : methoden) {
            res = res.concat(m.toString() + "\n");
        }
        return res;
    }

    @Override
    public String toCodeTPH() {
        String res = "class " + name + " \n";
        for (Field f : felder) {
            res = res.concat(f.toCodeTPH() + "\n");
        }
        for (Method m : methoden) {
            res = res.concat(m.toCodeTPH() + "\n");
        }
        return res;
    }

    @Override
    public String toCodeTyped(TypeVarStore typeVarStore) {
        String res = "class " + name + " \n";
        for (Field f : felder) {
            res = res.concat(f.toCodeTyped(typeVarStore)+ "\n");
        }
        for (Method m : methoden) {
            res = res.concat(m.toCodeTyped(typeVarStore) + "\n");
        }
        return res;
    }






}
