package com.minelittlepony.bigpony.minelittlepony;

import com.minelittlepony.api.pony.IPony;
import com.minelittlepony.api.pony.meta.Size;
import com.minelittlepony.bigpony.Cam;
import com.minelittlepony.bigpony.Scaled;
import com.minelittlepony.bigpony.Scaling;
import com.minelittlepony.bigpony.Triple;
import com.minelittlepony.bigpony.hdskins.SkinDetecter;
import com.minelittlepony.client.MineLittlePony;
import com.mojang.authlib.GameProfile;

import java.util.concurrent.CompletableFuture;

import com.minelittlepony.api.model.IModel;
import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;

import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;

public class Main extends PresetDetector implements ClientModInitializer {

    @Override
    public void onInitializeClient() {
        INSTANCE = this;

        PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared);
    }

    private void onPonyModelPrepared(Entity entity, IModel model, ModelAttributes.Mode mode) {

        if (entity instanceof Scaled && !((Scaled)entity).getScaling().isVisual() && isPony((PlayerEntity)entity)) {
            model.getAttributes().visualHeight = entity.getHeight() / model.getSize().getScaleFactor();
        }
    }

    @Override
    public boolean isFillyCam() {
        return MineLittlePony.getInstance().getConfig().fillycam.get();
    }

    @Override
    public boolean isPony(PlayerEntity player) {
        return !MineLittlePony.getInstance().getManager().getPony(player).getRace(false).isHuman();
    }

    @Override
    public CompletableFuture<Identifier> detectPreset(GameProfile profile, Scaling into) {
        return SkinDetecter.getInstance().loadSkin(profile).thenApplyAsync(skin -> {
            // Turn on filly cam so we can get the camera parameters
            MineLittlePony.getInstance().getConfig().fillycam.set(true);

            IPony pony = IPony.forResource(skin);
            Size size = pony.getMetadata().getSize();

            into.setScale(new Triple(size.getScaleFactor()));
            into.setCamera(new Cam(size.getEyeDistanceFactor(), size.getEyeHeightFactor()));

            // We turn off filly cam because it's not needed and might cause issues with buckets if left enabled
            MineLittlePony.getInstance().getConfig().fillycam.set(false);
            MineLittlePony.getInstance().getConfig().save();
            return skin;
        }, MinecraftClient.getInstance());
    }
}

@@ -163,19 +163,48 @@
 ony.
-big
+api.
 pony.
-Cam
+network.fabric.PonyDataCallback
 ;%0Aim
@@ -235,22 +235,17 @@
 bigpony.
-Scaled
+*
 ;%0Aimport
@@ -276,57 +276,28 @@
 ony.
-Scaling;%0Aimport com.minelittlepony.bigpony.Triple
+client.BigPonyClient
 ;%0Aim
@@ -696,24 +696,57 @@
 nitializer;%0A
+import net.fabricmc.api.EnvType;%0A
 import net.m
@@ -1133,16 +1133,372 @@
 pared);%0A
+        PonyDataCallback.EVENT.register((sender, data, noSkin, env) -%3E %7B%0A            if (!BigPony.getInstance().getScaling().isVisual()%0A                    && env == EnvType.CLIENT%0A                    && BigPonyClient.isClientPlayer(sender)) %7B%0A                detectPreset(sender.getGameProfile(), ((Scaled)sender).getScaling());%0A            %7D%0A        %7D);%0A
     %7D%0A%0A 
@@ -1591,17 +1591,16 @@
 mode) %7B%0A
-%0A
         

Use the pony data callback to update a player's size when their skin changes