package net.minecraft.client.renderer.entity.layers;

import net.minecraft.Util;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.Resource;
import java.io.IOException;
import net.minecraft.server.packs.metadata.MetadataSectionSerializer;
import net.minecraft.core.DefaultedRegistry;
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.util.Mth;
import net.minecraft.client.model.VillagerHeadModel;
import net.minecraft.core.Registry;
import net.minecraft.world.entity.npc.VillagerDataHolder;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.client.resources.metadata.animation.VillagerMetaDataSection;
import net.minecraft.world.entity.npc.VillagerType;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import net.minecraft.resources.ResourceLocation;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;

public class VillagerProfessionLayer<T extends LivingEntity, M extends EntityModel> extends RenderLayer<T, M> implements ResourceManagerReloadListener {
    private static final Int2ObjectMap<ResourceLocation> LEVEL_LOCATIONS;
    private final Object2ObjectMap<VillagerType, VillagerMetaDataSection.Hat> typeHatCache;
    private final Object2ObjectMap<VillagerProfession, VillagerMetaDataSection.Hat> professionHatCache;
    private final ReloadableResourceManager resourceManager;
    private final String path;
    
    public VillagerProfessionLayer(final RenderLayerParent<T, M> dwv, final ReloadableResourceManager yz, final String string) {
        super(dwv);
        this.typeHatCache = (Object2ObjectMap<VillagerType, VillagerMetaDataSection.Hat>)new Object2ObjectOpenHashMap();
        this.professionHatCache = (Object2ObjectMap<VillagerProfession, VillagerMetaDataSection.Hat>)new Object2ObjectOpenHashMap();
        this.resourceManager = yz;
        this.path = string;
        yz.registerReloadListener(this);
    }
    
    @Override
    public void render(final PoseStack cyl, final MultiBufferSource dqt, final int integer, final T akz, final float float5, final float float6, final float float7, final float float8, final float float9, final float float10) {
        if (((Entity)akz).isInvisible()) {
            return;
        }
        final VillagerData axx12 = ((VillagerDataHolder)akz).getVillagerData();
        final VillagerType ayb13 = axx12.getType();
        final VillagerProfession axz14 = axx12.getProfession();
        final VillagerMetaDataSection.Hat a15 = this.<VillagerType>getHatData(this.typeHatCache, "type", Registry.VILLAGER_TYPE, ayb13);
        final VillagerMetaDataSection.Hat a16 = this.<VillagerProfession>getHatData(this.professionHatCache, "profession", Registry.VILLAGER_PROFESSION, axz14);
        final M dla17 = this.getParentModel();
        ((VillagerHeadModel)dla17).hatVisible(a16 == VillagerMetaDataSection.Hat.NONE || (a16 == VillagerMetaDataSection.Hat.PARTIAL && a15 != VillagerMetaDataSection.Hat.FULL));
        final ResourceLocation sm18 = this.getResourceLocation("type", Registry.VILLAGER_TYPE.getKey(ayb13));
        RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dla17, sm18, cyl, dqt, integer, akz, 1.0f, 1.0f, 1.0f);
        ((VillagerHeadModel)dla17).hatVisible(true);
        if (axz14 != VillagerProfession.NONE && !((LivingEntity)akz).isBaby()) {
            final ResourceLocation sm19 = this.getResourceLocation("profession", Registry.VILLAGER_PROFESSION.getKey(axz14));
            RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dla17, sm19, cyl, dqt, integer, akz, 1.0f, 1.0f, 1.0f);
            if (axz14 != VillagerProfession.NITWIT) {
                final ResourceLocation sm20 = this.getResourceLocation("profession_level", (ResourceLocation)VillagerProfessionLayer.LEVEL_LOCATIONS.get(Mth.clamp(axx12.getLevel(), 1, VillagerProfessionLayer.LEVEL_LOCATIONS.size())));
                RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dla17, sm20, cyl, dqt, integer, akz, 1.0f, 1.0f, 1.0f);
            }
        }
    }
    
    private ResourceLocation getResourceLocation(final String string, final ResourceLocation sm) {
        return new ResourceLocation(sm.getNamespace(), "textures/entity/" + this.path + "/" + string + "/" + sm.getPath() + ".png");
    }
    
    public <K> VillagerMetaDataSection.Hat getHatData(final Object2ObjectMap<K, VillagerMetaDataSection.Hat> object2ObjectMap, final String string, final DefaultedRegistry<K> fo, final K object) {
        Resource za6;
        VillagerMetaDataSection ebl8;
        final VillagerMetaDataSection.Hat hat;
        final Throwable t2;
        return (VillagerMetaDataSection.Hat)object2ObjectMap.computeIfAbsent(object, object4 -> {
            try {
                za6 = this.resourceManager.getResource(this.getResourceLocation(string, fo.getKey(object)));
                try {
                    ebl8 = za6.<VillagerMetaDataSection>getMetadata((MetadataSectionSerializer<VillagerMetaDataSection>)VillagerMetaDataSection.SERIALIZER);
                    if (ebl8 != null) {
                        ebl8.getHat();
                        return hat;
                    }
                }
                catch (Throwable t) {
                    throw t;
                }
                finally {
                    if (za6 != null) {
                        if (t2 != null) {
                            try {
                                za6.close();
                            }
                            catch (Throwable exception) {
                                t2.addSuppressed(exception);
                            }
                        }
                        else {
                            za6.close();
                        }
                    }
                }
            }
            catch (IOException ex) {}
            return VillagerMetaDataSection.Hat.NONE;
        });
    }
    
    @Override
    public void onResourceManagerReload(final ResourceManager zb) {
        this.professionHatCache.clear();
        this.typeHatCache.clear();
    }
    
    static {
        LEVEL_LOCATIONS = Util.<Int2ObjectMap>make((Int2ObjectMap)new Int2ObjectOpenHashMap(), int2ObjectOpenHashMap -> {
            int2ObjectOpenHashMap.put(1, new ResourceLocation("stone"));
            int2ObjectOpenHashMap.put(2, new ResourceLocation("iron"));
            int2ObjectOpenHashMap.put(3, new ResourceLocation("gold"));
            int2ObjectOpenHashMap.put(4, new ResourceLocation("emerald"));
            int2ObjectOpenHashMap.put(5, new ResourceLocation("diamond"));
        });
    }
}
