package tconstruct.client;

import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HEALTH;

import java.util.Random;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.potion.Potion;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;

import org.lwjgl.opengl.GL11;

import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;

public class HealthBarRenderer extends Gui {

    private static final boolean isRpghudLoaded = Loader.isModLoaded("rpghud");
    private static final boolean isTukmc_vzLoaded = Loader.isModLoaded("tukmc_Vz");
    private static final boolean isBorderlandsModLoaded = Loader.isModLoaded("borderlands");
    private static final ResourceLocation TINKER_HEARTS = new ResourceLocation("tinker", "textures/gui/newhearts.png");
    private static final Minecraft mc = Minecraft.getMinecraft();
    private final Random rand = new Random();
    private int updateCounter = 0;

    @SubscribeEvent
    public void onTick(TickEvent.ClientTickEvent event) {
        if (event.phase == TickEvent.Phase.START && !mc.isGamePaused()) {
            this.updateCounter++;
        }
    }

    /* HUD */
    @SubscribeEvent(priority = EventPriority.HIGH) // Not highest for DualHotbar compatibility
    public void renderHealthbar(RenderGameOverlayEvent.Pre event) {

        if (event.type != RenderGameOverlayEvent.ElementType.HEALTH) {
            return;
        }

        // uses different display, displays health correctly by itself.
        if (isRpghudLoaded) {
            return;
        }

        if (isTukmc_vzLoaded && !isBorderlandsModLoaded) {
            // Loader check to avoid conflicting
            // with a GUI mod (thanks Vazkii!)
            return;
        }

        mc.mcProfiler.startSection("health");
        GL11.glEnable(GL11.GL_BLEND);

        final int width = event.resolution.getScaledWidth();
        final int height = event.resolution.getScaledHeight();
        final int xBasePos = width / 2 - 91;
        int yBasePos = height - 39;

        boolean highlight = mc.thePlayer.hurtResistantTime / 3 % 2 == 1;

        if (mc.thePlayer.hurtResistantTime < 10) {
            highlight = false;
        }

        final IAttributeInstance attrMaxHealth = mc.thePlayer.getEntityAttribute(SharedMonsterAttributes.maxHealth);
        final int health = MathHelper.ceiling_float_int(mc.thePlayer.getHealth());
        final int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
        final float healthMax = Math.min(20F, (float) attrMaxHealth.getAttributeValue());
        final float absorb = mc.thePlayer.getAbsorptionAmount();

        final int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
        final int rowHeight = Math.max(10 - (healthRows - 2), 3);

        this.rand.setSeed(updateCounter * 312871L);

        int left = width / 2 - 91;
        int top = height - GuiIngameForge.left_height;

        if (!GuiIngameForge.renderExperiance) {
            top += 7;
            yBasePos += 7;
        }

        int regen = -1;
        if (mc.thePlayer.isPotionActive(Potion.regeneration)) {
            regen = updateCounter % 25;
        }

        final int TOP;
        int tinkerTextureY = 0;
        if (mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) {
            TOP = 9 * 5;
            tinkerTextureY += 27;
        } else {
            TOP = 0;
        }
        final int BACKGROUND = (highlight ? 25 : 16);
        int MARGIN = 16;
        if (mc.thePlayer.isPotionActive(Potion.poison)) {
            MARGIN += 36;
            tinkerTextureY = 9;
        } else if (mc.thePlayer.isPotionActive(Potion.wither)) {
            MARGIN += 72;
            tinkerTextureY = 18;
        }
        float absorbRemaining = absorb;

        // Render vanilla hearts
        for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i) {
            final int row = MathHelper.ceiling_float_int((float) (i + 1) / 10.0F) - 1;
            int x = left + i % 10 * 8;
            int y = top - row * rowHeight;

            if (health <= 4) y += rand.nextInt(2);
            if (i == regen) y -= 2;

            this.drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9); // heart background texture

            if (highlight) {
                if (i * 2 + 1 < healthLast) {
                    this.drawTexturedModalRect(x, y, MARGIN + 54, TOP, 9, 9); // full heart damage texture
                } else if (i * 2 + 1 == healthLast) {
                    this.drawTexturedModalRect(x, y, MARGIN + 63, TOP, 9, 9); // half heart damage texture
                }
            }

            if (absorbRemaining > 0.0F) {
                if (absorbRemaining == absorb && absorb % 2.0F == 1.0F) {
                    this.drawTexturedModalRect(x, y, MARGIN + 153, TOP, 9, 9); // half heart absorption texture
                } else {
                    this.drawTexturedModalRect(x, y, MARGIN + 144, TOP, 9, 9); // full heart absorption texture
                }
                absorbRemaining -= 2.0F;
            } else if (i * 2 + 1 + 20 >= health) {
                // only draw red vanilla hearts when it won't be covered by tinkers' hearts
                if (i * 2 + 1 < health) {
                    this.drawTexturedModalRect(x, y, MARGIN + 36, TOP, 9, 9); // full heart texture
                } else if (i * 2 + 1 == health) {
                    this.drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); // half heart texture
                }
            }
        }

        if (health > 20) {
            // Render tinkers' hearts
            mc.getTextureManager().bindTexture(TINKER_HEARTS);
            for (int i = Math.max(0, health / 20 - 2); i < health / 20; i++) {
                // uncomment the line below to help with debugging
                // yBasePos -=20;
                final int heartIndexMax = Math.min(10, (health - 20 * (i + 1)) / 2);
                for (int j = 0; j < heartIndexMax; j++) {
                    int y = 0;
                    if (j == regen) y -= 2;
                    if ((i + 1) * 20 + j * 2 + 21 >= health) {
                        // full heart texture
                        this.drawTexturedModalRect(xBasePos + 8 * j, yBasePos + y, 18 * i, tinkerTextureY, 9, 9);
                    }
                }
                if (health % 2 == 1 && heartIndexMax < 10) {
                    int y = 0;
                    if (heartIndexMax == regen) y -= 2;
                    // half heart texture
                    this.drawTexturedModalRect(
                            xBasePos + 8 * heartIndexMax,
                            yBasePos + y,
                            9 + 18 * i,
                            tinkerTextureY,
                            9,
                            9);
                }
            }
            mc.getTextureManager().bindTexture(icons);
        }

        GuiIngameForge.left_height += 10;
        if (absorb > 0) GuiIngameForge.left_height += 10;
        GL11.glDisable(GL11.GL_BLEND);
        mc.mcProfiler.endSection();
        event.setCanceled(true);
        MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(event, HEALTH));

    }

}

// Render vanilla hearts
package tconstruct.client;

import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HEALTH;

import java.util.Random;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.potion.Potion;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;

import org.lwjgl.opengl.GL11;

import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;

public class HealthBarRenderer extends Gui {

    private static final boolean isRpghudLoaded = Loader.isModLoaded("rpghud");
    private static final boolean isTukmc_vzLoaded = Loader.isModLoaded("tukmc_Vz");
    private static final boolean isBorderlandsModLoaded = Loader.isModLoaded("borderlands");
    private static final ResourceLocation TINKER_HEARTS = new ResourceLocation("tinker", "textures/gui/newhearts.png");
    private static final Minecraft mc = Minecraft.getMinecraft();
    private final Random rand = new Random();
    private int updateCounter = 0;

    @SubscribeEvent
    public void onTick(TickEvent.ClientTickEvent event) {
        if (event.phase == TickEvent.Phase.START && !mc.isGamePaused()) {
            this.updateCounter++;
        }
    }

    /* HUD */
    @SubscribeEvent(priority = EventPriority.HIGH) // Not highest for DualHotbar compatibility
    public void renderHealthbar(RenderGameOverlayEvent.Pre event) {

        if (event.type != RenderGameOverlayEvent.ElementType.HEALTH) {
            return;
        }

        // uses different display, displays health correctly by itself.
        if (isRpghudLoaded) {
            return;
        }

        if (isTukmc_vzLoaded && !isBorderlandsModLoaded) {
            // Loader check to avoid conflicting
            // with a GUI mod (thanks Vazkii!)
            return;
        }

        mc.mcProfiler.startSection("health");
        GL11.glEnable(GL11.GL_BLEND);

        final int width = event.resolution.getScaledWidth();
        final int height = event.resolution.getScaledHeight();
        final int xBasePos = width / 2 - 91;
        int yBasePos = height - 39;

        boolean highlight = mc.thePlayer.hurtResistantTime / 3 % 2 == 1;

        if (mc.thePlayer.hurtResistantTime < 10) {
            highlight = false;
        }

        final IAttributeInstance attrMaxHealth = mc.thePlayer.getEntityAttribute(SharedMonsterAttributes.maxHealth);
        final int health = MathHelper.ceiling_float_int(mc.thePlayer.getHealth());
        final int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
        final float healthMax = Math.min(20F, (float) attrMaxHealth.getAttributeValue());
        final float absorb = mc.thePlayer.getAbsorptionAmount();

        final int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
        final int rowHeight = Math.max(10 - (healthRows - 2), 3);

        this.rand.setSeed(updateCounter * 312871L);

        int left = width / 2 - 91;
        int top = height - GuiIngameForge.left_height;

        if (!GuiIngameForge.renderExperiance) {
            top += 7;
            yBasePos += 7;
        }

        int regen = -1;
        if (mc.thePlayer.isPotionActive(Potion.regeneration)) {
            regen = updateCounter % 25;
        }

        final int TOP;
        int tinkerTextureY = 0;
        if (mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) {
            TOP = 9 * 5;
            tinkerTextureY += 27;
        } else {
            TOP = 0;
        }
        final int BACKGROUND = (highlight ? 25 : 16);
        int MARGIN = 16;
        if (mc.thePlayer.isPotionActive(Potion.poison)) {
            MARGIN += 36;
            tinkerTextureY = 9;
        } else if (mc.thePlayer.isPotionActive(Potion.wither)) {
            MARGIN += 72;
            tinkerTextureY = 18;
        }
        float absorbRemaining = absorb;

        // Render vanilla<SUF>
        for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i) {
            final int row = MathHelper.ceiling_float_int((float) (i + 1) / 10.0F) - 1;
            int x = left + i % 10 * 8;
            int y = top - row * rowHeight;

            if (health <= 4) y += rand.nextInt(2);
            if (i == regen) y -= 2;

            this.drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9); // heart background texture

            if (highlight) {
                if (i * 2 + 1 < healthLast) {
                    this.drawTexturedModalRect(x, y, MARGIN + 54, TOP, 9, 9); // full heart damage texture
                } else if (i * 2 + 1 == healthLast) {
                    this.drawTexturedModalRect(x, y, MARGIN + 63, TOP, 9, 9); // half heart damage texture
                }
            }

            if (absorbRemaining > 0.0F) {
                if (absorbRemaining == absorb && absorb % 2.0F == 1.0F) {
                    this.drawTexturedModalRect(x, y, MARGIN + 153, TOP, 9, 9); // half heart absorption texture
                } else {
                    this.drawTexturedModalRect(x, y, MARGIN + 144, TOP, 9, 9); // full heart absorption texture
                }
                absorbRemaining -= 2.0F;
            } else if (i * 2 + 1 + 20 >= health) {
                // only draw red vanilla hearts when it won't be covered by tinkers' hearts
                if (i * 2 + 1 < health) {
                    this.drawTexturedModalRect(x, y, MARGIN + 36, TOP, 9, 9); // full heart texture
                } else if (i * 2 + 1 == health) {
                    this.drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); // half heart texture
                }
            }
        }

        if (health > 20) {
            // Render tinkers' hearts
            mc.getTextureManager().bindTexture(TINKER_HEARTS);
            for (int i = Math.max(0, health / 20 - 2); i < health / 20; i++) {
                // uncomment the line below to help with debugging
                // yBasePos -=20;
                final int heartIndexMax = Math.min(10, (health - 20 * (i + 1)) / 2);
                for (int j = 0; j < heartIndexMax; j++) {
                    int y = 0;
                    if (j == regen) y -= 2;
                    if ((i + 1) * 20 + j * 2 + 21 >= health) {
                        // full heart texture
                        this.drawTexturedModalRect(xBasePos + 8 * j, yBasePos + y, 18 * i, tinkerTextureY, 9, 9);
                    }
                }
                if (health % 2 == 1 && heartIndexMax < 10) {
                    int y = 0;
                    if (heartIndexMax == regen) y -= 2;
                    // half heart texture
                    this.drawTexturedModalRect(
                            xBasePos + 8 * heartIndexMax,
                            yBasePos + y,
                            9 + 18 * i,
                            tinkerTextureY,
                            9,
                            9);
                }
            }
            mc.getTextureManager().bindTexture(icons);
        }

        GuiIngameForge.left_height += 10;
        if (absorb > 0) GuiIngameForge.left_height += 10;
        GL11.glDisable(GL11.GL_BLEND);
        mc.mcProfiler.endSection();
        event.setCanceled(true);
        MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(event, HEALTH));

    }

}
