Volver al índice

src/main/java/ar/com/companeros/flags/BannerDesign.java

package ar.com.companeros.flags;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.Locale;
import java.util.Set;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.entity.BannerPattern;
import net.minecraft.world.level.block.entity.BannerPatterns;

/** Diseño acotado: un círculo y, opcionalmente, un patrón geométrico vanilla. */
public record BannerDesign(DyeColor baseColor, DyeColor circleColor, Symbol symbol, DyeColor symbolColor) {
    private static final Set<String> FIELDS = Set.of("baseColor", "circleColor", "symbol", "symbolColor");

    // Cada símbolo usa un único tinte y nunca necesita plantillas especiales.
    public enum Symbol {
        NONE(null), STRIPE_CENTER(BannerPatterns.STRIPE_CENTER), STRIPE_MIDDLE(BannerPatterns.STRIPE_MIDDLE),
        STRIPE_DOWNRIGHT(BannerPatterns.STRIPE_DOWNRIGHT), STRIPE_DOWNLEFT(BannerPatterns.STRIPE_DOWNLEFT),
        CROSS(BannerPatterns.CROSS), STRAIGHT_CROSS(BannerPatterns.STRAIGHT_CROSS),
        TRIANGLE_BOTTOM(BannerPatterns.TRIANGLE_BOTTOM), TRIANGLE_TOP(BannerPatterns.TRIANGLE_TOP),
        RHOMBUS_MIDDLE(BannerPatterns.RHOMBUS_MIDDLE), BORDER(BannerPatterns.BORDER);
        final ResourceKey<BannerPattern> pattern;
        Symbol(ResourceKey<BannerPattern> pattern) { this.pattern = pattern; }
        public String inputName() { return name().toLowerCase(Locale.ROOT); }
    }

    public BannerDesign {
        if (baseColor == null || circleColor == null || symbol == null || symbol != Symbol.NONE && symbolColor == null)
            throw new IllegalArgumentException("Diseño incompleto");
        if (symbol == Symbol.NONE) symbolColor = null;
    }

    // No se aceptan NBT, comandos ni campos adicionales provenientes del agente.
    public static BannerDesign parse(JsonObject input) {
        if (input == null || !FIELDS.containsAll(input.keySet())) throw new IllegalArgumentException("Campos de diseño inválidos");
        DyeColor base = color(text(input, "baseColor"));
        DyeColor circle = color(text(input, "circleColor"));
        Symbol symbol = input.has("symbol") ? Symbol.valueOf(text(input, "symbol").toUpperCase(Locale.ROOT)) : Symbol.NONE;
        DyeColor ink = input.has("symbolColor") ? color(text(input, "symbolColor")) : null;
        return new BannerDesign(base, circle, symbol, ink);
    }

    public static BannerDesign fromTag(CompoundTag tag) {
        if (!FIELDS.containsAll(tag.getAllKeys())) throw new IllegalArgumentException("Campos guardados de diseño inválidos");
        JsonObject input = new JsonObject();
        for (String key : FIELDS) if (tag.contains(key, 8)) input.addProperty(key, tag.getString(key));
        return parse(input);
    }

    public CompoundTag toTag() {
        CompoundTag tag = new CompoundTag();
        tag.putString("baseColor", baseColor.getName());
        tag.putString("circleColor", circleColor.getName());
        tag.putString("symbol", symbol.inputName());
        if (symbolColor != null) tag.putString("symbolColor", symbolColor.getName());
        return tag;
    }

    public ListTag patterns() {
        var builder = new BannerPattern.Builder().addPattern(BannerPatterns.CIRCLE_MIDDLE, circleColor);
        if (symbol != Symbol.NONE) builder.addPattern(symbol.pattern, symbolColor);
        return builder.toListTag();
    }

    private static String text(JsonObject input, String key) {
        JsonElement value = input.get(key);
        if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString())
            throw new IllegalArgumentException("Se necesita un nombre para " + key);
        return value.getAsString();
    }
    private static DyeColor color(String name) {
        DyeColor color = DyeColor.byName(name, null);
        if (color == null) throw new IllegalArgumentException("Color desconocido");
        return color;
    }
}