package net.minecraft.server.bossevents;

import java.util.AbstractList;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.CompoundTag;
import java.util.Iterator;
import java.util.Collection;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.util.Mth;
import net.minecraft.server.level.ServerPlayer;
import com.google.common.collect.Sets;
import net.minecraft.world.BossEvent;
import net.minecraft.network.chat.Component;
import java.util.UUID;
import java.util.Set;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerBossEvent;

public class CustomBossEvent extends ServerBossEvent {
    private final ResourceLocation id;
    private final Set<UUID> players;
    private int value;
    private int max;
    
    public CustomBossEvent(final ResourceLocation sm, final Component lf) {
        super(lf, BossBarColor.WHITE, BossBarOverlay.PROGRESS);
        this.players = Sets.newHashSet();
        this.max = 100;
        this.id = sm;
        this.setPercent(0.0f);
    }
    
    public ResourceLocation getTextId() {
        return this.id;
    }
    
    @Override
    public void addPlayer(final ServerPlayer xe) {
        super.addPlayer(xe);
        this.players.add(xe.getUUID());
    }
    
    public void addOfflinePlayer(final UUID uUID) {
        this.players.add(uUID);
    }
    
    @Override
    public void removePlayer(final ServerPlayer xe) {
        super.removePlayer(xe);
        this.players.remove(xe.getUUID());
    }
    
    @Override
    public void removeAllPlayers() {
        super.removeAllPlayers();
        this.players.clear();
    }
    
    public int getValue() {
        return this.value;
    }
    
    public int getMax() {
        return this.max;
    }
    
    public void setValue(final int integer) {
        this.value = integer;
        this.setPercent(Mth.clamp(integer / (float)this.max, 0.0f, 1.0f));
    }
    
    public void setMax(final int integer) {
        this.max = integer;
        this.setPercent(Mth.clamp(this.value / (float)integer, 0.0f, 1.0f));
    }
    
    public final Component getDisplayName() {
        final HoverEvent hoverEvent;
        final Style style;
        return ComponentUtils.wrapInSquareBrackets(this.getName()).withStyle(ln -> {
            ln.setColor(this.getColor().getFormatting());
            new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent(this.getTextId().toString()));
            style.setHoverEvent(hoverEvent).setInsertion(this.getTextId().toString());
        });
    }
    
    public boolean setPlayers(final Collection<ServerPlayer> collection) {
        final Set<UUID> set3 = Sets.newHashSet();
        final Set<ServerPlayer> set4 = Sets.newHashSet();
        for (final UUID uUID6 : this.players) {
            boolean boolean7 = false;
            for (final ServerPlayer xe9 : collection) {
                if (xe9.getUUID().equals(uUID6)) {
                    boolean7 = true;
                    break;
                }
            }
            if (!boolean7) {
                set3.add(uUID6);
            }
        }
        for (final ServerPlayer xe10 : collection) {
            boolean boolean7 = false;
            for (final UUID uUID7 : this.players) {
                if (xe10.getUUID().equals(uUID7)) {
                    boolean7 = true;
                    break;
                }
            }
            if (!boolean7) {
                set4.add(xe10);
            }
        }
        for (final UUID uUID6 : set3) {
            for (final ServerPlayer xe11 : this.getPlayers()) {
                if (xe11.getUUID().equals(uUID6)) {
                    this.removePlayer(xe11);
                    break;
                }
            }
            this.players.remove(uUID6);
        }
        for (final ServerPlayer xe10 : set4) {
            this.addPlayer(xe10);
        }
        return !set3.isEmpty() || !set4.isEmpty();
    }
    
    public CompoundTag save() {
        final CompoundTag jt2 = new CompoundTag();
        jt2.putString("Name", Component.Serializer.toJson(this.name));
        jt2.putBoolean("Visible", this.isVisible());
        jt2.putInt("Value", this.value);
        jt2.putInt("Max", this.max);
        jt2.putString("Color", this.getColor().getName());
        jt2.putString("Overlay", this.getOverlay().getName());
        jt2.putBoolean("DarkenScreen", this.shouldDarkenScreen());
        jt2.putBoolean("PlayBossMusic", this.shouldPlayBossMusic());
        jt2.putBoolean("CreateWorldFog", this.shouldCreateWorldFog());
        final ListTag jz3 = new ListTag();
        for (final UUID uUID5 : this.players) {
            ((AbstractList<CompoundTag>)jz3).add(NbtUtils.createUUIDTag(uUID5));
        }
        jt2.put("Players", jz3);
        return jt2;
    }
    
    public static CustomBossEvent load(final CompoundTag jt, final ResourceLocation sm) {
        final CustomBossEvent tc3 = new CustomBossEvent(sm, Component.Serializer.fromJson(jt.getString("Name")));
        tc3.setVisible(jt.getBoolean("Visible"));
        tc3.setValue(jt.getInt("Value"));
        tc3.setMax(jt.getInt("Max"));
        tc3.setColor(BossBarColor.byName(jt.getString("Color")));
        tc3.setOverlay(BossBarOverlay.byName(jt.getString("Overlay")));
        tc3.setDarkenScreen(jt.getBoolean("DarkenScreen"));
        tc3.setPlayBossMusic(jt.getBoolean("PlayBossMusic"));
        tc3.setCreateWorldFog(jt.getBoolean("CreateWorldFog"));
        final ListTag jz4 = jt.getList("Players", 10);
        for (int integer5 = 0; integer5 < jz4.size(); ++integer5) {
            tc3.addOfflinePlayer(NbtUtils.loadUUIDTag(jz4.getCompound(integer5)));
        }
        return tc3;
    }
    
    public void onPlayerConnect(final ServerPlayer xe) {
        if (this.players.contains(xe.getUUID())) {
            this.addPlayer(xe);
        }
    }
    
    public void onPlayerDisconnect(final ServerPlayer xe) {
        super.removePlayer(xe);
    }
}
