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> eid, final ReloadableResourceManager aba, final String string) {
        super(eid);
        this.typeHatCache = (Object2ObjectMap<VillagerType, VillagerMetaDataSection.Hat>)new Object2ObjectOpenHashMap();
        this.professionHatCache = (Object2ObjectMap<VillagerProfession, VillagerMetaDataSection.Hat>)new Object2ObjectOpenHashMap();
        this.resourceManager = aba;
        this.path = string;
        aba.registerReloadListener(this);
    }
    
    @Override
    public void render(final PoseStack dhl, final MultiBufferSource ebz, final int integer, final T aoy, final float float5, final float float6, final float float7, final float float8, final float float9, final float float10) {
        if (((Entity)aoy).isInvisible()) {
            return;
        }
        final VillagerData bdq12 = ((VillagerDataHolder)aoy).getVillagerData();
        final VillagerType bdu13 = bdq12.getType();
        final VillagerProfession bds14 = bdq12.getProfession();
        final VillagerMetaDataSection.Hat a15 = this.<VillagerType>getHatData(this.typeHatCache, "type", Registry.VILLAGER_TYPE, bdu13);
        final VillagerMetaDataSection.Hat a16 = this.<VillagerProfession>getHatData(this.professionHatCache, "profession", Registry.VILLAGER_PROFESSION, bds14);
        final M dvv17 = this.getParentModel();
        ((VillagerHeadModel)dvv17).hatVisible(a16 == VillagerMetaDataSection.Hat.NONE || (a16 == VillagerMetaDataSection.Hat.PARTIAL && a15 != VillagerMetaDataSection.Hat.FULL));
        final ResourceLocation uh18 = this.getResourceLocation("type", Registry.VILLAGER_TYPE.getKey(bdu13));
        RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dvv17, uh18, dhl, ebz, integer, aoy, 1.0f, 1.0f, 1.0f);
        ((VillagerHeadModel)dvv17).hatVisible(true);
        if (bds14 != VillagerProfession.NONE && !((LivingEntity)aoy).isBaby()) {
            final ResourceLocation uh19 = this.getResourceLocation("profession", Registry.VILLAGER_PROFESSION.getKey(bds14));
            RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dvv17, uh19, dhl, ebz, integer, aoy, 1.0f, 1.0f, 1.0f);
            if (bds14 != VillagerProfession.NITWIT) {
                final ResourceLocation uh20 = this.getResourceLocation("profession_level", (ResourceLocation)VillagerProfessionLayer.LEVEL_LOCATIONS.get(Mth.clamp(bdq12.getLevel(), 1, VillagerProfessionLayer.LEVEL_LOCATIONS.size())));
                RenderLayer.<T>renderColoredCutoutModel((net.minecraft.client.model.EntityModel<T>)dvv17, uh20, dhl, ebz, integer, aoy, 1.0f, 1.0f, 1.0f);
            }
        }
    }
    
    private ResourceLocation getResourceLocation(final String string, final ResourceLocation uh) {
        return new ResourceLocation(uh.getNamespace(), "textures/entity/" + this.path + "/" + string + "/" + uh.getPath() + ".png");
    }
    
    public <K> VillagerMetaDataSection.Hat getHatData(final Object2ObjectMap<K, VillagerMetaDataSection.Hat> object2ObjectMap, final String string, final DefaultedRegistry<K> fy, final K object) {
        Resource abb6;
        VillagerMetaDataSection emx8;
        final VillagerMetaDataSection.Hat hat;
        final Throwable t2;
        return (VillagerMetaDataSection.Hat)object2ObjectMap.computeIfAbsent(object, object4 -> {
            try {
                abb6 = this.resourceManager.getResource(this.getResourceLocation(string, fy.getKey(object)));
                try {
                    emx8 = abb6.<VillagerMetaDataSection>getMetadata((MetadataSectionSerializer<VillagerMetaDataSection>)VillagerMetaDataSection.SERIALIZER);
                    if (emx8 != null) {
                        emx8.getHat();
                        return hat;
                    }
                }
                catch (Throwable t) {
                    throw t;
                }
                finally {
                    if (abb6 != null) {
                        if (t2 != null) {
                            try {
                                abb6.close();
                            }
                            catch (Throwable exception) {
                                t2.addSuppressed(exception);
                            }
                        }
                        else {
                            abb6.close();
                        }
                    }
                }
            }
            catch (IOException ex) {}
            return VillagerMetaDataSection.Hat.NONE;
        });
    }
    
    @Override
    public void onResourceManagerReload(final ResourceManager abc) {
        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"));
        });
    }
}
