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

import com.google.common.collect.Maps;
import net.minecraft.world.entity.Entity;
import java.util.function.Function;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.RenderType;
import javax.annotation.Nullable;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.DyeableArmorItem;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.resources.ResourceLocation;
import java.util.Map;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.world.entity.LivingEntity;

public class HumanoidArmorLayer<T extends LivingEntity, M extends HumanoidModel<T>, A extends HumanoidModel<T>> extends RenderLayer<T, M> {
    private static final Map<String, ResourceLocation> ARMOR_LOCATION_CACHE;
    private final A innerModel;
    private final A outerModel;
    
    public HumanoidArmorLayer(final RenderLayerParent<T, M> eid, final A dwf2, final A dwf3) {
        super(eid);
        this.innerModel = dwf2;
        this.outerModel = dwf3;
    }
    
    @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) {
        this.renderArmorPiece(dhl, ebz, aoy, EquipmentSlot.CHEST, integer, this.getArmorModel(EquipmentSlot.CHEST));
        this.renderArmorPiece(dhl, ebz, aoy, EquipmentSlot.LEGS, integer, this.getArmorModel(EquipmentSlot.LEGS));
        this.renderArmorPiece(dhl, ebz, aoy, EquipmentSlot.FEET, integer, this.getArmorModel(EquipmentSlot.FEET));
        this.renderArmorPiece(dhl, ebz, aoy, EquipmentSlot.HEAD, integer, this.getArmorModel(EquipmentSlot.HEAD));
    }
    
    private void renderArmorPiece(final PoseStack dhl, final MultiBufferSource ebz, final T aoy, final EquipmentSlot aor, final int integer, final A dwf) {
        final ItemStack bki8 = aoy.getItemBySlot(aor);
        if (!(bki8.getItem() instanceof ArmorItem)) {
            return;
        }
        final ArmorItem bid9 = (ArmorItem)bki8.getItem();
        if (bid9.getSlot() != aor) {
            return;
        }
        this.getParentModel().copyPropertiesTo(dwf);
        this.setPartVisibility(dwf, aor);
        final boolean boolean10 = this.usesInnerModel(aor);
        final boolean boolean11 = bki8.hasFoil();
        if (bid9 instanceof DyeableArmorItem) {
            final int integer2 = ((DyeableArmorItem)bid9).getColor(bki8);
            final float float13 = (integer2 >> 16 & 0xFF) / 255.0f;
            final float float14 = (integer2 >> 8 & 0xFF) / 255.0f;
            final float float15 = (integer2 & 0xFF) / 255.0f;
            this.renderModel(dhl, ebz, integer, bid9, boolean11, dwf, boolean10, float13, float14, float15, null);
            this.renderModel(dhl, ebz, integer, bid9, boolean11, dwf, boolean10, 1.0f, 1.0f, 1.0f, "overlay");
        }
        else {
            this.renderModel(dhl, ebz, integer, bid9, boolean11, dwf, boolean10, 1.0f, 1.0f, 1.0f, null);
        }
    }
    
    protected void setPartVisibility(final A dwf, final EquipmentSlot aor) {
        dwf.setAllVisible(false);
        switch (aor) {
            case HEAD: {
                dwf.head.visible = true;
                dwf.hat.visible = true;
                break;
            }
            case CHEST: {
                dwf.body.visible = true;
                dwf.rightArm.visible = true;
                dwf.leftArm.visible = true;
                break;
            }
            case LEGS: {
                dwf.body.visible = true;
                dwf.rightLeg.visible = true;
                dwf.leftLeg.visible = true;
                break;
            }
            case FEET: {
                dwf.rightLeg.visible = true;
                dwf.leftLeg.visible = true;
                break;
            }
        }
    }
    
    private void renderModel(final PoseStack dhl, final MultiBufferSource ebz, final int integer, final ArmorItem bid, final boolean boolean5, final A dwf, final boolean boolean7, final float float8, final float float9, final float float10, @Nullable final String string) {
        final VertexConsumer dhp13 = ItemRenderer.getArmorFoilBuffer(ebz, RenderType.armorCutoutNoCull(this.getArmorLocation(bid, boolean7, string)), false, boolean5);
        dwf.renderToBuffer(dhl, dhp13, integer, OverlayTexture.NO_OVERLAY, float8, float9, float10, 1.0f);
    }
    
    private A getArmorModel(final EquipmentSlot aor) {
        return this.usesInnerModel(aor) ? this.innerModel : this.outerModel;
    }
    
    private boolean usesInnerModel(final EquipmentSlot aor) {
        return aor == EquipmentSlot.LEGS;
    }
    
    private ResourceLocation getArmorLocation(final ArmorItem bid, final boolean boolean2, @Nullable final String string) {
        final String string2 = "textures/models/armor/" + bid.getMaterial().getName() + "_layer_" + (boolean2 ? 2 : 1) + ((string == null) ? "" : ("_" + string)) + ".png";
        return HumanoidArmorLayer.ARMOR_LOCATION_CACHE.computeIfAbsent(string2, ResourceLocation::new);
    }
    
    static {
        ARMOR_LOCATION_CACHE = Maps.newHashMap();
    }
}
