package de.dhbwstuttgart.syntaxtree.type;
import java.util.Hashtable;

import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
import org.antlr.v4.runtime.Token;

/**
 * ReprÃ¯Â¿Â½sentiert einen Typparameter fÃ¯Â¿Â½r einen vom Programmierer nicht angegeben    
 * Typ. Jede TypePlaceholder besitzt einen eindeutigen Namen aus einem Namenspool  
 * und
 * ist in einer zentralen Registry, d.h. einer <code>Hashtable</code> abgelegt.
 * @author JÃ¯Â¿Â½rg BÃ¯Â¿Â½uerle
 * @version $Date: 2013/06/19 12:45:37 $
 */
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
{
	private final String name;



    /**
     * Privater Konstruktor - Eine TypePlaceholder-Variable wird Ã¯Â¿Â½ber die
     * Factory-Methode <code>fresh()</code> erzeugt.
     * <br>Author: JÃ¯Â¿Â½rg BÃ¯Â¿Â½uerle
     */
    private TypePlaceholder(String name, Token offset)
    {
        super(offset);
        this.name = name;
    }
    
    
    /**
     * @author Andreas Stadelmeier, a10023
     * Ruft die TypePlaceholder.fresh()-Methode auf.
     * FÃ¼gt zusÃ¤tzlich einen Replacementlistener hinzu.
     * @return
     */
    public static TypePlaceholder fresh(Token position){
		return new TypePlaceholder(NameGenerator.makeNewName(), position);
    }


    /**
     * Author: JÃ¯Â¿Â½rg BÃ¯Â¿Â½uerle<br/>
     * @return
     */
    public boolean equals(Object obj)
    {
        if(obj instanceof TypePlaceholder){
            return this.toString().equals(((TypePlaceholder)obj).toString());
        	//return super.equals(obj);
        }
        else{
            return false;
        }
    }


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

    public String getName() {
        return name;
    }

    @Override
    public void accept(ASTVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public <A> A acceptTV(TypeVisitor<A> visitor) {
        return visitor.visit(this);
    }

    @Override
    public void accept(ResultSetVisitor visitor) {
        visitor.visit(this);
    }
}
