package net.minecraft.client.renderer.entity;

import com.google.common.collect.Sets;
import net.minecraft.server.packs.resources.ResourceManager;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.client.player.LocalPlayer;
import com.mojang.blaze3d.vertex.BufferBuilder;
import net.minecraft.util.Mth;
import com.mojang.blaze3d.vertex.Tesselator;
import net.minecraft.client.gui.Font;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.CrashReport;
import net.minecraft.client.renderer.texture.OverlayTexture;
import com.mojang.blaze3d.platform.Lighting;
import net.minecraft.client.Minecraft;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.texture.TextureAtlas;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.LivingEntity;
import javax.annotation.Nullable;
import net.minecraft.world.level.Level;
import net.minecraft.client.renderer.block.model.BakedQuad;
import java.util.List;
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
import com.mojang.blaze3d.vertex.VertexMultiConsumer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.block.Block;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.world.level.block.StainedGlassPaneBlock;
import net.minecraft.world.level.block.HalfTransparentBlock;
import net.minecraft.world.item.BlockItem;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.world.item.Items;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.Direction;
import java.util.Random;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.item.ItemStack;
import net.minecraft.client.resources.model.BakedModel;
import java.util.Iterator;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.Registry;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.ItemModelShaper;
import net.minecraft.world.item.Item;
import java.util.Set;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;

public class ItemRenderer implements ResourceManagerReloadListener {
    public static final ResourceLocation ENCHANT_GLINT_LOCATION;
    private static final Set<Item> IGNORED;
    public float blitOffset;
    private final ItemModelShaper itemModelShaper;
    private final TextureManager textureManager;
    private final ItemColors itemColors;
    
    public ItemRenderer(final TextureManager elw, final ModelManager enm, final ItemColors dmr) {
        this.textureManager = elw;
        this.itemModelShaper = new ItemModelShaper(enm);
        for (final Item bke6 : Registry.ITEM) {
            if (!ItemRenderer.IGNORED.contains(bke6)) {
                this.itemModelShaper.register(bke6, new ModelResourceLocation(Registry.ITEM.getKey(bke6), "inventory"));
            }
        }
        this.itemColors = dmr;
    }
    
    public ItemModelShaper getItemModelShaper() {
        return this.itemModelShaper;
    }
    
    private void renderModelLists(final BakedModel enh, final ItemStack bki, final int integer3, final int integer4, final PoseStack dhl, final VertexConsumer dhp) {
        final Random random8 = new Random();
        final long long9 = 42L;
        for (final Direction fz14 : Direction.values()) {
            random8.setSeed(42L);
            this.renderQuadList(dhl, dhp, enh.getQuads(null, fz14, random8), bki, integer3, integer4);
        }
        random8.setSeed(42L);
        this.renderQuadList(dhl, dhp, enh.getQuads(null, null, random8), bki, integer3, integer4);
    }
    
    public void render(final ItemStack bki, final ItemTransforms.TransformType b, final boolean boolean3, final PoseStack dhl, final MultiBufferSource ebz, final int integer6, final int integer7, BakedModel enh) {
        if (bki.isEmpty()) {
            return;
        }
        dhl.pushPose();
        final boolean boolean4 = b == ItemTransforms.TransformType.GUI || b == ItemTransforms.TransformType.GROUND || b == ItemTransforms.TransformType.FIXED;
        if (bki.getItem() == Items.TRIDENT && boolean4) {
            enh = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation("minecraft:trident#inventory"));
        }
        enh.getTransforms().getTransform(b).apply(boolean3, dhl);
        dhl.translate(-0.5, -0.5, -0.5);
        if (enh.isCustomRenderer() || (bki.getItem() == Items.TRIDENT && !boolean4)) {
            BlockEntityWithoutLevelRenderer.instance.renderByItem(bki, b, dhl, ebz, integer6, integer7);
        }
        else {
            boolean boolean5;
            if (b != ItemTransforms.TransformType.GUI && !b.firstPerson() && bki.getItem() instanceof BlockItem) {
                final Block bvr12 = ((BlockItem)bki.getItem()).getBlock();
                boolean5 = (!(bvr12 instanceof HalfTransparentBlock) && !(bvr12 instanceof StainedGlassPaneBlock));
            }
            else {
                boolean5 = true;
            }
            final RenderType ech12 = ItemBlockRenderTypes.getRenderType(bki, boolean5);
            VertexConsumer dhp13;
            if (bki.getItem() == Items.COMPASS && bki.hasFoil()) {
                dhl.pushPose();
                final PoseStack.Pose a14 = dhl.last();
                if (b == ItemTransforms.TransformType.GUI) {
                    a14.pose().multiply(0.5f);
                }
                else if (b.firstPerson()) {
                    a14.pose().multiply(0.75f);
                }
                if (boolean5) {
                    dhp13 = getCompassFoilBufferDirect(ebz, ech12, a14);
                }
                else {
                    dhp13 = getCompassFoilBuffer(ebz, ech12, a14);
                }
                dhl.popPose();
            }
            else if (boolean5) {
                dhp13 = getFoilBufferDirect(ebz, ech12, true, bki.hasFoil());
            }
            else {
                dhp13 = getFoilBuffer(ebz, ech12, true, bki.hasFoil());
            }
            this.renderModelLists(enh, bki, integer6, integer7, dhl, dhp13);
        }
        dhl.popPose();
    }
    
    public static VertexConsumer getArmorFoilBuffer(final MultiBufferSource ebz, final RenderType ech, final boolean boolean3, final boolean boolean4) {
        if (boolean4) {
            return VertexMultiConsumer.create(ebz.getBuffer(boolean3 ? RenderType.armorGlint() : RenderType.armorEntityGlint()), ebz.getBuffer(ech));
        }
        return ebz.getBuffer(ech);
    }
    
    public static VertexConsumer getCompassFoilBuffer(final MultiBufferSource ebz, final RenderType ech, final PoseStack.Pose a) {
        return VertexMultiConsumer.create(new SheetedDecalTextureGenerator(ebz.getBuffer(RenderType.glint()), a.pose(), a.normal()), ebz.getBuffer(ech));
    }
    
    public static VertexConsumer getCompassFoilBufferDirect(final MultiBufferSource ebz, final RenderType ech, final PoseStack.Pose a) {
        return VertexMultiConsumer.create(new SheetedDecalTextureGenerator(ebz.getBuffer(RenderType.glintDirect()), a.pose(), a.normal()), ebz.getBuffer(ech));
    }
    
    public static VertexConsumer getFoilBuffer(final MultiBufferSource ebz, final RenderType ech, final boolean boolean3, final boolean boolean4) {
        if (boolean4) {
            return VertexMultiConsumer.create(ebz.getBuffer(boolean3 ? RenderType.glint() : RenderType.entityGlint()), ebz.getBuffer(ech));
        }
        return ebz.getBuffer(ech);
    }
    
    public static VertexConsumer getFoilBufferDirect(final MultiBufferSource ebz, final RenderType ech, final boolean boolean3, final boolean boolean4) {
        if (boolean4) {
            return VertexMultiConsumer.create(ebz.getBuffer(boolean3 ? RenderType.glintDirect() : RenderType.entityGlintDirect()), ebz.getBuffer(ech));
        }
        return ebz.getBuffer(ech);
    }
    
    private void renderQuadList(final PoseStack dhl, final VertexConsumer dhp, final List<BakedQuad> list, final ItemStack bki, final int integer5, final int integer6) {
        final boolean boolean8 = !bki.isEmpty();
        final PoseStack.Pose a9 = dhl.last();
        for (final BakedQuad ect11 : list) {
            int integer7 = -1;
            if (boolean8 && ect11.isTinted()) {
                integer7 = this.itemColors.getColor(bki, ect11.getTintIndex());
            }
            final float float13 = (integer7 >> 16 & 0xFF) / 255.0f;
            final float float14 = (integer7 >> 8 & 0xFF) / 255.0f;
            final float float15 = (integer7 & 0xFF) / 255.0f;
            dhp.putBulkData(a9, ect11, float13, float14, float15, integer5, integer6);
        }
    }
    
    public BakedModel getModel(final ItemStack bki, @Nullable final Level bqb, @Nullable final LivingEntity aoy) {
        final Item bke6 = bki.getItem();
        BakedModel enh5;
        if (bke6 == Items.TRIDENT) {
            enh5 = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation("minecraft:trident_in_hand#inventory"));
        }
        else {
            enh5 = this.itemModelShaper.getItemModel(bki);
        }
        final ClientLevel dym7 = (bqb instanceof ClientLevel) ? ((ClientLevel)bqb) : null;
        final BakedModel enh6 = enh5.getOverrides().resolve(enh5, bki, dym7, aoy);
        return (enh6 == null) ? this.itemModelShaper.getModelManager().getMissingModel() : enh6;
    }
    
    public void renderStatic(final ItemStack bki, final ItemTransforms.TransformType b, final int integer3, final int integer4, final PoseStack dhl, final MultiBufferSource ebz) {
        this.renderStatic(null, bki, b, false, dhl, ebz, null, integer3, integer4);
    }
    
    public void renderStatic(@Nullable final LivingEntity aoy, final ItemStack bki, final ItemTransforms.TransformType b, final boolean boolean4, final PoseStack dhl, final MultiBufferSource ebz, @Nullable final Level bqb, final int integer8, final int integer9) {
        if (bki.isEmpty()) {
            return;
        }
        final BakedModel enh11 = this.getModel(bki, bqb, aoy);
        this.render(bki, b, boolean4, dhl, ebz, integer8, integer9, enh11);
    }
    
    public void renderGuiItem(final ItemStack bki, final int integer2, final int integer3) {
        this.renderGuiItem(bki, integer2, integer3, this.getModel(bki, null, null));
    }
    
    protected void renderGuiItem(final ItemStack bki, final int integer2, final int integer3, final BakedModel enh) {
        RenderSystem.pushMatrix();
        this.textureManager.bind(TextureAtlas.LOCATION_BLOCKS);
        this.textureManager.getTexture(TextureAtlas.LOCATION_BLOCKS).setFilter(false, false);
        RenderSystem.enableRescaleNormal();
        RenderSystem.enableAlphaTest();
        RenderSystem.defaultAlphaFunc();
        RenderSystem.enableBlend();
        RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
        RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
        RenderSystem.translatef((float)integer2, (float)integer3, 100.0f + this.blitOffset);
        RenderSystem.translatef(8.0f, 8.0f, 0.0f);
        RenderSystem.scalef(1.0f, -1.0f, 1.0f);
        RenderSystem.scalef(16.0f, 16.0f, 16.0f);
        final PoseStack dhl6 = new PoseStack();
        final MultiBufferSource.BufferSource a7 = Minecraft.getInstance().renderBuffers().bufferSource();
        final boolean boolean8 = !enh.usesBlockLight();
        if (boolean8) {
            Lighting.setupForFlatItems();
        }
        this.render(bki, ItemTransforms.TransformType.GUI, false, dhl6, a7, 15728880, OverlayTexture.NO_OVERLAY, enh);
        a7.endBatch();
        RenderSystem.enableDepthTest();
        if (boolean8) {
            Lighting.setupFor3DItems();
        }
        RenderSystem.disableAlphaTest();
        RenderSystem.disableRescaleNormal();
        RenderSystem.popMatrix();
    }
    
    public void renderAndDecorateItem(final ItemStack bki, final int integer2, final int integer3) {
        this.tryRenderGuiItem(Minecraft.getInstance().player, bki, integer2, integer3);
    }
    
    public void renderAndDecorateFakeItem(final ItemStack bki, final int integer2, final int integer3) {
        this.tryRenderGuiItem(null, bki, integer2, integer3);
    }
    
    public void renderAndDecorateItem(final LivingEntity aoy, final ItemStack bki, final int integer3, final int integer4) {
        this.tryRenderGuiItem(aoy, bki, integer3, integer4);
    }
    
    private void tryRenderGuiItem(@Nullable final LivingEntity aoy, final ItemStack bki, final int integer3, final int integer4) {
        if (bki.isEmpty()) {
            return;
        }
        this.blitOffset += 50.0f;
        try {
            this.renderGuiItem(bki, integer3, integer4, this.getModel(bki, null, aoy));
        }
        catch (Throwable throwable6) {
            final CrashReport j7 = CrashReport.forThrowable(throwable6, "Rendering item");
            final CrashReportCategory k8 = j7.addCategory("Item being rendered");
            k8.setDetail("Item Type", () -> String.valueOf(bki.getItem()));
            k8.setDetail("Item Damage", () -> String.valueOf(bki.getDamageValue()));
            k8.setDetail("Item NBT", () -> String.valueOf(bki.getTag()));
            k8.setDetail("Item Foil", () -> String.valueOf(bki.hasFoil()));
            throw new ReportedException(j7);
        }
        this.blitOffset -= 50.0f;
    }
    
    public void renderGuiItemDecorations(final Font dmt, final ItemStack bki, final int integer3, final int integer4) {
        this.renderGuiItemDecorations(dmt, bki, integer3, integer4, null);
    }
    
    public void renderGuiItemDecorations(final Font dmt, final ItemStack bki, final int integer3, final int integer4, @Nullable final String string) {
        if (bki.isEmpty()) {
            return;
        }
        final PoseStack dhl7 = new PoseStack();
        if (bki.getCount() != 1 || string != null) {
            final String string2 = (string == null) ? String.valueOf(bki.getCount()) : string;
            dhl7.translate(0.0, 0.0, this.blitOffset + 200.0f);
            final MultiBufferSource.BufferSource a9 = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
            dmt.drawInBatch(string2, (float)(integer3 + 19 - 2 - dmt.width(string2)), (float)(integer4 + 6 + 3), 16777215, true, dhl7.last().pose(), a9, false, 0, 15728880);
            a9.endBatch();
        }
        if (bki.isDamaged()) {
            RenderSystem.disableDepthTest();
            RenderSystem.disableTexture();
            RenderSystem.disableAlphaTest();
            RenderSystem.disableBlend();
            final Tesselator dhn8 = Tesselator.getInstance();
            final BufferBuilder dhg9 = dhn8.getBuilder();
            final float float10 = (float)bki.getDamageValue();
            final float float11 = (float)bki.getMaxDamage();
            final float float12 = Math.max(0.0f, (float11 - float10) / float11);
            final int integer5 = Math.round(13.0f - float10 * 13.0f / float11);
            final int integer6 = Mth.hsvToRgb(float12 / 3.0f, 1.0f, 1.0f);
            this.fillRect(dhg9, integer3 + 2, integer4 + 13, 13, 2, 0, 0, 0, 255);
            this.fillRect(dhg9, integer3 + 2, integer4 + 13, integer5, 1, integer6 >> 16 & 0xFF, integer6 >> 8 & 0xFF, integer6 & 0xFF, 255);
            RenderSystem.enableBlend();
            RenderSystem.enableAlphaTest();
            RenderSystem.enableTexture();
            RenderSystem.enableDepthTest();
        }
        final LocalPlayer ebf8 = Minecraft.getInstance().player;
        final float float13 = (ebf8 == null) ? 0.0f : ebf8.getCooldowns().getCooldownPercent(bki.getItem(), Minecraft.getInstance().getFrameTime());
        if (float13 > 0.0f) {
            RenderSystem.disableDepthTest();
            RenderSystem.disableTexture();
            RenderSystem.enableBlend();
            RenderSystem.defaultBlendFunc();
            final Tesselator dhn9 = Tesselator.getInstance();
            final BufferBuilder dhg10 = dhn9.getBuilder();
            this.fillRect(dhg10, integer3, integer4 + Mth.floor(16.0f * (1.0f - float13)), 16, Mth.ceil(16.0f * float13), 255, 255, 255, 127);
            RenderSystem.enableTexture();
            RenderSystem.enableDepthTest();
        }
    }
    
    private void fillRect(final BufferBuilder dhg, final int integer2, final int integer3, final int integer4, final int integer5, final int integer6, final int integer7, final int integer8, final int integer9) {
        dhg.begin(7, DefaultVertexFormat.POSITION_COLOR);
        dhg.vertex(integer2 + 0, integer3 + 0, 0.0).color(integer6, integer7, integer8, integer9).endVertex();
        dhg.vertex(integer2 + 0, integer3 + integer5, 0.0).color(integer6, integer7, integer8, integer9).endVertex();
        dhg.vertex(integer2 + integer4, integer3 + integer5, 0.0).color(integer6, integer7, integer8, integer9).endVertex();
        dhg.vertex(integer2 + integer4, integer3 + 0, 0.0).color(integer6, integer7, integer8, integer9).endVertex();
        Tesselator.getInstance().end();
    }
    
    @Override
    public void onResourceManagerReload(final ResourceManager abc) {
        this.itemModelShaper.rebuildCache();
    }
    
    static {
        ENCHANT_GLINT_LOCATION = new ResourceLocation("textures/misc/enchanted_item_glint.png");
        IGNORED = Sets.<Item>newHashSet(Items.AIR);
    }
}
