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 dbn) {
        this.advancements = new AdvancementList();
        this.progress = Maps.newHashMap();
        this.minecraft = dbn;
    }
    
    public void update(final ClientboundUpdateAdvancementsPacket pe) {
        if (pe.shouldReset()) {
            this.advancements.clear();
            this.progress.clear();
        }
        this.advancements.remove(pe.getRemoved());
        this.advancements.add(pe.getAdded());
        for (final Map.Entry<ResourceLocation, AdvancementProgress> entry4 : pe.getProgress().entrySet()) {
            final Advancement u5 = this.advancements.get(entry4.getKey());
            if (u5 != null) {
                final AdvancementProgress w6 = entry4.getValue();
                w6.update(u5.getCriteria(), u5.getRequirements());
                this.progress.put(u5, w6);
                if (this.listener != null) {
                    this.listener.onUpdateAdvancementProgress(u5, w6);
                }
                if (pe.shouldReset() || !w6.isDone() || u5.getDisplay() == null || !u5.getDisplay().shouldShowToast()) {
                    continue;
                }
                this.minecraft.getToasts().addToast(new AdvancementToast(u5));
            }
            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 u, final boolean boolean2) {
        final ClientPacketListener dnp4 = this.minecraft.getConnection();
        if (dnp4 != null && u != null && boolean2) {
            dnp4.send(ServerboundSeenAdvancementsPacket.openedTab(u));
        }
        if (this.selectedTab != u) {
            this.selectedTab = u;
            if (this.listener != null) {
                this.listener.onSelectedTabChanged(u);
            }
        }
    }
    
    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 u, final AdvancementProgress w);
        
        void onSelectedTabChanged(@Nullable final Advancement u);
    }
}
