package com.minelittlepony.client.model.armour;

import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ItemStack;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;

import com.google.common.collect.Maps;
import com.minelittlepony.client.ForgeProxy;
import com.minelittlepony.model.armour.ArmourLayer;
import com.minelittlepony.model.armour.ArmourVariant;
import com.minelittlepony.model.armour.IArmourTextureResolver;

import javax.annotation.Nullable;

import java.util.Map;

public class DefaultArmourTextureResolver<T extends LivingEntity> implements IArmourTextureResolver<T> {

    private final Map<String, Identifier> HUMAN_ARMOUR = Maps.newHashMap();
    private final Map<Identifier, Identifier> PONY_ARMOUR = Maps.newHashMap();

    @Override
    public Identifier getArmourTexture(T entity, ItemStack itemstack, EquipmentSlot slot, ArmourLayer layer,  @Nullable String type) {
        ArmorItem item = (ArmorItem) itemstack.getItem();
        String texture = item.getMaterial().getName();

        String domain = "minecraft";

        int idx = texture.indexOf(':');
        if (idx > -1) {
            domain = texture.substring(0, idx);
            texture = texture.substring(idx + 1);
        }

        String customType = type == null ? "" : String.format("_%s", type);

        String ponyRes = String.format("%s:textures/models/armor/%s_layer_%s%s.png", domain, texture, layer.name().toLowerCase(), customType);
        String oldPonyRes = String.format("%s:textures/models/armor/%s_layer_%d%s.png", domain, texture, layer == ArmourLayer.INNER ? 2 : 1, customType);

        Identifier human = getArmorTexture(entity, itemstack, ponyRes, slot, type);
        Identifier pony = ponifyResource(human);

        Identifier oldHuman = getArmorTexture(entity, itemstack, oldPonyRes, slot, type);
        Identifier oldPony = ponifyResource(oldHuman);

        return resolve(pony, oldPony, oldHuman, human);
    }

    private Identifier resolve(Identifier... resources) {
        // check resource packs for either texture.

        ResourceManager manager = MinecraftClient.getInstance().getResourceManager();

        for (Identifier i : resources) {
            if (manager.containsResource(i)) {
                return i;
            }
        }

        return resources[resources.length - 1];
    }

    private Identifier ponifyResource(Identifier human) {
        return PONY_ARMOUR.computeIfAbsent(human, key -> {
            String domain = human.getNamespace();
            if ("minecraft".equals(domain)) {
                domain = "minelittlepony"; // it's a vanilla armor. I provide these.
            }

            return new Identifier(domain, human.getPath().replace(".png", "_pony.png"));
        });
    }

    private Identifier getArmorTexture(T entity, ItemStack item, String def, EquipmentSlot slot, @Nullable String type) {
        return HUMAN_ARMOUR.computeIfAbsent(ForgeProxy.getArmorTexture(entity, item, def, slot, type), Identifier::new);
    }

    @Override
    public ArmourVariant getArmourVariant(ArmourLayer layer, Identifier resolvedTexture) {
        if (resolvedTexture.getPath().endsWith("_pony.png")) {
            return ArmourVariant.NORMAL;
        }
        return ArmourVariant.LEGACY;
    }
}

@@ -328,24 +328,63 @@
 dentifier;%0A%0A
+import com.google.common.base.Strings;%0A
 import com.g
@@ -660,16 +660,71 @@
 lable;%0A%0A
+import java.nio.file.Path;%0Aimport java.nio.file.Paths;%0A
 import j
@@ -2729,21 +2729,19 @@
 omain = 
-human
+key
 .getName
@@ -2937,21 +2937,19 @@
 domain, 
-human
+key
 .getPath
@@ -3115,32 +3115,286 @@
  String type) %7B%0A
+%0A        String modTexture = Strings.nullToEmpty(ForgeProxy.getArmorTexture(entity, item, def, slot, type));%0A%0A        if (modTexture.isEmpty() %7C%7C modTexture.equals(def)) %7B%0A            return HUMAN_ARMOUR.computeIfAbsent(def, Identifier::new);%0A        %7D%0A%0A
         return H
@@ -3425,82 +3425,594 @@
 ent(
-ForgeProxy.getAr
 mo
-r
+d
 Texture
-(entity, item, def, slot, type), Identifier::new
+, s -%3E %7B%0A            Identifier modId = new Identifier(s);%0A            Identifier defId = new Identifier(def);%0A%0A            Path defPath = Paths.get(defId.getPath());%0A%0A            String domain = modId.getNamespace();%0A%0A            String path = Paths.get(modId.getPath()).getParent().resolve(defPath.getFileName()).toString();%0A%0A            Identifier interemId = new Identifier(domain, path);%0A%0A            if (MinecraftClient.getInstance().getResourceManager().containsResource(interemId)) %7B%0A                return interemId;%0A            %7D%0A%0A            return modId;%0A        %7D
 );%0A 

Rewrite armour texture resolution to prioritize our own naming scheme over what mods return