package me.km.overrides;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.entity.IEntityRenderer;
import net.minecraft.client.renderer.entity.layers.CapeLayer;
import net.minecraft.client.renderer.entity.model.PlayerModel;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.entity.player.PlayerModelPart;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class ModCapeLayer extends CapeLayer {
    public ModCapeLayer(IEntityRenderer<AbstractClientPlayerEntity, PlayerModel<AbstractClientPlayerEntity>> pRenderer) {
        super(pRenderer);
    }

    @Override
    public void render(MatrixStack mStack, IRenderTypeBuffer buffer, int packedLightIn, AbstractClientPlayerEntity p, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) {
        if(p.hasPlayerInfo() && !p.isInvisible() && p.isWearing(PlayerModelPart.CAPE)) {
            ItemStack chestStack = p.getItemStackFromSlot(EquipmentSlotType.CHEST);
            if(chestStack.getItem() != Items.ELYTRA) {
                ResourceLocation rl = PlayerCapeLoader.INSTANCE.getTexture(p.getUniqueID());
                if(rl == null) {
                    return;
                }

                mStack.push();
                mStack.translate(0.0, 0.0, 0.125);
                double d0 = MathHelper.lerp(partialTicks, p.prevChasingPosX, p.chasingPosX) - MathHelper.lerp(partialTicks, p.prevPosX, p.getPosX());
                double d1 = MathHelper.lerp(partialTicks, p.prevChasingPosY, p.chasingPosY) - MathHelper.lerp(partialTicks, p.prevPosY, p.getPosY());
                double d2 = MathHelper.lerp(partialTicks, p.prevChasingPosZ, p.chasingPosZ) - MathHelper.lerp(partialTicks, p.prevPosZ, p.getPosZ());
                float f = p.prevRenderYawOffset + (p.renderYawOffset - p.prevRenderYawOffset);
                double d3 = MathHelper.sin(f * ((float) Math.PI / 180f));
                double d4 = -MathHelper.cos(f * ((float) Math.PI / 180f));
                float f1 = (float) d1 * 10.0f;
                f1 = MathHelper.clamp(f1, -6.0f, 32.0f);
                float f2 = (float) (d0 * d3 + d2 * d4) * 100.0f;
                f2 = MathHelper.clamp(f2, 0.0f, 150.0f);
                float f3 = (float) (d0 * d4 - d2 * d3) * 100.0f;
                f3 = MathHelper.clamp(f3, -20.0f, 20.0f);
                if(f2 < 0.0f) {
                    f2 = 0.0f;
                }

                float f4 = MathHelper.lerp(partialTicks, p.prevCameraYaw, p.cameraYaw);
                f1 = f1 + MathHelper.sin(MathHelper.lerp(partialTicks, p.prevDistanceWalkedModified, p.distanceWalkedModified) * 6.0f) * 32.0f * f4;
                if(p.isCrouching()) {
                    f1 += 25.0f;
                }

                mStack.rotate(Vector3f.XP.rotationDegrees(6.0f + f2 / 2.0f + f1));
                mStack.rotate(Vector3f.ZP.rotationDegrees(f3 / 2.0f));
                mStack.rotate(Vector3f.YP.rotationDegrees(180.0f - f3 / 2.0f));
                IVertexBuilder ivertexbuilder = buffer.getBuffer(RenderType.getEntitySolid(rl));
                this.getEntityModel().renderCape(mStack, ivertexbuilder, packedLightIn, OverlayTexture.NO_OVERLAY);
                mStack.pop();
            }
        }
    }
}
