package com.zivilon.cinder_loe.mixins;

import com.zivilon.cinder_loe.CinderLoE_Config;
import org.lwjgl.opengl.GL11;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

import io.gitlab.dwarfyassassin.lotrucp.client.util.FakeArmorStandEntity;

import lotr.client.LOTRClientProxy;
import lotr.client.model.LOTRArmorModels;
import lotr.client.model.LOTRModelBiped;
import lotr.client.render.tileentity.LOTRRenderArmorStand;
import lotr.common.tileentity.LOTRTileEntityArmorStand;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.ForgeHooksClient;

@Mixin(LOTRRenderArmorStand.class)
public abstract class MixinLOTRRenderArmorStand extends TileEntitySpecialRenderer {

    @Shadow(remap = false)
    private static ModelBase standModel;
    @Shadow(remap = false)
    private static ResourceLocation standTexture;
    @Shadow(remap = false)
    private static ModelBiped modelBipedMain;
    @Shadow(remap = false)
    private static ModelBiped modelBiped1;
    @Shadow(remap = false)
    private static ModelBiped modelBiped2;
    @Shadow(remap = false)
    private static float BIPED_ARM_ROTATION;
    @Shadow(remap = false)
    private static float BIPED_TICKS_EXISTED;


    /**
    * @author Shinare
    * @reason Added support configurable enchantment colour
    */
    @Overwrite(remap = false)
    public void func_147500_a(TileEntity tileentity, double d, double d1, double d2, float f) {
        LOTRTileEntityArmorStand armorStand = (LOTRTileEntityArmorStand)tileentity;
        FakeArmorStandEntity fakeArmorStandEntity = FakeArmorStandEntity.INSTANCE;
        GL11.glPushMatrix();
        GL11.glDisable(2884);
        GL11.glEnable(32826);
        GL11.glEnable(3008);
        GL11.glTranslatef((float)d + 0.5F, (float)d1 + 1.5F, (float)d2 + 0.5F);
        switch (armorStand.getBlockMetadata() & 0x3) {
            case 0:
                GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
                break;
            case 1:
                GL11.glRotatef(270.0F, 0.0F, 1.0F, 0.0F);
                break;
            case 2:
                GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
                break;
            case 3:
                GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
                break;
        }
        GL11.glScalef(-1.0F, -1.0F, 1.0F);
        float scale = 0.0625F;
        bindTexture(standTexture);
        standModel.render((Entity)fakeArmorStandEntity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, scale);
        LOTRArmorModels.INSTANCE.setupModelForRender(modelBipedMain, null, (EntityLivingBase)fakeArmorStandEntity);
        GL11.glTranslatef(0.0F, -0.1875F, 0.0F);
        for (int slot = 0; slot < 4; slot++) {
            ItemStack itemstack = armorStand.getStackInSlot(slot);
            if (itemstack != null && (itemstack.getItem() instanceof ItemArmor || itemstack.getItem() instanceof lotr.common.item.LOTRItemPlate)) {
                boolean isArmor = itemstack.getItem() instanceof ItemArmor;
                if (isArmor)
                    bindTexture(RenderBiped.getArmorResource((Entity)fakeArmorStandEntity, itemstack, slot, null));
                ModelBiped armorModel = (slot == 2) ? modelBiped2 : modelBiped1;
                LOTRArmorModels.INSTANCE.setupArmorForSlot(armorModel, slot);
                armorModel = ForgeHooksClient.getArmorModel((EntityLivingBase)fakeArmorStandEntity, itemstack, slot, armorModel);
                ModelBiped specialModel = LOTRArmorModels.INSTANCE.getSpecialArmorModel(itemstack, slot, (EntityLivingBase)fakeArmorStandEntity, modelBipedMain);
                if (specialModel != null)
                    armorModel = specialModel;
                LOTRArmorModels.INSTANCE.setupModelForRender(armorModel, null, (EntityLivingBase)fakeArmorStandEntity);
                float f1 = 1.0F;
                boolean isColoredArmor = false;
                if (isArmor) {
                    int j = ((ItemArmor)itemstack.getItem()).getColor(itemstack);
                    if (j != -1) {
                        float f2 = (j >> 16 & 0xFF) / 255.0F;
                        float f3 = (j >> 8 & 0xFF) / 255.0F;
                        float f4 = (j & 0xFF) / 255.0F;
                        GL11.glColor3f(f1 * f2, f1 * f3, f1 * f4);
                        isColoredArmor = true;
                    } else {
                        GL11.glColor3f(f1, f1, f1);
                    }
                } else {
                    GL11.glColor3f(f1, f1, f1);
                }
                armorModel.render((Entity)fakeArmorStandEntity, BIPED_ARM_ROTATION, 0.0F, BIPED_TICKS_EXISTED, 0.0F, 0.0F, scale);
                if (isColoredArmor) {
                    bindTexture(RenderBiped.getArmorResource(null, itemstack, slot, "overlay"));
                    f1 = 1.0F;
                    GL11.glColor3f(f1, f1, f1);
                    armorModel.render((Entity)fakeArmorStandEntity, BIPED_ARM_ROTATION, 0.0F, BIPED_TICKS_EXISTED, 0.0F, 0.0F, scale);
                }
                if (itemstack.isItemEnchanted()) {
                    float f2 = armorStand.ticksExisted + f;
                    bindTexture(LOTRClientProxy.enchantmentTexture);
                    GL11.glEnable(3042);
                    float f3 = 0.5F;
                    GL11.glColor4f(f3, f3, f3, 1.0F);
                    GL11.glDepthFunc(514);
                    GL11.glDepthMask(false);
                    for (int k = 0; k < 2; k++) {
                        GL11.glDisable(2896);
                        GL11.glColor4f(CinderLoE_Config.enchantment_color_red, CinderLoE_Config.enchantment_color_green, CinderLoE_Config.enchantment_color_blue, 1.0F);
                        GL11.glBlendFunc(768, 1);
                        GL11.glMatrixMode(5890);
                        GL11.glLoadIdentity();
                        float f5 = 0.33333334F;
                        GL11.glScalef(f5, f5, f5);
                        GL11.glRotatef(30.0F - k * 60.0F, 0.0F, 0.0F, 1.0F);
                        float f6 = f2 * (0.001F + k * 0.003F) * 20.0F;
                        GL11.glTranslatef(0.0F, f6, 0.0F);
                        GL11.glMatrixMode(5888);
                        armorModel.render((Entity)fakeArmorStandEntity, BIPED_ARM_ROTATION, 0.0F, BIPED_TICKS_EXISTED, 0.0F, 0.0F, scale);
                    }
                    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
                    GL11.glMatrixMode(5890);
                    GL11.glDepthMask(true);
                    GL11.glLoadIdentity();
                    GL11.glMatrixMode(5888);
                    GL11.glEnable(2896);
                    GL11.glDisable(3042);
                    GL11.glDepthFunc(515);
                }
            }
        }
        GL11.glEnable(2884);
        GL11.glDisable(32826);
        GL11.glPopMatrix();
    }
}
