package net.minecraft.client.renderer.entity.player;

import com.mojang.math.Vector3f;
import net.minecraft.util.Mth;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.world.scores.Score;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Scoreboard;
import net.minecraft.world.entity.Entity;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.CrossbowItem;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.PlayerModelPart;
import net.minecraft.world.phys.Vec3;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.entity.layers.BeeStingerLayer;
import net.minecraft.client.renderer.entity.layers.SpinAttackEffectLayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.client.renderer.entity.layers.ParrotOnShoulderLayer;
import net.minecraft.client.renderer.entity.layers.ElytraLayer;
import net.minecraft.client.renderer.entity.layers.CustomHeadLayer;
import net.minecraft.client.renderer.entity.layers.CapeLayer;
import net.minecraft.client.renderer.entity.layers.Deadmau5EarsLayer;
import net.minecraft.client.renderer.entity.layers.ArrowLayer;
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;

public class PlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> {
    public PlayerRenderer(final EntityRenderDispatcher dvf) {
        this(dvf, false);
    }
    
    public PlayerRenderer(final EntityRenderDispatcher dvf, final boolean boolean2) {
        super(dvf, new PlayerModel(0.0f, boolean2), 0.5f);
        this.addLayer((RenderLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>)new HumanoidArmorLayer((RenderLayerParent<LivingEntity, HumanoidModel>)this, new HumanoidModel(0.5f), new HumanoidModel(1.0f)));
        this.addLayer(new ItemInHandLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>(this));
        this.addLayer(new ArrowLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>(this));
        this.addLayer(new Deadmau5EarsLayer(this));
        this.addLayer(new CapeLayer(this));
        this.addLayer(new CustomHeadLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>(this));
        this.addLayer(new ElytraLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>(this));
        this.addLayer((RenderLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>)new ParrotOnShoulderLayer((RenderLayerParent<Player, PlayerModel<Player>>)this));
        this.addLayer((RenderLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>)new SpinAttackEffectLayer((RenderLayerParent<LivingEntity, PlayerModel<LivingEntity>>)this));
        this.addLayer(new BeeStingerLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>>(this));
    }
    
    @Override
    public void render(final AbstractClientPlayer dpy, final float float2, final float float3, final PoseStack cyl, final MultiBufferSource dqt, final int integer) {
        this.setModelProperties(dpy);
        super.render(dpy, float2, float3, cyl, dqt, integer);
    }
    
    public Vec3 getRenderOffset(final AbstractClientPlayer dpy, final float float2) {
        if (dpy.isCrouching()) {
            return new Vec3(0.0, -0.125, 0.0);
        }
        return super.getRenderOffset((T)dpy, float2);
    }
    
    private void setModelProperties(final AbstractClientPlayer dpy) {
        final PlayerModel<AbstractClientPlayer> dlz3 = ((LivingEntityRenderer<T, PlayerModel<AbstractClientPlayer>>)this).getModel();
        if (dpy.isSpectator()) {
            dlz3.setAllVisible(false);
            dlz3.head.visible = true;
            dlz3.hat.visible = true;
        }
        else {
            final ItemStack ben4 = dpy.getMainHandItem();
            final ItemStack ben5 = dpy.getOffhandItem();
            dlz3.setAllVisible(true);
            dlz3.hat.visible = dpy.isModelPartShown(PlayerModelPart.HAT);
            dlz3.jacket.visible = dpy.isModelPartShown(PlayerModelPart.JACKET);
            dlz3.leftPants.visible = dpy.isModelPartShown(PlayerModelPart.LEFT_PANTS_LEG);
            dlz3.rightPants.visible = dpy.isModelPartShown(PlayerModelPart.RIGHT_PANTS_LEG);
            dlz3.leftSleeve.visible = dpy.isModelPartShown(PlayerModelPart.LEFT_SLEEVE);
            dlz3.rightSleeve.visible = dpy.isModelPartShown(PlayerModelPart.RIGHT_SLEEVE);
            dlz3.crouching = dpy.isCrouching();
            final HumanoidModel.ArmPose a6 = this.getArmPose(dpy, ben4, ben5, InteractionHand.MAIN_HAND);
            final HumanoidModel.ArmPose a7 = this.getArmPose(dpy, ben4, ben5, InteractionHand.OFF_HAND);
            if (dpy.getMainArm() == HumanoidArm.RIGHT) {
                dlz3.rightArmPose = a6;
                dlz3.leftArmPose = a7;
            }
            else {
                dlz3.rightArmPose = a7;
                dlz3.leftArmPose = a6;
            }
        }
    }
    
    private HumanoidModel.ArmPose getArmPose(final AbstractClientPlayer dpy, final ItemStack ben2, final ItemStack ben3, final InteractionHand ajk) {
        HumanoidModel.ArmPose a6 = HumanoidModel.ArmPose.EMPTY;
        final ItemStack ben4 = (ajk == InteractionHand.MAIN_HAND) ? ben2 : ben3;
        if (!ben4.isEmpty()) {
            a6 = HumanoidModel.ArmPose.ITEM;
            if (dpy.getUseItemRemainingTicks() > 0) {
                final UseAnim bfy8 = ben4.getUseAnimation();
                if (bfy8 == UseAnim.BLOCK) {
                    a6 = HumanoidModel.ArmPose.BLOCK;
                }
                else if (bfy8 == UseAnim.BOW) {
                    a6 = HumanoidModel.ArmPose.BOW_AND_ARROW;
                }
                else if (bfy8 == UseAnim.SPEAR) {
                    a6 = HumanoidModel.ArmPose.THROW_SPEAR;
                }
                else if (bfy8 == UseAnim.CROSSBOW && ajk == dpy.getUsedItemHand()) {
                    a6 = HumanoidModel.ArmPose.CROSSBOW_CHARGE;
                }
            }
            else {
                final boolean boolean8 = ben2.getItem() == Items.CROSSBOW;
                final boolean boolean9 = CrossbowItem.isCharged(ben2);
                final boolean boolean10 = ben3.getItem() == Items.CROSSBOW;
                final boolean boolean11 = CrossbowItem.isCharged(ben3);
                if (boolean8 && boolean9) {
                    a6 = HumanoidModel.ArmPose.CROSSBOW_HOLD;
                }
                if (boolean10 && boolean11 && ben2.getItem().getUseAnimation(ben2) == UseAnim.NONE) {
                    a6 = HumanoidModel.ArmPose.CROSSBOW_HOLD;
                }
            }
        }
        return a6;
    }
    
    @Override
    public ResourceLocation getTextureLocation(final AbstractClientPlayer dpy) {
        return dpy.getSkinTextureLocation();
    }
    
    @Override
    protected void scale(final AbstractClientPlayer dpy, final PoseStack cyl, final float float3) {
        final float float4 = 0.9375f;
        cyl.scale(0.9375f, 0.9375f, 0.9375f);
    }
    
    protected void renderNameTag(final AbstractClientPlayer dpy, final String string, final PoseStack cyl, final MultiBufferSource dqt, final int integer) {
        final double double7 = this.entityRenderDispatcher.distanceToSqr(dpy);
        cyl.pushPose();
        if (double7 < 100.0) {
            final Scoreboard cwl9 = dpy.getScoreboard();
            final Objective cwi10 = cwl9.getDisplayObjective(2);
            if (cwi10 != null) {
                final Score cwk11 = cwl9.getOrCreatePlayerScore(dpy.getScoreboardName(), cwi10);
                super.renderNameTag((T)dpy, cwk11.getScore() + " " + cwi10.getDisplayName().getColoredString(), cyl, dqt, integer);
                final double double8 = 0.0;
                this.getFont().getClass();
                cyl.translate(double8, 9.0f * 1.15f * 0.025f, 0.0);
            }
        }
        super.renderNameTag((T)dpy, string, cyl, dqt, integer);
        cyl.popPose();
    }
    
    public void renderRightHand(final PoseStack cyl, final MultiBufferSource dqt, final int integer, final AbstractClientPlayer dpy) {
        this.renderHand(cyl, dqt, integer, dpy, ((PlayerModel)this.model).rightArm, ((PlayerModel)this.model).rightSleeve);
    }
    
    public void renderLeftHand(final PoseStack cyl, final MultiBufferSource dqt, final int integer, final AbstractClientPlayer dpy) {
        this.renderHand(cyl, dqt, integer, dpy, ((PlayerModel)this.model).leftArm, ((PlayerModel)this.model).leftSleeve);
    }
    
    private void renderHand(final PoseStack cyl, final MultiBufferSource dqt, final int integer, final AbstractClientPlayer dpy, final ModelPart dni5, final ModelPart dni6) {
        final PlayerModel<AbstractClientPlayer> dlz8 = ((LivingEntityRenderer<T, PlayerModel<AbstractClientPlayer>>)this).getModel();
        this.setModelProperties(dpy);
        dlz8.attackTime = 0.0f;
        dlz8.crouching = false;
        dlz8.setupAnim(dpy, dlz8.swimAmount = 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
        dni5.xRot = 0.0f;
        dni5.render(cyl, dqt.getBuffer(RenderType.entitySolid(dpy.getSkinTextureLocation())), integer, OverlayTexture.NO_OVERLAY);
        dni6.xRot = 0.0f;
        dni6.render(cyl, dqt.getBuffer(RenderType.entityTranslucent(dpy.getSkinTextureLocation())), integer, OverlayTexture.NO_OVERLAY);
    }
    
    @Override
    protected void setupRotations(final AbstractClientPlayer dpy, final PoseStack cyl, final float float3, final float float4, final float float5) {
        final float float6 = dpy.getSwimAmount(float5);
        if (dpy.isFallFlying()) {
            super.setupRotations(dpy, cyl, float3, float4, float5);
            final float float7 = dpy.getFallFlyingTicks() + float5;
            final float float8 = Mth.clamp(float7 * float7 / 100.0f, 0.0f, 1.0f);
            if (!dpy.isAutoSpinAttack()) {
                cyl.mulPose(Vector3f.XP.rotationDegrees(float8 * (-90.0f - dpy.xRot)));
            }
            final Vec3 cvl10 = dpy.getViewVector(float5);
            final Vec3 cvl11 = dpy.getDeltaMovement();
            final double double12 = Entity.getHorizontalDistanceSqr(cvl11);
            final double double13 = Entity.getHorizontalDistanceSqr(cvl10);
            if (double12 > 0.0 && double13 > 0.0) {
                final double double14 = (cvl11.x * cvl10.x + cvl11.z * cvl10.z) / (Math.sqrt(double12) * Math.sqrt(double13));
                final double double15 = cvl11.x * cvl10.z - cvl11.z * cvl10.x;
                cyl.mulPose(Vector3f.YP.rotation((float)(Math.signum(double15) * Math.acos(double14))));
            }
        }
        else if (float6 > 0.0f) {
            super.setupRotations(dpy, cyl, float3, float4, float5);
            final float float7 = dpy.isInWater() ? (-90.0f - dpy.xRot) : -90.0f;
            final float float8 = Mth.lerp(float6, 0.0f, float7);
            cyl.mulPose(Vector3f.XP.rotationDegrees(float8));
            if (dpy.isVisuallySwimming()) {
                cyl.translate(0.0, -1.0, 0.30000001192092896);
            }
        }
        else {
            super.setupRotations(dpy, cyl, float3, float4, float5);
        }
    }
}
