package net.minecraft.server.bossevents;

import net.minecraft.nbt.IntArrayTag;
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 uh, final Component mr) {
        super(mr, BossBarColor.WHITE, BossBarOverlay.PROGRESS);
        this.players = Sets.newHashSet();
        this.max = 100;
        this.id = uh;
        this.setPercent(0.0f);
    }
    
    public ResourceLocation getTextId() {
        return this.id;
    }
    
    @Override
    public void addPlayer(final ServerPlayer ze) {
        super.addPlayer(ze);
        this.players.add(ze.getUUID());
    }
    
    public void addOfflinePlayer(final UUID uUID) {
        this.players.add(uUID);
    }
    
    @Override
    public void removePlayer(final ServerPlayer ze) {
        super.removePlayer(ze);
        this.players.remove(ze.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 mv;
        final Style style;
        return ComponentUtils.wrapInSquareBrackets(this.getName()).withStyle(nb -> {
            nb.withColor(this.getColor().getFormatting());
            new HoverEvent((HoverEvent.Action<TextComponent>)HoverEvent.Action.SHOW_TEXT, new TextComponent(this.getTextId().toString()));
            return style.withHoverEvent(mv).withInsertion(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 ze9 : collection) {
                if (ze9.getUUID().equals(uUID6)) {
                    boolean7 = true;
                    break;
                }
            }
            if (!boolean7) {
                set3.add(uUID6);
            }
        }
        for (final ServerPlayer ze10 : collection) {
            boolean boolean7 = false;
            for (final UUID uUID7 : this.players) {
                if (ze10.getUUID().equals(uUID7)) {
                    boolean7 = true;
                    break;
                }
            }
            if (!boolean7) {
                set4.add(ze10);
            }
        }
        for (final UUID uUID6 : set3) {
            for (final ServerPlayer ze11 : this.getPlayers()) {
                if (ze11.getUUID().equals(uUID6)) {
                    this.removePlayer(ze11);
                    break;
                }
            }
            this.players.remove(uUID6);
        }
        for (final ServerPlayer ze10 : set4) {
            this.addPlayer(ze10);
        }
        return !set3.isEmpty() || !set4.isEmpty();
    }
    
    public CompoundTag save() {
        final CompoundTag le2 = new CompoundTag();
        le2.putString("Name", Component.Serializer.toJson(this.name));
        le2.putBoolean("Visible", this.isVisible());
        le2.putInt("Value", this.value);
        le2.putInt("Max", this.max);
        le2.putString("Color", this.getColor().getName());
        le2.putString("Overlay", this.getOverlay().getName());
        le2.putBoolean("DarkenScreen", this.shouldDarkenScreen());
        le2.putBoolean("PlayBossMusic", this.shouldPlayBossMusic());
        le2.putBoolean("CreateWorldFog", this.shouldCreateWorldFog());
        final ListTag lk3 = new ListTag();
        for (final UUID uUID5 : this.players) {
            ((AbstractList<IntArrayTag>)lk3).add(NbtUtils.createUUID(uUID5));
        }
        le2.put("Players", lk3);
        return le2;
    }
    
    public static CustomBossEvent load(final CompoundTag le, final ResourceLocation uh) {
        final CustomBossEvent uz3 = new CustomBossEvent(uh, Component.Serializer.fromJson(le.getString("Name")));
        uz3.setVisible(le.getBoolean("Visible"));
        uz3.setValue(le.getInt("Value"));
        uz3.setMax(le.getInt("Max"));
        uz3.setColor(BossBarColor.byName(le.getString("Color")));
        uz3.setOverlay(BossBarOverlay.byName(le.getString("Overlay")));
        uz3.setDarkenScreen(le.getBoolean("DarkenScreen"));
        uz3.setPlayBossMusic(le.getBoolean("PlayBossMusic"));
        uz3.setCreateWorldFog(le.getBoolean("CreateWorldFog"));
        final ListTag lk4 = le.getList("Players", 11);
        for (int integer5 = 0; integer5 < lk4.size(); ++integer5) {
            uz3.addOfflinePlayer(NbtUtils.loadUUID(lk4.get(integer5)));
        }
        return uz3;
    }
    
    public void onPlayerConnect(final ServerPlayer ze) {
        if (this.players.contains(ze.getUUID())) {
            this.addPlayer(ze);
        }
    }
    
    public void onPlayerDisconnect(final ServerPlayer ze) {
        super.removePlayer(ze);
    }
}
