package net.tropicraft.core.client.entity.render;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;

import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.tropicraft.Constants;
import net.tropicraft.core.common.entity.SeaTurtleEntity;
import net.tropicraft.core.common.entity.placeable.BeachFloatEntity;
import net.tropicraft.core.common.entity.placeable.FurnitureEntity;

@EventBusSubscriber(value = Dist.CLIENT, modid = Constants.MODID)
public class PlayerRotationHandler {

    private static float rotationYawHead, prevRotationYawHead, rotationPitch, prevRotationPitch;
    
    private static float interpolateAndWrap(float cur, float prev, float partial) {
        return MathHelper.wrapDegrees(prev + ((cur - prev) * partial));
    }

    @SubscribeEvent
    public static void onRenderPlayer(RenderPlayerEvent.Pre event) {
        MatrixStack stack = event.getMatrixStack();
        IRenderTypeBuffer buffers = event.getBuffers();
        PlayerEntity p = event.getPlayer();
        Entity riding = p.getRidingEntity();
        if (riding instanceof BeachFloatEntity) {
            FurnitureEntity floaty = (FurnitureEntity) riding;

            stack.push();
            //            GlStateManager.translated(event.getX(), event.getY(), event.getZ());
            stack.rotate(Vector3f.YN.rotationDegrees(-(floaty.prevRotationYaw + (event.getPartialRenderTick() * (floaty.rotationYaw - floaty.prevRotationYaw)))));
            stack.translate(0, 1.55, 1.55);
            stack.rotate(Vector3f.XN.rotationDegrees(90));

            // Cancel out player camera rotation
            float f = interpolateAndWrap(p.renderYawOffset, p.prevRenderYawOffset, event.getPartialRenderTick());
            stack.rotate(Vector3f.YP.rotationDegrees(f));

            // Lock in head
            rotationYawHead = p.rotationYawHead;
            prevRotationYawHead = p.prevRotationYawHead;
            p.rotationYawHead = p.renderYawOffset;
            p.prevRotationYawHead = p.prevRenderYawOffset;
            rotationPitch = p.rotationPitch;
            prevRotationPitch = p.prevRotationPitch;
            p.rotationPitch = 10f;
            p.prevRotationPitch = 10f;

            // TODO - 1.15 seemed to get rid of initial/after translations but maybe they are needed?
//            GlStateManager.translated(-event.getX(), -event.getY(), -event.getZ());
        }
        if (riding instanceof SeaTurtleEntity) {
            SeaTurtleEntity turtle = (SeaTurtleEntity) riding;
            stack.push();
//            GlStateManager.translated(event.getX(), event.getY(), event.getZ());

            // Cancel out player camera rotation
            float pitch = interpolateAndWrap(turtle.rotationPitch, turtle.prevRotationPitch, event.getPartialRenderTick());
            float yaw = interpolateAndWrap(turtle.rotationYawHead, turtle.prevRotationYawHead, event.getPartialRenderTick());

            stack.translate(0, turtle.getMountedYOffset() - p.getYOffset(), 0);
            stack.rotate(Vector3f.YN.rotationDegrees(yaw));
            stack.translate(0, -0.1, 0); // TODO figure out why this budging is needed
            stack.rotate(Vector3f.XP.rotationDegrees(pitch));
            stack.translate(0, 0.1, 0);
            stack.rotate(Vector3f.YP.rotationDegrees(yaw));
            stack.translate(0, -turtle.getMountedYOffset() + p.getYOffset(), 0);

            Vec3d passengerOffset = (new Vec3d(-0.25f, 0.0D, 0.0D)).rotateYaw((float) (-Math.toRadians(yaw) - (Math.PI / 2)));
            stack.translate(passengerOffset.getX(), 0, passengerOffset.getZ());

            // Lock in head
            rotationPitch = p.rotationPitch;
            prevRotationPitch = p.prevRotationPitch;
            p.rotationPitch = 10f;
            p.prevRotationPitch = 10f;

            //GlStateManager.translated(-event.getX(), -event.getY(), -event.getZ());
        }
    }

    @SubscribeEvent
    public static void onRenderPlayerPost(RenderPlayerEvent.Post event) {
        PlayerEntity p = event.getPlayer();
        if (p.getRidingEntity() instanceof BeachFloatEntity || p.getRidingEntity() instanceof SeaTurtleEntity) {
            event.getMatrixStack().pop();
            p.rotationPitch = rotationPitch;
            p.prevRotationPitch = prevRotationPitch;
        }
        if (p.getRidingEntity() instanceof BeachFloatEntity) {
            p.rotationYawHead = rotationYawHead;
            p.prevRotationYawHead = prevRotationYawHead;
        }
    }

    @SubscribeEvent
    public static void onRenderPlayerSpecials(RenderLivingEvent.Pre<?, ?> event) {
        if (event.getEntity().getRidingEntity() instanceof BeachFloatEntity) {
            event.setCanceled(true);
        }
    }
}

@@ -94,108 +94,8 @@
 ck;%0A
-import com.mojang.blaze3d.platform.GlStateManager;%0A%0Aimport com.mojang.blaze3d.vertex.IVertexBuilder;
 %0Aimp
@@ -448,30 +448,33 @@
 event.Render
-Living
+Nameplate
 Event;%0Aimpor
@@ -522,24 +522,77 @@
 layerEvent;%0A
+import net.minecraftforge.eventbus.api.Event.Result;%0A
 import net.m
@@ -1723,103 +1723,8 @@
 ();%0A
-            //            GlStateManager.translated(event.getX(), event.getY(), event.getZ());%0A
     
@@ -1746,33 +1746,33 @@
 otate(Vector3f.Y
-N
+P
 .rotationDegrees
@@ -2616,33 +2616,32 @@
 ionPitch = 10f;%0A
-%0A
             // T
@@ -2640,182 +2640,143 @@
     
-// TODO - 1.15 seemed to get rid of initial/after translations but maybe they are needed?%0A//            GlStateManager.translated(-event.getX(), -event.getY(), -event.getZ())
+%0A            // Cancel limb swing%0A            p.limbSwing = 0;%0A            p.limbSwingAmount = 0;%0A            p.prevLimbSwingAmount = 0
 ;%0A  
@@ -2924,91 +2924,8 @@
 h();
-%0A//            GlStateManager.translated(event.getX(), event.getY(), event.getZ());
 %0A%0A  
@@ -4104,95 +4104,8 @@
 10f;
-%0A%0A            //GlStateManager.translated(-event.getX(), -event.getY(), -event.getZ());
 %0A   
@@ -4781,29 +4781,22 @@
 nder
-LivingEvent.Pre%3C?, ?%3E
+NameplateEvent
  eve
@@ -4905,21 +4905,26 @@
 .set
-Canceled(true
+Result(Result.DENY
 );%0A 

Fix player rendering on turtles and beach floats