package com.minelittlepony.client.model.part;

import net.minecraft.client.model.Model;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.MathHelper;

import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.model.IPart;
import com.minelittlepony.mson.api.ModelContext;
import com.minelittlepony.mson.api.MsonModel;

import java.util.UUID;
import java.util.concurrent.ExecutionException;

public class PonyTail extends ModelPart implements IPart, MsonModel {

    private final AbstractPonyModel<?> theModel;

    private int tailStop = 0;

    public PonyTail(AbstractPonyModel<?> model) {
        super(model);
        theModel = model;
    }


    @Override
    public void init(ModelContext context) {
        try {
            int segments = context.getLocals().getValue("segments").get().intValue();

            for (int i = 0; i < segments; i++) {
                Segment segment = context.findByName("segment_" + i);
                segment.index = i;
                addChild(segment);
            }

        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void setRotationAndAngles(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
        roll = rainboom ? 0 : MathHelper.cos(move * 0.8F) * 0.2f * swing;
        yaw = bodySwing;

        if (theModel.getAttributes().isCrouching && !rainboom) {
            rotateSneak();
        } else if (theModel.isRiding()) {
            pivotZ = TAIL_RP_Z_RIDING;
            pivotY = TAIL_RP_Y_RIDING;
            pitch = PI / 5;
        } else {
            setPivot(TAIL_RP_X, TAIL_RP_Y, TAIL_RP_Z_NOTSNEAK);
            if (rainboom) {
                pitch = ROTATE_90 + MathHelper.sin(move) / 10;
            } else {
                pitch = swing / 2;

                swingX(ticks);
            }
        }

        if (rainboom) {
            pivotY += 6;
            pivotZ++;
        }

        tailStop = theModel.getMetadata().getTail().ordinal();
    }

    private void swingX(float ticks) {
        float sinTickFactor = MathHelper.sin(ticks * 0.067f) * 0.05f;
        pitch += sinTickFactor;
        yaw += sinTickFactor;
    }

    private void rotateSneak() {
        setPivot(TAIL_RP_X, TAIL_RP_Y, TAIL_RP_Z_SNEAK);
        pitch = -BODY_ROT_X_SNEAK + 0.1F;
    }

    @Override
    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    @Override
    public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) {
        render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
    }

    private static class Segment extends ModelPart implements MsonModel {

        public PonyTail tail;

        public int index;

        public Segment(Model model) {
            super(model);
        }

        @Override
        public void init(ModelContext context) {
            tail = context.getContext();
            context.findByName("segment", this);
        }

        @Override
        public void render(MatrixStack stack, VertexConsumer renderContext, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
            if (index < tail.tailStop) {
                super.render(stack, renderContext, overlayUv, lightUv, red, green, blue, alpha);
            }
        }
    }
}

@@ -559,34 +559,16 @@
 onyTail 
-extends ModelPart 
 implemen
@@ -606,13 +606,35 @@
 ate 
-final
+ModelPart tail;%0A    private
  Abs
@@ -701,168 +701,165 @@
     
-public PonyTail(AbstractPonyModel%3C?%3E model) %7B%0A        super(model);%0A        theModel = model;%0A    %7D%0A%0A%0A    @Override%0A    public void init(ModelContext context) %7B
+@Override%0A    public void init(ModelContext context) %7B%0A        theModel = (AbstractPonyModel%3C?%3E)context.getModel();%0A%0A        tail = new ModelPart(theModel);%0A
 %0A   
@@ -1126,16 +1126,21 @@
         
+tail.
 addChild
@@ -1444,16 +1444,21 @@
         
+tail.
 roll = r
@@ -1519,24 +1519,29 @@
 ng;%0A        
+tail.
 yaw = bodySw
@@ -1688,24 +1688,29 @@
             
+tail.
 pivotZ = TAI
@@ -1732,24 +1732,29 @@
             
+tail.
 pivotY = TAI
@@ -1772,32 +1772,37 @@
 NG;%0A            
+tail.
 pitch = PI / 5;%0A
@@ -1822,32 +1822,37 @@
 e %7B%0A            
+tail.
 setPivot(TAIL_RP
@@ -1923,32 +1923,37 @@
                 
+tail.
 pitch = ROTATE_9
@@ -2012,32 +2012,37 @@
                 
+tail.
 pitch = swing / 
@@ -2133,24 +2133,29 @@
             
+tail.
 pivotY += 6;
@@ -2167,16 +2167,21 @@
         
+tail.
 pivotZ++
@@ -2376,24 +2376,29 @@
 5f;%0A        
+tail.
 pitch += sin
@@ -2417,16 +2417,21 @@
         
+tail.
 yaw += s
@@ -2492,16 +2492,21 @@
         
+tail.
 setPivot
@@ -2554,16 +2554,21 @@
         
+tail.
 pitch = 
@@ -2669,19 +2669,19 @@
        t
-his
+ail
 .visible
@@ -2892,16 +2892,21 @@
         
+tail.
 render(s

Fix loading error when instantiating the pony tail