package de.dhbwstuttgart.typeinference.unify.model;

import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import java.util.ArrayList;
import java.util.Collection;

/**
 * A wildcard type that is either a ExtendsType or a SuperType.
 * @author Florian Steurer
 */
public abstract class WildcardType extends UnifyType implements ISerializableData {
	
	/**
	 * The wildcarded type, e.q. Integer for ? extends Integer. Never a wildcard type itself.
	 */
	protected UnifyType wildcardedType;
	
	/**
	 * Creates a new instance.
	 * @param name The name of the type, e.q. ? extends Integer
	 * @param wildcardedType The wildcarded type, e.q. Integer for ? extends Integer. Never a wildcard type itself.
	 */
	protected WildcardType(String name, UnifyType wildcardedType) {
		super(name, wildcardedType.getTypeParams());
		this.wildcardedType = wildcardedType;
	}
	
	/**
	 * Returns the wildcarded type, e.q. Integer for ? extends Integer.
	 * @return The wildcarded type. Never a wildcard type itself.
	 */
	public UnifyType getWildcardedType() {
		return wildcardedType;
	}
	
	/**
	 * Returns the type parameters of the WILDCARDED TYPE.
	 */
	@Override
	public TypeParams getTypeParams() {
		return wildcardedType.getTypeParams();
	}
	
	@Override
	public boolean wrongWildcard () {//This is an error
		return (wildcardedType instanceof WildcardType);
	}
	
	@Override
	public int hashCode() {
		return wildcardedType.hashCode() + getName().hashCode() + 17;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof WildcardType))
			return false;
		
		if(obj.hashCode() != this.hashCode())
			return false;
		
		WildcardType other = (WildcardType) obj;
		return other.getWildcardedType().equals(wildcardedType);
	}
	

	@Override
	public Collection<PlaceholderType> getInvolvedPlaceholderTypes() {
    ArrayList<PlaceholderType> ret = new ArrayList<>(wildcardedType.getInvolvedPlaceholderTypes());
		return ret;
	}
}
