package net.minecraft.client.gui.components;

import com.google.common.collect.ComparisonChain;
import java.util.Comparator;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import com.mojang.authlib.GameProfile;
import java.util.Iterator;
import java.util.List;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.ChatFormatting;
import net.minecraft.world.level.GameType;
import net.minecraft.world.entity.player.PlayerModelPart;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
import javax.annotation.Nullable;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Scoreboard;
import net.minecraft.Util;
import net.minecraft.world.scores.Team;
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.PlayerInfo;
import com.google.common.collect.Ordering;
import net.minecraft.client.gui.GuiComponent;

public class PlayerTabOverlay extends GuiComponent {
    private static final Ordering<PlayerInfo> PLAYER_ORDERING;
    private final Minecraft minecraft;
    private final Gui gui;
    private Component footer;
    private Component header;
    private long visibilityId;
    private boolean visible;
    
    public PlayerTabOverlay(final Minecraft dbn, final Gui dci) {
        this.minecraft = dbn;
        this.gui = dci;
    }
    
    public Component getNameForDisplay(final PlayerInfo dns) {
        if (dns.getTabListDisplayName() != null) {
            return dns.getTabListDisplayName();
        }
        return PlayerTeam.formatNameForTeam(dns.getTeam(), new TextComponent(dns.getProfile().getName()));
    }
    
    public void setVisible(final boolean boolean1) {
        if (boolean1 && !this.visible) {
            this.visibilityId = Util.getMillis();
        }
        this.visible = boolean1;
    }
    
    public void render(final int integer, final Scoreboard cwl, @Nullable final Objective cwi) {
        final ClientPacketListener dnp5 = this.minecraft.player.connection;
        List<PlayerInfo> list6 = PlayerTabOverlay.PLAYER_ORDERING.<PlayerInfo>sortedCopy(dnp5.getOnlinePlayers());
        int integer2 = 0;
        int integer3 = 0;
        for (final PlayerInfo dns10 : list6) {
            int integer4 = this.minecraft.font.width(this.getNameForDisplay(dns10).getColoredString());
            integer2 = Math.max(integer2, integer4);
            if (cwi != null && cwi.getRenderType() != ObjectiveCriteria.RenderType.HEARTS) {
                integer4 = this.minecraft.font.width(" " + cwl.getOrCreatePlayerScore(dns10.getProfile().getName(), cwi).getScore());
                integer3 = Math.max(integer3, integer4);
            }
        }
        list6 = list6.subList(0, Math.min(list6.size(), 80));
        int integer4;
        int integer6;
        int integer5;
        for (integer5 = (integer6 = list6.size()), integer4 = 1; integer6 > 20; integer6 = (integer5 + integer4 - 1) / integer4) {
            ++integer4;
        }
        final boolean boolean12 = this.minecraft.isLocalServer() || this.minecraft.getConnection().getConnection().isEncrypted();
        int integer7;
        if (cwi != null) {
            if (cwi.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
                integer7 = 90;
            }
            else {
                integer7 = integer3;
            }
        }
        else {
            integer7 = 0;
        }
        final int integer8 = Math.min(integer4 * ((boolean12 ? 9 : 0) + integer2 + integer7 + 13), integer - 50) / integer4;
        final int integer9 = integer / 2 - (integer8 * integer4 + (integer4 - 1) * 5) / 2;
        int integer10 = 10;
        int integer11 = integer8 * integer4 + (integer4 - 1) * 5;
        List<String> list7 = null;
        if (this.header != null) {
            list7 = this.minecraft.font.split(this.header.getColoredString(), integer - 50);
            for (final String string20 : list7) {
                integer11 = Math.max(integer11, this.minecraft.font.width(string20));
            }
        }
        List<String> list8 = null;
        if (this.footer != null) {
            list8 = this.minecraft.font.split(this.footer.getColoredString(), integer - 50);
            for (final String string21 : list8) {
                integer11 = Math.max(integer11, this.minecraft.font.width(string21));
            }
        }
        if (list7 != null) {
            final int integer23 = integer / 2 - integer11 / 2 - 1;
            final int integer24 = integer10 - 1;
            final int integer25 = integer / 2 + integer11 / 2 + 1;
            final int n = integer10;
            final int size = list7.size();
            this.minecraft.font.getClass();
            GuiComponent.fill(integer23, integer24, integer25, n + size * 9, Integer.MIN_VALUE);
            for (final String string21 : list7) {
                final int integer12 = this.minecraft.font.width(string21);
                this.minecraft.font.drawShadow(string21, (float)(integer / 2 - integer12 / 2), (float)integer10, -1);
                final int n2 = integer10;
                this.minecraft.font.getClass();
                integer10 = n2 + 9;
            }
            ++integer10;
        }
        GuiComponent.fill(integer / 2 - integer11 / 2 - 1, integer10 - 1, integer / 2 + integer11 / 2 + 1, integer10 + integer6 * 9, Integer.MIN_VALUE);
        final int integer13 = this.minecraft.options.getBackgroundColor(553648127);
        for (int integer14 = 0; integer14 < integer5; ++integer14) {
            final int integer12 = integer14 / integer6;
            final int integer15 = integer14 % integer6;
            int integer16 = integer9 + integer12 * integer8 + integer12 * 5;
            final int integer17 = integer10 + integer15 * 9;
            GuiComponent.fill(integer16, integer17, integer16 + integer8, integer17 + 8, integer13);
            RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
            RenderSystem.enableAlphaTest();
            RenderSystem.enableBlend();
            RenderSystem.defaultBlendFunc();
            if (integer14 < list6.size()) {
                final PlayerInfo dns11 = list6.get(integer14);
                final GameProfile gameProfile27 = dns11.getProfile();
                if (boolean12) {
                    final Player ayj28 = this.minecraft.level.getPlayerByUUID(gameProfile27.getId());
                    final boolean boolean13 = ayj28 != null && ayj28.isModelPartShown(PlayerModelPart.CAPE) && ("Dinnerbone".equals(gameProfile27.getName()) || "Grumm".equals(gameProfile27.getName()));
                    this.minecraft.getTextureManager().bind(dns11.getSkinLocation());
                    final int integer18 = 8 + (boolean13 ? 8 : 0);
                    final int integer19 = 8 * (boolean13 ? -1 : 1);
                    GuiComponent.blit(integer16, integer17, 8, 8, 8.0f, (float)integer18, 8, integer19, 64, 64);
                    if (ayj28 != null && ayj28.isModelPartShown(PlayerModelPart.HAT)) {
                        final int integer20 = 8 + (boolean13 ? 8 : 0);
                        final int integer21 = 8 * (boolean13 ? -1 : 1);
                        GuiComponent.blit(integer16, integer17, 8, 8, 40.0f, (float)integer20, 8, integer21, 64, 64);
                    }
                    integer16 += 9;
                }
                final String string22 = this.getNameForDisplay(dns11).getColoredString();
                if (dns11.getGameMode() == GameType.SPECTATOR) {
                    this.minecraft.font.drawShadow(ChatFormatting.ITALIC + string22, (float)integer16, (float)integer17, -1862270977);
                }
                else {
                    this.minecraft.font.drawShadow(string22, (float)integer16, (float)integer17, -1);
                }
                if (cwi != null && dns11.getGameMode() != GameType.SPECTATOR) {
                    final int integer22 = integer16 + integer2 + 1;
                    final int integer18 = integer22 + integer7;
                    if (integer18 - integer22 > 5) {
                        this.renderTablistScore(cwi, integer17, gameProfile27.getName(), integer22, integer18, dns11);
                    }
                }
                this.renderPingIcon(integer8, integer16 - (boolean12 ? 9 : 0), integer17, dns11);
            }
        }
        if (list8 != null) {
            integer10 += integer6 * 9 + 1;
            final int integer26 = integer / 2 - integer11 / 2 - 1;
            final int integer27 = integer10 - 1;
            final int integer28 = integer / 2 + integer11 / 2 + 1;
            final int n3 = integer10;
            final int size2 = list8.size();
            this.minecraft.font.getClass();
            GuiComponent.fill(integer26, integer27, integer28, n3 + size2 * 9, Integer.MIN_VALUE);
            for (final String string23 : list8) {
                final int integer15 = this.minecraft.font.width(string23);
                this.minecraft.font.drawShadow(string23, (float)(integer / 2 - integer15 / 2), (float)integer10, -1);
                final int n4 = integer10;
                this.minecraft.font.getClass();
                integer10 = n4 + 9;
            }
        }
    }
    
    protected void renderPingIcon(final int integer1, final int integer2, final int integer3, final PlayerInfo dns) {
        RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
        this.minecraft.getTextureManager().bind(PlayerTabOverlay.GUI_ICONS_LOCATION);
        final int integer4 = 0;
        int integer5;
        if (dns.getLatency() < 0) {
            integer5 = 5;
        }
        else if (dns.getLatency() < 150) {
            integer5 = 0;
        }
        else if (dns.getLatency() < 300) {
            integer5 = 1;
        }
        else if (dns.getLatency() < 600) {
            integer5 = 2;
        }
        else if (dns.getLatency() < 1000) {
            integer5 = 3;
        }
        else {
            integer5 = 4;
        }
        this.setBlitOffset(this.getBlitOffset() + 100);
        this.blit(integer2 + integer1 - 11, integer3, 0, 176 + integer5 * 8, 10, 8);
        this.setBlitOffset(this.getBlitOffset() - 100);
    }
    
    private void renderTablistScore(final Objective cwi, final int integer2, final String string, final int integer4, final int integer5, final PlayerInfo dns) {
        final int integer6 = cwi.getScoreboard().getOrCreatePlayerScore(string, cwi).getScore();
        if (cwi.getRenderType() == ObjectiveCriteria.RenderType.HEARTS) {
            this.minecraft.getTextureManager().bind(PlayerTabOverlay.GUI_ICONS_LOCATION);
            final long long9 = Util.getMillis();
            if (this.visibilityId == dns.getRenderVisibilityId()) {
                if (integer6 < dns.getLastHealth()) {
                    dns.setLastHealthTime(long9);
                    dns.setHealthBlinkTime(this.gui.getGuiTicks() + 20);
                }
                else if (integer6 > dns.getLastHealth()) {
                    dns.setLastHealthTime(long9);
                    dns.setHealthBlinkTime(this.gui.getGuiTicks() + 10);
                }
            }
            if (long9 - dns.getLastHealthTime() > 1000L || this.visibilityId != dns.getRenderVisibilityId()) {
                dns.setLastHealth(integer6);
                dns.setDisplayHealth(integer6);
                dns.setLastHealthTime(long9);
            }
            dns.setRenderVisibilityId(this.visibilityId);
            dns.setLastHealth(integer6);
            final int integer7 = Mth.ceil(Math.max(integer6, dns.getDisplayHealth()) / 2.0f);
            final int integer8 = Math.max(Mth.ceil((float)(integer6 / 2)), Math.max(Mth.ceil((float)(dns.getDisplayHealth() / 2)), 10));
            final boolean boolean13 = dns.getHealthBlinkTime() > this.gui.getGuiTicks() && (dns.getHealthBlinkTime() - this.gui.getGuiTicks()) / 3L % 2L == 1L;
            if (integer7 > 0) {
                final int integer9 = Mth.floor(Math.min((integer5 - integer4 - 4) / (float)integer8, 9.0f));
                if (integer9 > 3) {
                    for (int integer10 = integer7; integer10 < integer8; ++integer10) {
                        this.blit(integer4 + integer10 * integer9, integer2, boolean13 ? 25 : 16, 0, 9, 9);
                    }
                    for (int integer10 = 0; integer10 < integer7; ++integer10) {
                        this.blit(integer4 + integer10 * integer9, integer2, boolean13 ? 25 : 16, 0, 9, 9);
                        if (boolean13) {
                            if (integer10 * 2 + 1 < dns.getDisplayHealth()) {
                                this.blit(integer4 + integer10 * integer9, integer2, 70, 0, 9, 9);
                            }
                            if (integer10 * 2 + 1 == dns.getDisplayHealth()) {
                                this.blit(integer4 + integer10 * integer9, integer2, 79, 0, 9, 9);
                            }
                        }
                        if (integer10 * 2 + 1 < integer6) {
                            this.blit(integer4 + integer10 * integer9, integer2, (integer10 >= 10) ? 160 : 52, 0, 9, 9);
                        }
                        if (integer10 * 2 + 1 == integer6) {
                            this.blit(integer4 + integer10 * integer9, integer2, (integer10 >= 10) ? 169 : 61, 0, 9, 9);
                        }
                    }
                }
                else {
                    final float float15 = Mth.clamp(integer6 / 20.0f, 0.0f, 1.0f);
                    final int integer11 = (int)((1.0f - float15) * 255.0f) << 16 | (int)(float15 * 255.0f) << 8;
                    String string2 = "" + integer6 / 2.0f;
                    if (integer5 - this.minecraft.font.width(string2 + "hp") >= integer4) {
                        string2 += "hp";
                    }
                    this.minecraft.font.drawShadow(string2, (float)((integer5 + integer4) / 2 - this.minecraft.font.width(string2) / 2), (float)integer2, integer11);
                }
            }
        }
        else {
            final String string3 = ChatFormatting.YELLOW + "" + integer6;
            this.minecraft.font.drawShadow(string3, (float)(integer5 - this.minecraft.font.width(string3)), (float)integer2, 16777215);
        }
    }
    
    public void setFooter(@Nullable final Component lf) {
        this.footer = lf;
    }
    
    public void setHeader(@Nullable final Component lf) {
        this.header = lf;
    }
    
    public void reset() {
        this.header = null;
        this.footer = null;
    }
    
    static {
        PLAYER_ORDERING = Ordering.<PlayerInfo>from((Comparator<PlayerInfo>)new PlayerInfoComparator());
    }
    
    static class PlayerInfoComparator implements Comparator<PlayerInfo> {
        private PlayerInfoComparator() {
        }
        
        @Override
        public int compare(final PlayerInfo dns1, final PlayerInfo dns2) {
            final PlayerTeam cwj4 = dns1.getTeam();
            final PlayerTeam cwj5 = dns2.getTeam();
            return ComparisonChain.start().compareTrueFirst(dns1.getGameMode() != GameType.SPECTATOR, dns2.getGameMode() != GameType.SPECTATOR).compare((cwj4 != null) ? cwj4.getName() : "", (cwj5 != null) ? cwj5.getName() : "").<String>compare(dns1.getProfile().getName(), dns2.getProfile().getName(), String::compareToIgnoreCase).result();
        }
    }
}
