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 abstract class AbstractArmorLayer<T extends LivingEntity, M extends HumanoidModel<T>, A extends HumanoidModel<T>> extends RenderLayer<T, M> {
    protected final A innerModel;
    protected final A outerModel;
    private static final Map<String, ResourceLocation> ARMOR_LOCATION_CACHE;
    
    protected AbstractArmorLayer(final RenderLayerParent<T, M> dwv, final A dlj2, final A dlj3) {
        super(dwv);
        this.innerModel = dlj2;
        this.outerModel = dlj3;
    }
    
    @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) {
        this.renderArmorPiece(cyl, dqt, akz, float5, float6, float7, float8, float9, float10, EquipmentSlot.CHEST, integer);
        this.renderArmorPiece(cyl, dqt, akz, float5, float6, float7, float8, float9, float10, EquipmentSlot.LEGS, integer);
        this.renderArmorPiece(cyl, dqt, akz, float5, float6, float7, float8, float9, float10, EquipmentSlot.FEET, integer);
        this.renderArmorPiece(cyl, dqt, akz, float5, float6, float7, float8, float9, float10, EquipmentSlot.HEAD, integer);
    }
    
    private void renderArmorPiece(final PoseStack cyl, final MultiBufferSource dqt, final T akz, final float float4, final float float5, final float float6, final float float7, final float float8, final float float9, final EquipmentSlot akv, final int integer) {
        final ItemStack ben13 = akz.getItemBySlot(akv);
        if (!(ben13.getItem() instanceof ArmorItem)) {
            return;
        }
        final ArmorItem bcg14 = (ArmorItem)ben13.getItem();
        if (bcg14.getSlot() != akv) {
            return;
        }
        final A dlj15 = this.getArmorModel(akv);
        this.getParentModel().copyPropertiesTo(dlj15);
        dlj15.prepareMobModel(akz, float4, float5, float6);
        this.setPartVisibility(dlj15, akv);
        dlj15.setupAnim(akz, float4, float5, float7, float8, float9);
        final boolean boolean16 = this.usesInnerModel(akv);
        final boolean boolean17 = ben13.hasFoil();
        if (bcg14 instanceof DyeableArmorItem) {
            final int integer2 = ((DyeableArmorItem)bcg14).getColor(ben13);
            final float float10 = (integer2 >> 16 & 0xFF) / 255.0f;
            final float float11 = (integer2 >> 8 & 0xFF) / 255.0f;
            final float float12 = (integer2 & 0xFF) / 255.0f;
            this.renderModel(cyl, dqt, integer, bcg14, boolean17, dlj15, boolean16, float10, float11, float12, null);
            this.renderModel(cyl, dqt, integer, bcg14, boolean17, dlj15, boolean16, 1.0f, 1.0f, 1.0f, "overlay");
        }
        else {
            this.renderModel(cyl, dqt, integer, bcg14, boolean17, dlj15, boolean16, 1.0f, 1.0f, 1.0f, null);
        }
    }
    
    private void renderModel(final PoseStack cyl, final MultiBufferSource dqt, final int integer, final ArmorItem bcg, final boolean boolean5, final A dlj, final boolean boolean7, final float float8, final float float9, final float float10, @Nullable final String string) {
        final VertexConsumer cyo13 = ItemRenderer.getFoilBuffer(dqt, RenderType.entityCutoutNoCull(this.getArmorLocation(bcg, boolean7, string)), false, boolean5);
        dlj.renderToBuffer(cyl, cyo13, integer, OverlayTexture.NO_OVERLAY, float8, float9, float10, 1.0f);
    }
    
    public A getArmorModel(final EquipmentSlot akv) {
        return this.usesInnerModel(akv) ? this.innerModel : this.outerModel;
    }
    
    private boolean usesInnerModel(final EquipmentSlot akv) {
        return akv == EquipmentSlot.LEGS;
    }
    
    private ResourceLocation getArmorLocation(final ArmorItem bcg, final boolean boolean2, @Nullable final String string) {
        final String string2 = "textures/models/armor/" + bcg.getMaterial().getName() + "_layer_" + (boolean2 ? 2 : 1) + ((string == null) ? "" : ("_" + string)) + ".png";
        return AbstractArmorLayer.ARMOR_LOCATION_CACHE.computeIfAbsent(string2, ResourceLocation::new);
    }
    
    protected abstract void setPartVisibility(final A dlj, final EquipmentSlot akv);
    
    protected abstract void hideAllArmor(final A dlj);
    
    static {
        ARMOR_LOCATION_CACHE = Maps.newHashMap();
    }
}
