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.world.phys.Vec3;
import net.minecraft.world.level.LightLayer;
import net.minecraft.core.BlockPos;
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 egm, final M dvv, final float float3) {
        super(egm, dvv, float3);
    }
    
    @Override
    protected boolean shouldShowName(final T aoz) {
        return super.shouldShowName(aoz) && (aoz.shouldShowName() || (aoz.hasCustomName() && aoz == this.entityRenderDispatcher.crosshairPickEntity));
    }
    
    public boolean shouldRender(final T aoz, final Frustum ees, final double double3, final double double4, final double double5) {
        if (super.shouldRender((T)aoz, ees, double3, double4, double5)) {
            return true;
        }
        final Entity aom10 = aoz.getLeashHolder();
        return aom10 != null && ees.isVisible(aom10.getBoundingBoxForCulling());
    }
    
    @Override
    public void render(final T aoz, final float float2, final float float3, final PoseStack dhl, final MultiBufferSource ebz, final int integer) {
        super.render(aoz, float2, float3, dhl, ebz, integer);
        final Entity aom8 = aoz.getLeashHolder();
        if (aom8 == null) {
            return;
        }
        this.<Entity>renderLeash(aoz, float3, dhl, ebz, aom8);
    }
    
    private <E extends Entity> void renderLeash(final T aoz, final float float2, final PoseStack dhl, final MultiBufferSource ebz, final E aom) {
        dhl.pushPose();
        final double double7 = Mth.lerp(float2 * 0.5f, aom.yRot, aom.yRotO) * 0.017453292f;
        final double double8 = Mth.lerp(float2 * 0.5f, aom.xRot, aom.xRotO) * 0.017453292f;
        double double9 = Math.cos(double7);
        double double10 = Math.sin(double7);
        double double11 = Math.sin(double8);
        if (aom instanceof HangingEntity) {
            double9 = 0.0;
            double10 = 0.0;
            double11 = -1.0;
        }
        final double double12 = Math.cos(double8);
        final double double13 = Mth.lerp(float2, aom.xo, aom.getX()) - double9 * 0.7 - double10 * 0.5 * double12;
        final double double14 = Mth.lerp(float2, aom.yo + aom.getEyeHeight() * 0.7, aom.getY() + aom.getEyeHeight() * 0.7) - double11 * 0.5 - 0.25;
        final double double15 = Mth.lerp(float2, aom.zo, aom.getZ()) - double10 * 0.7 + double9 * 0.5 * double12;
        final double double16 = Mth.lerp(float2, aoz.yBodyRot, aoz.yBodyRotO) * 0.017453292f + 1.5707963267948966;
        final Vec3 dem27 = aoz.getLeashOffset();
        double9 = Math.cos(double16) * dem27.z + Math.sin(double16) * dem27.x;
        double10 = Math.sin(double16) * dem27.z - Math.cos(double16) * dem27.x;
        final double double17 = Mth.lerp(float2, aoz.xo, aoz.getX()) + double9;
        final double double18 = Mth.lerp(float2, aoz.yo, aoz.getY()) + dem27.y;
        final double double19 = Mth.lerp(float2, aoz.zo, aoz.getZ()) + double10;
        dhl.translate(double9, dem27.y, 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 dhp38 = ebz.getBuffer(RenderType.leash());
        final Matrix4f b39 = dhl.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 BlockPos fu43 = new BlockPos(aoz.getEyePosition(float2));
        final BlockPos fu44 = new BlockPos(aom.getEyePosition(float2));
        final int integer45 = this.getBlockLightLevel((T)aoz, fu43);
        final int integer46 = this.entityRenderDispatcher.<E>getRenderer(aom).getBlockLightLevel(aom, fu44);
        final int integer47 = aoz.level.getBrightness(LightLayer.SKY, fu43);
        final int integer48 = aoz.level.getBrightness(LightLayer.SKY, fu44);
        renderSide(dhp38, b39, float3, float4, float5, integer45, integer46, integer47, integer48, 0.025f, 0.025f, float8, float9);
        renderSide(dhp38, b39, float3, float4, float5, integer45, integer46, integer47, integer48, 0.025f, 0.0f, float8, float9);
        dhl.popPose();
    }
    
    public static void renderSide(final VertexConsumer dhp, 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(dhp, b, integer14, float3, float4, float5, float10, float11, 24, integer11, false, float12, float13);
            addVertexPair(dhp, b, integer14, float3, float4, float5, float10, float11, 24, integer11 + 1, true, float12, float13);
        }
    }
    
    public static void addVertexPair(final VertexConsumer dhp, 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 > 0.0f) ? (float5 * float17 * float17) : (float5 - float5 * (1.0f - float17) * (1.0f - float17));
        final float float20 = float6 * float17;
        if (!boolean11) {
            dhp.vertex(b, float18 + float12, float19 + float7 - float8, float20 - float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        }
        dhp.vertex(b, float18 - float12, float19 + float8, float20 + float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        if (boolean11) {
            dhp.vertex(b, float18 + float12, float19 + float7 - float8, float20 - float13).color(float14, float15, float16, 1.0f).uv2(integer3).endVertex();
        }
    }
}
