package net.minecraft.client.multiplayer;

import org.apache.logging.log4j.LogManager;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ServerboundSeenAdvancementsPacket;
import java.util.Iterator;
import net.minecraft.client.gui.components.toasts.Toast;
import net.minecraft.client.gui.components.toasts.AdvancementToast;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket;
import com.google.common.collect.Maps;
import javax.annotation.Nullable;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.advancements.Advancement;
import java.util.Map;
import net.minecraft.advancements.AdvancementList;
import net.minecraft.client.Minecraft;
import org.apache.logging.log4j.Logger;

public class ClientAdvancements {
    private static final Logger LOGGER;
    private final Minecraft minecraft;
    private final AdvancementList advancements;
    private final Map<Advancement, AdvancementProgress> progress;
    @Nullable
    private Listener listener;
    @Nullable
    private Advancement selectedTab;
    
    public ClientAdvancements(final Minecraft dlx) {
        this.advancements = new AdvancementList();
        this.progress = Maps.newHashMap();
        this.minecraft = dlx;
    }
    
    public void update(final ClientboundUpdateAdvancementsPacket qs) {
        if (qs.shouldReset()) {
            this.advancements.clear();
            this.progress.clear();
        }
        this.advancements.remove(qs.getRemoved());
        this.advancements.add(qs.getAdded());
        for (final Map.Entry<ResourceLocation, AdvancementProgress> entry4 : qs.getProgress().entrySet()) {
            final Advancement w5 = this.advancements.get(entry4.getKey());
            if (w5 != null) {
                final AdvancementProgress y6 = entry4.getValue();
                y6.update(w5.getCriteria(), w5.getRequirements());
                this.progress.put(w5, y6);
                if (this.listener != null) {
                    this.listener.onUpdateAdvancementProgress(w5, y6);
                }
                if (qs.shouldReset() || !y6.isDone() || w5.getDisplay() == null || !w5.getDisplay().shouldShowToast()) {
                    continue;
                }
                this.minecraft.getToasts().addToast(new AdvancementToast(w5));
            }
            else {
                ClientAdvancements.LOGGER.warn("Server informed client about progress for unknown advancement {}", entry4.getKey());
            }
        }
    }
    
    public AdvancementList getAdvancements() {
        return this.advancements;
    }
    
    public void setSelectedTab(@Nullable final Advancement w, final boolean boolean2) {
        final ClientPacketListener dyn4 = this.minecraft.getConnection();
        if (dyn4 != null && w != null && boolean2) {
            dyn4.send(ServerboundSeenAdvancementsPacket.openedTab(w));
        }
        if (this.selectedTab != w) {
            this.selectedTab = w;
            if (this.listener != null) {
                this.listener.onSelectedTabChanged(w);
            }
        }
    }
    
    public void setListener(@Nullable final Listener a) {
        this.listener = a;
        this.advancements.setListener(a);
        if (a != null) {
            for (final Map.Entry<Advancement, AdvancementProgress> entry4 : this.progress.entrySet()) {
                a.onUpdateAdvancementProgress(entry4.getKey(), entry4.getValue());
            }
            a.onSelectedTabChanged(this.selectedTab);
        }
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
    
    public interface Listener extends AdvancementList.Listener {
        void onUpdateAdvancementProgress(final Advancement w, final AdvancementProgress y);
        
        void onSelectedTabChanged(@Nullable final Advancement w);
    }
}
