package com.minelittlepony.client.render;

import org.lwjgl.opengl.GL14;

import com.minelittlepony.MineLittlePony;
import com.minelittlepony.client.ducks.IRenderItem;
import com.minelittlepony.client.render.tileentities.skull.PonySkullRenderer;
import com.minelittlepony.client.util.render.Color;
import com.minelittlepony.pony.IPony;
import com.minelittlepony.settings.PonySettings;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.FirstPersonRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AbsoluteHand;
import net.minecraft.util.UseAction;

import static com.mojang.blaze3d.platform.GlStateManager.*;

public class LevitatingItemRenderer {

    public static void enableItemGlowRenderProfile() {
        enableBlend();
        blendFuncSeparate(SourceFactor.CONSTANT_COLOR, DestFactor.ONE, SourceFactor.ONE, DestFactor.ZERO);
        MinecraftClient.getInstance().gameRenderer.disableLightmap();
    }

    /**
     * Renders a magical overlay over an item in third person.
     */
    public void renderItemGlow(LivingEntity entity, ItemStack drop, ModelTransformation.Type transform, AbsoluteHand hand, int glowColor) {
        pushMatrix();
        disableLighting();
        setColor(glowColor);

        ItemRenderer renderItem = MinecraftClient.getInstance().getItemRenderer();
        ((IRenderItem) renderItem).useTransparency(true);
        PonySkullRenderer.ponyInstance.useTransparency(true);

        scalef(1.1F, 1.1F, 1.1F);

        translatef(0, 0.01F, 0.01F);
        renderItem.renderHeldItem(drop, entity, transform, hand == AbsoluteHand.LEFT);
        translatef(0.01F, -0.01F, -0.02F);
        renderItem.renderHeldItem(drop, entity, transform, hand == AbsoluteHand.LEFT);

        ((IRenderItem) renderItem).useTransparency(false);
        PonySkullRenderer.ponyInstance.useTransparency(false);
        unsetColor();
        enableLighting();
        popMatrix();

        // I hate rendering
    }

    private void setColor(int glowColor) {
        GL14.glBlendColor(Color.r(glowColor), Color.g(glowColor), Color.b(glowColor), 0.2F);
    }

    private void unsetColor() {
        GL14.glBlendColor(255, 255, 255, 1);
    }

    /**
     * Renders an item in first person optionally with a magical overlay.
     */
    public void renderItemInFirstPerson(FirstPersonRenderer renderer, AbstractClientPlayerEntity entity, ItemStack stack, ModelTransformation.Type transform, boolean left) {
        IPony pony = MineLittlePony.getInstance().getManager().getPony(entity);

        pushMatrix();

        boolean doMagic = PonySettings.FPSMAGIC.get() && pony.getMetadata().hasMagic();

        ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();

        if (doMagic) {
            setupPerspective(itemRenderer, entity, stack, left);
        }

        renderer.renderItemFromSide(entity, stack, transform, left);

        if (doMagic) {
            disableLighting();

            ((IRenderItem)itemRenderer).useTransparency(true);
            PonySkullRenderer.ponyInstance.useTransparency(true);

            setColor(pony.getMetadata().getGlowColor());

            scalef(1.1F, 1.1F, 1.1F);

            translatef(-0.015F, 0.01F, 0.01F);
            renderer.renderItemFromSide(entity, stack, transform, left);
            translatef(0.03F, -0.01F, -0.02F);
            renderer.renderItemFromSide(entity, stack, transform, left);

            ((IRenderItem)itemRenderer).useTransparency(false);

            PonySkullRenderer.ponyInstance.useTransparency(false);

            unsetColor();
            enableLighting();
        }

        popMatrix();

        // I hate rendering
    }

    /**
     * Moves held items to look like they're floating in the player's field.
     */
    private void setupPerspective(ItemRenderer renderer, LivingEntity entity, ItemStack stack, boolean left) {
        UseAction action = stack.getUseAction();

        boolean doNormal = entity.getItemUseTime() <= 0 || action == UseAction.NONE;

        if (doNormal) { // eating, blocking, and drinking are not transformed. Only held items.
            float ticks = MinecraftClient.getInstance().getTickDelta() - entity.age;

            float floatAmount = (float)Math.sin(ticks / 9) / 40;
            float driftAmount = (float)Math.cos(ticks / 6) / 40;

            boolean handHeldTool = stack.getUseAction() == UseAction.BOW
                    || stack.getUseAction() == UseAction.BLOCK;

            translatef(driftAmount - floatAmount / 4, floatAmount, handHeldTool ? -0.3F : -0.6F);

            if (!renderer.hasDepthInGui(stack) && !handHeldTool) { // bows have to point forwards
                if (left) {
                    rotatef(-60, 0, 1, 0);
                    rotatef(30, 0, 0, 1);
                } else {
                    rotatef(60, 0, 1, 0);
                    rotatef(-30, 0, 0, 1);
                }
            }
        }
    }
}

@@ -1741,16 +1741,20 @@
 slatef(0
+.01F
 , 0.01F,
@@ -1872,20 +1872,21 @@
 tef(
+-
 0.0
-1
+2
 F, -0.0
-1
+2
 F, -
@@ -3456,14 +3456,12 @@
 tef(
--
 0.01
-5
 F, 0
@@ -3574,20 +3574,21 @@
 tef(
+-
 0.0
-3
+2
 F, -0.0
-1
+2
 F, -
@@ -4263,16 +4263,48 @@
 ion.NONE
+ %7C%7C action == UseAction.CROSSBOW
 ;%0A%0A     
@@ -4646,36 +4646,22 @@
 dTool = 
-stack.getUseA
+a
 ction
-()
  == UseA
@@ -4693,36 +4693,74 @@
      %7C%7C 
-stack.getUseAction()
+action == UseAction.CROSSBOW%0A                    %7C%7C action
  == UseA

Fix positioning of the crossbow when held by unicorns