package net.minecraft.client.renderer.entity;

import com.mojang.math.Matrix4f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.AABB;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.entity.Entity;

public abstract class EntityRenderer<T extends Entity> {
    protected final EntityRenderDispatcher entityRenderDispatcher;
    protected float shadowRadius;
    protected float shadowStrength;
    
    protected EntityRenderer(final EntityRenderDispatcher dvf) {
        this.shadowStrength = 1.0f;
        this.entityRenderDispatcher = dvf;
    }
    
    public final int getPackedLightCoords(final T akq, final float float2) {
        return LightTexture.pack(this.getBlockLightLevel(akq, float2), akq.level.getBrightness(LightLayer.SKY, new BlockPos(akq.getEyePosition(float2))));
    }
    
    protected int getBlockLightLevel(final T akq, final float float2) {
        if (akq.isOnFire()) {
            return 15;
        }
        return akq.level.getBrightness(LightLayer.BLOCK, new BlockPos(akq.getEyePosition(float2)));
    }
    
    public boolean shouldRender(final T akq, final Frustum dtm, final double double3, final double double4, final double double5) {
        if (!akq.shouldRender(double3, double4, double5)) {
            return false;
        }
        if (akq.noCulling) {
            return true;
        }
        AABB cvf10 = akq.getBoundingBoxForCulling().inflate(0.5);
        if (cvf10.hasNaN() || cvf10.getSize() == 0.0) {
            cvf10 = new AABB(akq.getX() - 2.0, akq.getY() - 2.0, akq.getZ() - 2.0, akq.getX() + 2.0, akq.getY() + 2.0, akq.getZ() + 2.0);
        }
        return dtm.isVisible(cvf10);
    }
    
    public Vec3 getRenderOffset(final T akq, final float float2) {
        return Vec3.ZERO;
    }
    
    public void render(final T akq, final float float2, final float float3, final PoseStack cyl, final MultiBufferSource dqt, final int integer) {
        if (!this.shouldShowName(akq)) {
            return;
        }
        this.renderNameTag(akq, akq.getDisplayName().getColoredString(), cyl, dqt, integer);
    }
    
    protected boolean shouldShowName(final T akq) {
        return akq.shouldShowName() && akq.hasCustomName();
    }
    
    public abstract ResourceLocation getTextureLocation(final T akq);
    
    public Font getFont() {
        return this.entityRenderDispatcher.getFont();
    }
    
    protected void renderNameTag(final T akq, final String string, final PoseStack cyl, final MultiBufferSource dqt, final int integer) {
        final double double7 = this.entityRenderDispatcher.distanceToSqr(akq);
        if (double7 > 4096.0) {
            return;
        }
        final boolean boolean9 = !akq.isDiscrete();
        final float float10 = akq.getBbHeight() + 0.5f;
        final int integer2 = "deadmau5".equals(string) ? -10 : 0;
        cyl.pushPose();
        cyl.translate(0.0, float10, 0.0);
        cyl.mulPose(this.entityRenderDispatcher.cameraOrientation());
        cyl.scale(-0.025f, -0.025f, 0.025f);
        final Matrix4f b12 = cyl.last().pose();
        final float float11 = Minecraft.getInstance().options.getBackgroundOpacity(0.25f);
        final int integer3 = (int)(float11 * 255.0f) << 24;
        final Font dch15 = this.getFont();
        final float float12 = (float)(-dch15.width(string) / 2);
        dch15.drawInBatch(string, float12, (float)integer2, 553648127, false, b12, dqt, boolean9, integer3, integer);
        if (boolean9) {
            dch15.drawInBatch(string, float12, (float)integer2, -1, false, b12, dqt, false, 0, integer);
        }
        cyl.popPose();
    }
    
    public EntityRenderDispatcher getDispatcher() {
        return this.entityRenderDispatcher;
    }
}
