package net.minecraft.client.renderer.entity;

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.client.renderer.LightTexture;
import com.mojang.math.Matrix4f;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LightLayer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.decoration.HangingEntity;
import net.minecraft.util.Mth;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.entity.Entity;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.model.EntityModel;
import net.minecraft.world.entity.Mob;

public abstract class MobRenderer<T extends Mob, M extends EntityModel<T>> extends LivingEntityRenderer<T, M> {
    public MobRenderer(final EntityRenderDispatcher dvf, final M dla, final float float3) {
        super(dvf, dla, float3);
    }
    
    @Override
    protected boolean shouldShowName(final T ala) {
        return super.shouldShowName(ala) && (ala.shouldShowName() || (ala.hasCustomName() && ala == this.entityRenderDispatcher.crosshairPickEntity));
    }
    
    public boolean shouldRender(final T ala, final Frustum dtm, final double double3, final double double4, final double double5) {
        if (super.shouldRender((T)ala, dtm, double3, double4, double5)) {
            return true;
        }
        final Entity akq10 = ala.getLeashHolder();
        return akq10 != null && dtm.isVisible(akq10.getBoundingBoxForCulling());
    }
    
    @Override
    public void render(final T ala, final float float2, final float float3, final PoseStack cyl, final MultiBufferSource dqt, final int integer) {
        super.render(ala, float2, float3, cyl, dqt, integer);
        final Entity akq8 = ala.getLeashHolder();
        if (akq8 == null) {
            return;
        }
        this.<Entity>renderLeash(ala, float3, cyl, dqt, akq8);
    }
    
    private <E extends Entity> void renderLeash(final T ala, final float float2, final PoseStack cyl, final MultiBufferSource dqt, final E akq) {
        cyl.pushPose();
        final double double7 = Mth.lerp(float2 * 0.5f, akq.yRot, akq.yRotO) * 0.017453292f;
        final double double8 = Mth.lerp(float2 * 0.5f, akq.xRot, akq.xRotO) * 0.017453292f;
        double double9 = Math.cos(double7);
        double double10 = Math.sin(double7);
        double double11 = Math.sin(double8);
        if (akq instanceof HangingEntity) {
            double9 = 0.0;
            double10 = 0.0;
            double11 = -1.0;
        }
        final double double12 = Math.cos(double8);
        final double double13 = Mth.lerp(float2, akq.xo, akq.getX()) - double9 * 0.7 - double10 * 0.5 * double12;
        final double double14 = Mth.lerp(float2, akq.yo + akq.getEyeHeight() * 0.7, akq.getY() + akq.getEyeHeight() * 0.7) - double11 * 0.5 - 0.25;
        final double double15 = Mth.lerp(float2, akq.zo, akq.getZ()) - double10 * 0.7 + double9 * 0.5 * double12;
        final double double16 = Mth.lerp(float2, ala.yBodyRot, ala.yBodyRotO) * 0.017453292f + 1.5707963267948966;
        double9 = Math.cos(double16) * ala.getBbWidth() * 0.4;
        double10 = Math.sin(double16) * ala.getBbWidth() * 0.4;
        final double double17 = Mth.lerp(float2, ala.xo, ala.getX()) + double9;
        final double double18 = Mth.lerp(float2, ala.yo, ala.getY());
        final double double19 = Mth.lerp(float2, ala.zo, ala.getZ()) + double10;
        cyl.translate(double9, -(1.6 - ala.getBbHeight()) * 0.5, double10);
        final float float3 = (float)(double13 - double17);
        final float float4 = (float)(double14 - double18);
        final float float5 = (float)(double15 - double19);
        final float float6 = 0.025f;
        final VertexConsumer cyo37 = dqt.getBuffer(RenderType.leash());
        final Matrix4f b38 = cyl.last().pose();
        final float float7 = Mth.fastInvSqrt(float3 * float3 + float5 * float5) * 0.025f / 2.0f;
        final float float8 = float5 * float7;
        final float float9 = float3 * float7;
        final int integer42 = this.getBlockLightLevel((T)ala, float2);
        final int integer43 = this.entityRenderDispatcher.<E>getRenderer(akq).getBlockLightLevel(akq, float2);
        final int integer44 = ala.level.getBrightness(LightLayer.SKY, new BlockPos(ala.getEyePosition(float2)));
        final int integer45 = ala.level.getBrightness(LightLayer.SKY, new BlockPos(akq.getEyePosition(float2)));
        renderSide(cyo37, b38, float3, float4, float5, integer42, integer43, integer44, integer45, 0.025f, 0.025f, float8, float9);
        renderSide(cyo37, b38, float3, float4, float5, integer42, integer43, integer44, integer45, 0.025f, 0.0f, float8, float9);
        cyl.popPose();
    }
    
    public static void renderSide(final VertexConsumer cyo, final Matrix4f b, final float float3, final float float4, final float float5, final int integer6, final int integer7, final int integer8, final int integer9, final float float10, final float float11, final float float12, final float float13) {
        final int integer10 = 24;
        for (int integer11 = 0; integer11 < 24; ++integer11) {
            final float float14 = integer11 / 23.0f;
            final int integer12 = (int)Mth.lerp(float14, (float)integer6, (float)integer7);
            final int integer13 = (int)Mth.lerp(float14, (float)integer8, (float)integer9);
            final int integer14 = LightTexture.pack(integer12, integer13);
            addVertexPair(cyo, b, integer14, float3, float4, float5, float10, float11, 24, integer11, false, float12, float13);
            addVertexPair(cyo, b, integer14, float3, float4, float5, float10, float11, 24, integer11 + 1, true, float12, float13);
        }
    }
    
    public static void addVertexPair(final VertexConsumer cyo, final Matrix4f b, final int integer3, final float float4, final float float5, final float float6, final float float7, final float float8, final int integer9, final int integer10, final boolean boolean11, final float float12, final float float13) {
        float float14 = 0.5f;
        float float15 = 0.4f;
        float float16 = 0.3f;
        if (integer10 % 2 == 0) {
            float14 *= 0.7f;
            float15 *= 0.7f;
            float16 *= 0.7f;
        }
        final float float17 = integer10 / (float)integer9;
        final float float18 = float4 * float17;
        final float float19 = float5 * (float17 * float17 + float17) * 0.5f + (integer9 - (float)integer10) / (integer9 * 0.75f) + 0.125f;
        final float float20 = float6 * float17;
        if (!boolean11) {
            cyo.vertex(b, float18 + float12, float19 + float7 - float8, float20 - float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        }
        cyo.vertex(b, float18 - float12, float19 + float8, float20 + float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        if (boolean11) {
            cyo.vertex(b, float18 + float12, float19 + float7 - float8, float20 - float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        }
    }
}
