package net.minecraft.client.renderer.block;

import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.client.renderer.block.model.ItemTransforms;
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 ecp, final BlockColors dmn) {
        this.random = new Random();
        this.blockModelShaper = ecp;
        this.blockColors = dmn;
        this.modelRenderer = new ModelBlockRenderer(this.blockColors);
        this.liquidBlockRenderer = new LiquidBlockRenderer();
    }
    
    public BlockModelShaper getBlockModelShaper() {
        return this.blockModelShaper;
    }
    
    public void renderBreakingTexture(final BlockState cfj, final BlockPos fu, final BlockAndTintGetter bpe, final PoseStack dhl, final VertexConsumer dhp) {
        if (cfj.getRenderShape() != RenderShape.MODEL) {
            return;
        }
        final BakedModel enh7 = this.blockModelShaper.getBlockModel(cfj);
        final long long8 = cfj.getSeed(fu);
        this.modelRenderer.tesselateBlock(bpe, enh7, cfj, fu, dhl, dhp, true, this.random, long8, OverlayTexture.NO_OVERLAY);
    }
    
    public boolean renderBatched(final BlockState cfj, final BlockPos fu, final BlockAndTintGetter bpe, final PoseStack dhl, final VertexConsumer dhp, final boolean boolean6, final Random random) {
        try {
            final RenderShape cak9 = cfj.getRenderShape();
            return cak9 == RenderShape.MODEL && this.modelRenderer.tesselateBlock(bpe, this.getBlockModel(cfj), cfj, fu, dhl, dhp, boolean6, random, cfj.getSeed(fu), OverlayTexture.NO_OVERLAY);
        }
        catch (Throwable throwable9) {
            final CrashReport j10 = CrashReport.forThrowable(throwable9, "Tesselating block in world");
            final CrashReportCategory k11 = j10.addCategory("Block being tesselated");
            CrashReportCategory.populateBlockDetails(k11, fu, cfj);
            throw new ReportedException(j10);
        }
    }
    
    public boolean renderLiquid(final BlockPos fu, final BlockAndTintGetter bpe, final VertexConsumer dhp, final FluidState cxa) {
        try {
            return this.liquidBlockRenderer.tesselate(bpe, fu, dhp, cxa);
        }
        catch (Throwable throwable6) {
            final CrashReport j7 = CrashReport.forThrowable(throwable6, "Tesselating liquid in world");
            final CrashReportCategory k8 = j7.addCategory("Block being tesselated");
            CrashReportCategory.populateBlockDetails(k8, fu, null);
            throw new ReportedException(j7);
        }
    }
    
    public ModelBlockRenderer getModelRenderer() {
        return this.modelRenderer;
    }
    
    public BakedModel getBlockModel(final BlockState cfj) {
        return this.blockModelShaper.getBlockModel(cfj);
    }
    
    public void renderSingleBlock(final BlockState cfj, final PoseStack dhl, final MultiBufferSource ebz, final int integer4, final int integer5) {
        final RenderShape cak7 = cfj.getRenderShape();
        if (cak7 == RenderShape.INVISIBLE) {
            return;
        }
        switch (cak7) {
            case MODEL: {
                final BakedModel enh8 = this.getBlockModel(cfj);
                final int integer6 = this.blockColors.getColor(cfj, 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(dhl.last(), ebz.getBuffer(ItemBlockRenderTypes.getRenderType(cfj, false)), cfj, enh8, float10, float11, float12, integer4, integer5);
                break;
            }
            case ENTITYBLOCK_ANIMATED: {
                BlockEntityWithoutLevelRenderer.instance.renderByItem(new ItemStack(cfj.getBlock()), ItemTransforms.TransformType.NONE, dhl, ebz, integer4, integer5);
                break;
            }
        }
    }
    
    @Override
    public void onResourceManagerReload(final ResourceManager abc) {
        this.liquidBlockRenderer.setupSprites();
    }
}
