package cn.citycraft.GsonAgent.api.reflect;

import java.lang.reflect.Type;

import cn.citycraft.GsonAgent.GsonAgent;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class TypeToken<T> {

	private final TypeTokenAbstract<T> internal;

	public TypeToken() {
		if (GsonAgent.newVersion) {
			this.internal = new cn.citycraft.GsonAgent.normal.reflect.TypeTokenHandle<T>();
		} else {
			this.internal = new cn.citycraft.GsonAgent.nms.reflect.TypeTokenHandle<T>();
		}
	}

	protected TypeToken(final TypeTokenAbstract<T> internal) {
		this.internal = internal;
	}

	public static <T> TypeToken<T> get(final Class<T> type) {
		if (GsonAgent.newVersion) {
			return new TypeToken(cn.citycraft.GsonAgent.normal.reflect.TypeTokenHandle.get(type));
		}
		return new TypeToken(cn.citycraft.GsonAgent.nms.reflect.TypeTokenHandle.get(type));
	}

	public static TypeToken<?> get(final Type type) {
		if (GsonAgent.newVersion) {
			return new TypeToken(cn.citycraft.GsonAgent.normal.reflect.TypeTokenHandle.get(type));
		}
		return new TypeToken(cn.citycraft.GsonAgent.nms.reflect.TypeTokenHandle.get(type));
	}

	@Override
	public boolean equals(final Object o) {
		return this.internal.equals(o);
	}

	public Object getHandle() {
		return this.internal.getHandle();
	}

	public Class<? super T> getRawType() {
		return this.internal.getRawType();
	}

	public Type getType() {
		return this.internal.getType();
	}

	@Override
	public int hashCode() {
		return this.internal.hashCode();
	}

	@Deprecated
	public boolean isAssignableFrom(final Class<?> cls) {
		return this.internal.isAssignableFrom(cls);
	}

	@Deprecated
	public boolean isAssignableFrom(final Type from) {
		return this.internal.isAssignableFrom(from);
	}

	@Deprecated
	public boolean isAssignableFrom(final TypeToken<?> token) {
		return this.internal.isAssignableFrom(token);
	}

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

}
