package net.minecraft.server.level;

import java.util.Collection;
import com.google.common.collect.Lists;
import java.util.Iterator;
import net.minecraft.network.protocol.Packet;
import com.google.common.base.Objects;
import net.minecraft.network.protocol.game.ClientboundBossEventPacket;
import java.util.Collections;
import com.google.common.collect.Sets;
import net.minecraft.util.Mth;
import net.minecraft.network.chat.Component;
import java.util.Set;
import net.minecraft.world.BossEvent;

public class ServerBossEvent extends BossEvent {
    private final Set<ServerPlayer> players;
    private final Set<ServerPlayer> unmodifiablePlayers;
    private boolean visible;
    
    public ServerBossEvent(final Component lf, final BossBarColor a, final BossBarOverlay b) {
        super(Mth.createInsecureUUID(), lf, a, b);
        this.players = Sets.newHashSet();
        this.unmodifiablePlayers = Collections.<ServerPlayer>unmodifiableSet(this.players);
        this.visible = true;
    }
    
    @Override
    public void setPercent(final float float1) {
        if (float1 != this.percent) {
            super.setPercent(float1);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_PCT);
        }
    }
    
    @Override
    public void setColor(final BossBarColor a) {
        if (a != this.color) {
            super.setColor(a);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_STYLE);
        }
    }
    
    @Override
    public void setOverlay(final BossBarOverlay b) {
        if (b != this.overlay) {
            super.setOverlay(b);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_STYLE);
        }
    }
    
    @Override
    public BossEvent setDarkenScreen(final boolean boolean1) {
        if (boolean1 != this.darkenScreen) {
            super.setDarkenScreen(boolean1);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_PROPERTIES);
        }
        return this;
    }
    
    @Override
    public BossEvent setPlayBossMusic(final boolean boolean1) {
        if (boolean1 != this.playBossMusic) {
            super.setPlayBossMusic(boolean1);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_PROPERTIES);
        }
        return this;
    }
    
    @Override
    public BossEvent setCreateWorldFog(final boolean boolean1) {
        if (boolean1 != this.createWorldFog) {
            super.setCreateWorldFog(boolean1);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_PROPERTIES);
        }
        return this;
    }
    
    @Override
    public void setName(final Component lf) {
        if (!Objects.equal(lf, this.name)) {
            super.setName(lf);
            this.broadcast(ClientboundBossEventPacket.Operation.UPDATE_NAME);
        }
    }
    
    private void broadcast(final ClientboundBossEventPacket.Operation a) {
        if (this.visible) {
            final ClientboundBossEventPacket mk3 = new ClientboundBossEventPacket(a, this);
            for (final ServerPlayer xe5 : this.players) {
                xe5.connection.send(mk3);
            }
        }
    }
    
    public void addPlayer(final ServerPlayer xe) {
        if (this.players.add(xe) && this.visible) {
            xe.connection.send(new ClientboundBossEventPacket(ClientboundBossEventPacket.Operation.ADD, this));
        }
    }
    
    public void removePlayer(final ServerPlayer xe) {
        if (this.players.remove(xe) && this.visible) {
            xe.connection.send(new ClientboundBossEventPacket(ClientboundBossEventPacket.Operation.REMOVE, this));
        }
    }
    
    public void removeAllPlayers() {
        if (!this.players.isEmpty()) {
            for (final ServerPlayer xe3 : Lists.<ServerPlayer>newArrayList(this.players)) {
                this.removePlayer(xe3);
            }
        }
    }
    
    public boolean isVisible() {
        return this.visible;
    }
    
    public void setVisible(final boolean boolean1) {
        if (boolean1 != this.visible) {
            this.visible = boolean1;
            for (final ServerPlayer xe4 : this.players) {
                xe4.connection.send(new ClientboundBossEventPacket(boolean1 ? ClientboundBossEventPacket.Operation.ADD : ClientboundBossEventPacket.Operation.REMOVE, this));
            }
        }
    }
    
    public Collection<ServerPlayer> getPlayers() {
        return this.unmodifiablePlayers;
    }
}
