package de.dhbwstuttgart.syntaxtree;

import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;

import org.antlr.v4.runtime.Token;

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

/**
 *  Entspricht einem GenericTypeVar, jedoch mit Bounds
 *  (d.h. vorgaben, von welchem Typ die Typevar sein darf
 *   => extends Class x
 *   => implements Interface y
 *   ... 
 * @author hoti 4.5.06
 * 
 */
public class GenericTypeVar extends SyntaxTreeNode
{

    /**
     * Hier sind die Bounds in Form von Type-Objekten abgespeichert 
     */
    List<? extends RefTypeOrTPHOrWildcardOrGeneric> bounds=new ArrayList<RefTypeOrTPHOrWildcardOrGeneric>();
	private Token endOffset;
    private String name;

    public GenericTypeVar(String s, List<? extends RefTypeOrTPHOrWildcardOrGeneric> bounds, Token offset, Token endOffset)
    {
        super(offset);
        name = s;
        if(bounds != null)for(RefTypeOrTPHOrWildcardOrGeneric t : bounds){
        	//if(t!=null)this.extendVars.add(t);
        }
        //this.genericTypeVar = new RefType(s,offset);
        this.bounds = bounds;
        this.endOffset = endOffset;
    }

    public List<? extends RefTypeOrTPHOrWildcardOrGeneric> getBounds()
    {
        return bounds;
    }

    public String toString()
    {
        return "BoGTV " + this.name + " " + this.bounds;
    }

    public String getName(){
        return name.toString();
    }

    /*
    public JavaClassName definingClass(){
        return name.getParentClass();
    }
*/
    @Override
    public void accept(ASTVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GenericTypeVar that = (GenericTypeVar) o;
        return bounds.equals(that.bounds) && name.equals(that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bounds, name);
    }
}
