package net.glowstone.util.nbt;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;

/**
 * The types of NBT tags that exist.
 */
public enum TagType {

    END("End", null, Void.class),
    BYTE("Byte", ByteTag.class, byte.class),
    SHORT("Short", ShortTag.class, short.class),
    INT("Int", IntTag.class, int.class),
    LONG("Long", LongTag.class, long.class),
    FLOAT("Float", FloatTag.class, float.class),
    DOUBLE("Double", DoubleTag.class, double.class),
    BYTE_ARRAY("Byte_Array", ByteArrayTag.class, byte[].class),
    STRING("String", StringTag.class, String.class),
    // javac complains about this because ListTag is generic
    @SuppressWarnings("unchecked")
    LIST("List", ListTag.class, List.class),
    COMPOUND("Compound", CompoundTag.class, Map.class),
    INT_ARRAY("Int_Array", IntArrayTag.class, int[].class);

    private final String name;
    private final Class<? extends Tag> tagClass;
    private final Class<?> valueClass;

    <V, T extends Tag<? extends V>> TagType(String name, Class<T> tagClass, Class<V> valueClass) {
        // ? extends V is needed to get Compound to work for some reason
        this.name = name;
        this.tagClass = tagClass;
        this.valueClass = valueClass;
    }

    public static TagType byId(int id) {
        if (id < 0 || id >= values().length) {
            return null;
        }
        return values()[id];
    }

    static TagType byIdOrError(int id) throws IOException {
        if (id < 0 || id >= values().length) {
            throw new IOException("Invalid tag type: " + id);
        }
        return values()[id];
    }

    public byte getId() {
        return (byte) ordinal();
    }

    public String getName() {
        return name;
    }

    public Class<? extends Tag> getTagClass() {
        return tagClass;
    }

    public Class<?> getValueClass() {
        return valueClass;
    }

    public Constructor<? extends Tag> getConstructor() throws NoSuchMethodException {
        return tagClass.getConstructor(valueClass);
    }
}

@@ -1302,162 +1302,554 @@
     
-public static TagType byId(int id) %7B%0A        if (id %3C 0 %7C%7C id %3E= values().length) %7B%0A            return null;%0A        %7D%0A        return values()%5Bid%5D;%0A    %7D%0A
+/**%0A     * Returns the tag type with a given ID.%0A     *%0A     * @param id the ID to look up%0A     * @return the tag type with ID %7B@code id%7D, or null if none exists%0A     */%0A    public static TagType byId(int id) %7B%0A        if (id %3C 0 %7C%7C id %3E= values().length) %7B%0A            return null;%0A        %7D%0A        return values()%5Bid%5D;%0A    %7D%0A%0A    /**%0A     * Returns the tag type with a given ID.%0A     *%0A     * @param id the ID to look up%0A     * @return the tag type with ID %7B@code id%7D%0A     * @throws IOException if %7B@code id%7D doesn't match any tag type%0A     */
 %0A   

Fix CheckStyle issues in util/nbt/TagType.java (#786)