package net.minecraft.world.level.block.entity;

import java.util.function.Supplier;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.BannerBlock;
import com.google.common.collect.Lists;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.level.block.AbstractBannerBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import com.mojang.datafixers.util.Pair;
import java.util.List;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.item.DyeColor;
import javax.annotation.Nullable;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Nameable;

public class BannerBlockEntity extends BlockEntity implements Nameable {
    @Nullable
    private Component name;
    @Nullable
    private DyeColor baseColor;
    @Nullable
    private ListTag itemPatterns;
    private boolean receivedData;
    @Nullable
    private List<Pair<BannerPattern, DyeColor>> patterns;
    
    public BannerBlockEntity() {
        super(BlockEntityType.BANNER);
        this.baseColor = DyeColor.WHITE;
    }
    
    public BannerBlockEntity(final DyeColor bje) {
        this();
        this.baseColor = bje;
    }
    
    @Nullable
    public static ListTag getItemPatterns(final ItemStack bki) {
        ListTag lk2 = null;
        final CompoundTag le3 = bki.getTagElement("BlockEntityTag");
        if (le3 != null && le3.contains("Patterns", 9)) {
            lk2 = le3.getList("Patterns", 10).copy();
        }
        return lk2;
    }
    
    public void fromItem(final ItemStack bki, final DyeColor bje) {
        this.itemPatterns = getItemPatterns(bki);
        this.baseColor = bje;
        this.patterns = null;
        this.receivedData = true;
        this.name = (bki.hasCustomHoverName() ? bki.getHoverName() : null);
    }
    
    @Override
    public Component getName() {
        if (this.name != null) {
            return this.name;
        }
        return new TranslatableComponent("block.minecraft.banner");
    }
    
    @Nullable
    @Override
    public Component getCustomName() {
        return this.name;
    }
    
    public void setCustomName(final Component mr) {
        this.name = mr;
    }
    
    @Override
    public CompoundTag save(final CompoundTag le) {
        super.save(le);
        if (this.itemPatterns != null) {
            le.put("Patterns", this.itemPatterns);
        }
        if (this.name != null) {
            le.putString("CustomName", Component.Serializer.toJson(this.name));
        }
        return le;
    }
    
    @Override
    public void load(final BlockState cfj, final CompoundTag le) {
        super.load(cfj, le);
        if (le.contains("CustomName", 8)) {
            this.name = Component.Serializer.fromJson(le.getString("CustomName"));
        }
        if (this.hasLevel()) {
            this.baseColor = ((AbstractBannerBlock)this.getBlockState().getBlock()).getColor();
        }
        else {
            this.baseColor = null;
        }
        this.itemPatterns = le.getList("Patterns", 10);
        this.patterns = null;
        this.receivedData = true;
    }
    
    @Nullable
    @Override
    public ClientboundBlockEntityDataPacket getUpdatePacket() {
        return new ClientboundBlockEntityDataPacket(this.worldPosition, 6, this.getUpdateTag());
    }
    
    @Override
    public CompoundTag getUpdateTag() {
        return this.save(new CompoundTag());
    }
    
    public static int getPatternCount(final ItemStack bki) {
        final CompoundTag le2 = bki.getTagElement("BlockEntityTag");
        if (le2 != null && le2.contains("Patterns")) {
            return le2.getList("Patterns", 10).size();
        }
        return 0;
    }
    
    public List<Pair<BannerPattern, DyeColor>> getPatterns() {
        if (this.patterns == null && this.receivedData) {
            this.patterns = createPatterns(this.getBaseColor(this::getBlockState), this.itemPatterns);
        }
        return this.patterns;
    }
    
    public static List<Pair<BannerPattern, DyeColor>> createPatterns(final DyeColor bje, @Nullable final ListTag lk) {
        final List<Pair<BannerPattern, DyeColor>> list3 = Lists.newArrayList();
        list3.add((Pair<BannerPattern, DyeColor>)Pair.of(BannerPattern.BASE, bje));
        if (lk != null) {
            for (int integer4 = 0; integer4 < lk.size(); ++integer4) {
                final CompoundTag le5 = lk.getCompound(integer4);
                final BannerPattern cdd6 = BannerPattern.byHash(le5.getString("Pattern"));
                if (cdd6 != null) {
                    final int integer5 = le5.getInt("Color");
                    list3.add((Pair<BannerPattern, DyeColor>)Pair.of(cdd6, DyeColor.byId(integer5)));
                }
            }
        }
        return list3;
    }
    
    public static void removeLastPattern(final ItemStack bki) {
        final CompoundTag le2 = bki.getTagElement("BlockEntityTag");
        if (le2 == null || !le2.contains("Patterns", 9)) {
            return;
        }
        final ListTag lk3 = le2.getList("Patterns", 10);
        if (lk3.isEmpty()) {
            return;
        }
        lk3.remove(lk3.size() - 1);
        if (lk3.isEmpty()) {
            bki.removeTagKey("BlockEntityTag");
        }
    }
    
    public ItemStack getItem(final BlockState cfj) {
        final ItemStack bki3 = new ItemStack(BannerBlock.byColor(this.getBaseColor(() -> cfj)));
        if (this.itemPatterns != null && !this.itemPatterns.isEmpty()) {
            bki3.getOrCreateTagElement("BlockEntityTag").put("Patterns", this.itemPatterns.copy());
        }
        if (this.name != null) {
            bki3.setHoverName(this.name);
        }
        return bki3;
    }
    
    public DyeColor getBaseColor(final Supplier<BlockState> supplier) {
        if (this.baseColor == null) {
            this.baseColor = ((AbstractBannerBlock)supplier.get().getBlock()).getColor();
        }
        return this.baseColor;
    }
}
