package net.minecraft.client.renderer.block;

import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.ItemStack;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.ReportedException;
import net.minecraft.CrashReportCategory;
import net.minecraft.CrashReport;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.world.level.block.RenderShape;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.client.color.block.BlockColors;
import java.util.Random;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;

public class BlockRenderDispatcher implements ResourceManagerReloadListener {
    private final BlockModelShaper blockModelShaper;
    private final ModelBlockRenderer modelRenderer;
    private final LiquidBlockRenderer liquidBlockRenderer;
    private final Random random;
    private final BlockColors blockColors;
    
    public BlockRenderDispatcher(final BlockModelShaper drj, final BlockColors dcb) {
        this.random = new Random();
        this.blockModelShaper = drj;
        this.blockColors = dcb;
        this.modelRenderer = new ModelBlockRenderer(this.blockColors);
        this.liquidBlockRenderer = new LiquidBlockRenderer();
    }
    
    public BlockModelShaper getBlockModelShaper() {
        return this.blockModelShaper;
    }
    
    public void renderBreakingTexture(final BlockState byj, final BlockPos fk, final BlockAndTintGetter bje, final PoseStack cyl, final VertexConsumer cyo) {
        if (byj.getRenderShape() != RenderShape.MODEL) {
            return;
        }
        final BakedModel ebv7 = this.blockModelShaper.getBlockModel(byj);
        final long long8 = byj.getSeed(fk);
        this.modelRenderer.tesselateBlock(bje, ebv7, byj, fk, cyl, cyo, true, this.random, long8, OverlayTexture.NO_OVERLAY);
    }
    
    public boolean renderBatched(final BlockState byj, final BlockPos fk, final BlockAndTintGetter bje, final PoseStack cyl, final VertexConsumer cyo, final boolean boolean6, final Random random) {
        try {
            final RenderShape btr9 = byj.getRenderShape();
            return btr9 == RenderShape.MODEL && this.modelRenderer.tesselateBlock(bje, this.getBlockModel(byj), byj, fk, cyl, cyo, boolean6, random, byj.getSeed(fk), OverlayTexture.NO_OVERLAY);
        }
        catch (Throwable throwable9) {
            final CrashReport h10 = CrashReport.forThrowable(throwable9, "Tesselating block in world");
            final CrashReportCategory i11 = h10.addCategory("Block being tesselated");
            CrashReportCategory.populateBlockDetails(i11, fk, byj);
            throw new ReportedException(h10);
        }
    }
    
    public boolean renderLiquid(final BlockPos fk, final BlockAndTintGetter bje, final VertexConsumer cyo, final FluidState coj) {
        try {
            return this.liquidBlockRenderer.tesselate(bje, fk, cyo, coj);
        }
        catch (Throwable throwable6) {
            final CrashReport h7 = CrashReport.forThrowable(throwable6, "Tesselating liquid in world");
            final CrashReportCategory i8 = h7.addCategory("Block being tesselated");
            CrashReportCategory.populateBlockDetails(i8, fk, null);
            throw new ReportedException(h7);
        }
    }
    
    public ModelBlockRenderer getModelRenderer() {
        return this.modelRenderer;
    }
    
    public BakedModel getBlockModel(final BlockState byj) {
        return this.blockModelShaper.getBlockModel(byj);
    }
    
    public void renderSingleBlock(final BlockState byj, final PoseStack cyl, final MultiBufferSource dqt, final int integer4, final int integer5) {
        final RenderShape btr7 = byj.getRenderShape();
        if (btr7 == RenderShape.INVISIBLE) {
            return;
        }
        switch (btr7) {
            case MODEL: {
                final BakedModel ebv8 = this.getBlockModel(byj);
                final int integer6 = this.blockColors.getColor(byj, null, null, 0);
                final float float10 = (integer6 >> 16 & 0xFF) / 255.0f;
                final float float11 = (integer6 >> 8 & 0xFF) / 255.0f;
                final float float12 = (integer6 & 0xFF) / 255.0f;
                this.modelRenderer.renderModel(cyl.last(), dqt.getBuffer(ItemBlockRenderTypes.getRenderType(byj)), byj, ebv8, float10, float11, float12, integer4, integer5);
                break;
            }
            case ENTITYBLOCK_ANIMATED: {
                BlockEntityWithoutLevelRenderer.instance.renderByItem(new ItemStack(byj.getBlock()), cyl, dqt, integer4, integer5);
                break;
            }
        }
    }
    
    @Override
    public void onResourceManagerReload(final ResourceManager zb) {
        this.liquidBlockRenderer.setupSprites();
    }
}
