package de.dhbwstuttgart.syntaxtree.type;

import de.dhbwstuttgart.typecheck.JavaClassName;
import org.antlr.v4.runtime.Token;

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


public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
{
	/**
     * Ist IsArray auf true, muss beim Codegen ein Zeichen [ gesetzt werden
     * Bsp.: 15| tag = CONSTANT_Utf8, length = 22, ([Ljava/lang/String;)V
     * Ist IsArray auf false, muss beim Codegen ein Zeichen [ gesetzt werden
     * Bsp.: 9| tag = CONSTANT_Utf8, length = 21, (Ljava/lang/String;)V
     */
	private boolean IsArray = false;
	protected JavaClassName name;
    protected List<RefTypeOrTPHOrWildcardOrGeneric> parameter = null;
    /**
     * Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
     * den primitiven Datentyp ersetzt werden
     *
     * Bsp: java.lang.Integer mit Flag wird dann zu [int]
     */
    private boolean primitiveFlag=false;

    public RefType(JavaClassName fullyQualifiedName, Token offset)
    {
        super(offset);
        this.name = (fullyQualifiedName);
    }

    @Override
    public String toString(){
        return this.name.toString();
    }

    @Override
	public int hashCode() {
    	int hash = 0;
    	hash += super.hashCode();
    	hash += this.name.hashCode();//Nur den Name hashen. Sorgt fÃ¼r langsame, aber funktionierende HashMaps
    	return hash;
	}

    public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset)
    {
        this(fullyQualifiedName, offset);
        if(parameter != null && parameter.size()>0)this.parameter = parameter;
    }

    public JavaClassName getName()
    {
        return name;
    }

    public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList(){
    	if(this.parameter==null)return new ArrayList<>();
    	return this.parameter;
    }

    /**
     * Author: Jrg Buerle<br/>
     * @return
     */
    public boolean equals(Object obj)
    {
        if(obj instanceof RefType){
            boolean ret = true;
            
            if(!super.equals(obj))
            	return false;
            
            if(parameter==null || parameter.size()==0){
                ret &= (((RefType)obj).getParaList()==null || ((RefType)obj).getParaList().size()==0);
            }
            else{
                if(((RefType)obj).getParaList()==null){
                    ret = false;
                }
                else if(parameter.size() != ((RefType)obj).getParaList().size())
                {
                	ret = false;
                }
                else
                {
                	for(int i = 0; i<parameter.size(); i++)
                	{
                		ret &= parameter.get(i).equals(((RefType)obj).getParaList().get(i));
                	}
                }
            }
            return ret;
        }
        else{
            return false;
        }
    }


}

