package net.minecraft.world.item;

import java.util.AbstractList;
import org.apache.logging.log4j.LogManager;
import net.minecraft.sounds.SoundEvent;
import java.util.function.Predicate;
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
import net.minecraft.tags.TagManager;
import java.util.Objects;
import net.minecraft.network.chat.HoverEvent;
import com.google.common.collect.HashMultimap;
import net.minecraft.world.item.enchantment.Enchantment;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.function.Function;
import net.minecraft.world.level.block.Block;
import net.minecraft.tags.BlockTags;
import net.minecraft.commands.arguments.blocks.BlockStateParser;
import com.mojang.brigadier.StringReader;
import java.util.Iterator;
import com.google.common.collect.Multimap;
import java.util.Collection;
import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.monster.SharedMonsterAttributes;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import java.util.Map;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.TextComponent;
import com.google.common.collect.Lists;
import java.util.List;
import com.google.gson.JsonParseException;
import net.minecraft.network.chat.Component;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.entity.Entity;
import java.util.function.Consumer;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.world.item.enchantment.DigDurabilityEnchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import javax.annotation.Nullable;
import net.minecraft.server.level.ServerPlayer;
import java.util.Random;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.stats.Stat;
import net.minecraft.stats.Stats;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.InteractionResult;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Registry;
import net.minecraft.world.level.ItemLike;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.nbt.CompoundTag;
import java.text.DecimalFormat;
import org.apache.logging.log4j.Logger;

public final class ItemStack {
    private static final Logger LOGGER;
    public static final ItemStack EMPTY;
    public static final DecimalFormat ATTRIBUTE_MODIFIER_FORMAT;
    private int count;
    private int popTime;
    @Deprecated
    private final Item item;
    private CompoundTag tag;
    private boolean emptyCacheFlag;
    private ItemFrame frame;
    private BlockInWorld cachedBreakBlock;
    private boolean cachedBreakBlockResult;
    private BlockInWorld cachedPlaceBlock;
    private boolean cachedPlaceBlockResult;
    
    private static DecimalFormat getAttributeDecimalFormat() {
        final DecimalFormat decimalFormat1 = new DecimalFormat("#.##");
        decimalFormat1.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT));
        return decimalFormat1;
    }
    
    public ItemStack(final ItemLike bjv) {
        this(bjv, 1);
    }
    
    public ItemStack(final ItemLike bjv, final int integer) {
        this.item = ((bjv == null) ? null : bjv.asItem());
        this.count = integer;
        if (this.item != null && this.item.canBeDepleted()) {
            this.setDamageValue(this.getDamageValue());
        }
        this.updateEmptyCacheFlag();
    }
    
    private void updateEmptyCacheFlag() {
        this.emptyCacheFlag = false;
        this.emptyCacheFlag = this.isEmpty();
    }
    
    private ItemStack(final CompoundTag jt) {
        this.item = Registry.ITEM.get(new ResourceLocation(jt.getString("id")));
        this.count = jt.getByte("Count");
        if (jt.contains("tag", 10)) {
            this.tag = jt.getCompound("tag");
            this.getItem().verifyTagAfterLoad(jt);
        }
        if (this.getItem().canBeDepleted()) {
            this.setDamageValue(this.getDamageValue());
        }
        this.updateEmptyCacheFlag();
    }
    
    public static ItemStack of(final CompoundTag jt) {
        try {
            return new ItemStack(jt);
        }
        catch (RuntimeException runtimeException2) {
            ItemStack.LOGGER.debug("Tried to load invalid item: {}", jt, runtimeException2);
            return ItemStack.EMPTY;
        }
    }
    
    public boolean isEmpty() {
        return this == ItemStack.EMPTY || (this.getItem() == null || this.getItem() == Items.AIR) || this.count <= 0;
    }
    
    public ItemStack split(final int integer) {
        final int integer2 = Math.min(integer, this.count);
        final ItemStack ben4 = this.copy();
        ben4.setCount(integer2);
        this.shrink(integer2);
        return ben4;
    }
    
    public Item getItem() {
        return this.emptyCacheFlag ? Items.AIR : this.item;
    }
    
    public InteractionResult useOn(final UseOnContext bfz) {
        final Player ayj3 = bfz.getPlayer();
        final BlockPos fk4 = bfz.getClickedPos();
        final BlockInWorld byn5 = new BlockInWorld(bfz.getLevel(), fk4, false);
        if (ayj3 != null && !ayj3.abilities.mayBuild && !this.hasAdventureModePlaceTagForBlock(bfz.getLevel().getTagManager(), byn5)) {
            return InteractionResult.PASS;
        }
        final Item bei6 = this.getItem();
        final InteractionResult ajl7 = bei6.useOn(bfz);
        if (ayj3 != null && ajl7 == InteractionResult.SUCCESS) {
            ayj3.awardStat(Stats.ITEM_USED.get(bei6));
        }
        return ajl7;
    }
    
    public float getDestroySpeed(final BlockState byj) {
        return this.getItem().getDestroySpeed(this, byj);
    }
    
    public InteractionResultHolder<ItemStack> use(final Level bjw, final Player ayj, final InteractionHand ajk) {
        return this.getItem().use(bjw, ayj, ajk);
    }
    
    public ItemStack finishUsingItem(final Level bjw, final LivingEntity akz) {
        return this.getItem().finishUsingItem(this, bjw, akz);
    }
    
    public CompoundTag save(final CompoundTag jt) {
        final ResourceLocation sm3 = Registry.ITEM.getKey(this.getItem());
        jt.putString("id", (sm3 == null) ? "minecraft:air" : sm3.toString());
        jt.putByte("Count", (byte)this.count);
        if (this.tag != null) {
            jt.put("tag", this.tag.copy());
        }
        return jt;
    }
    
    public int getMaxStackSize() {
        return this.getItem().getMaxStackSize();
    }
    
    public boolean isStackable() {
        return this.getMaxStackSize() > 1 && (!this.isDamageableItem() || !this.isDamaged());
    }
    
    public boolean isDamageableItem() {
        if (this.emptyCacheFlag || this.getItem().getMaxDamage() <= 0) {
            return false;
        }
        final CompoundTag jt2 = this.getTag();
        return jt2 == null || !jt2.getBoolean("Unbreakable");
    }
    
    public boolean isDamaged() {
        return this.isDamageableItem() && this.getDamageValue() > 0;
    }
    
    public int getDamageValue() {
        return (this.tag == null) ? 0 : this.tag.getInt("Damage");
    }
    
    public void setDamageValue(final int integer) {
        this.getOrCreateTag().putInt("Damage", Math.max(0, integer));
    }
    
    public int getMaxDamage() {
        return this.getItem().getMaxDamage();
    }
    
    public boolean hurt(int integer, final Random random, @Nullable final ServerPlayer xe) {
        if (!this.isDamageableItem()) {
            return false;
        }
        if (integer > 0) {
            final int integer2 = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this);
            int integer3 = 0;
            for (int integer4 = 0; integer2 > 0 && integer4 < integer; ++integer4) {
                if (DigDurabilityEnchantment.shouldIgnoreDurabilityDrop(this, integer2, random)) {
                    ++integer3;
                }
            }
            integer -= integer3;
            if (integer <= 0) {
                return false;
            }
        }
        if (xe != null && integer != 0) {
            CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(xe, this, this.getDamageValue() + integer);
        }
        final int integer2 = this.getDamageValue() + integer;
        this.setDamageValue(integer2);
        return integer2 >= this.getMaxDamage();
    }
    
    public <T extends LivingEntity> void hurtAndBreak(final int integer, final T akz, final Consumer<T> consumer) {
        if (akz.level.isClientSide || (akz instanceof Player && ((Player)akz).abilities.instabuild)) {
            return;
        }
        if (!this.isDamageableItem()) {
            return;
        }
        if (this.hurt(integer, akz.getRandom(), (akz instanceof ServerPlayer) ? akz : null)) {
            consumer.accept(akz);
            final Item bei5 = this.getItem();
            this.shrink(1);
            if (akz instanceof Player) {
                ((Player)akz).awardStat(Stats.ITEM_BROKEN.get(bei5));
            }
            this.setDamageValue(0);
        }
    }
    
    public void hurtEnemy(final LivingEntity akz, final Player ayj) {
        final Item bei4 = this.getItem();
        if (bei4.hurtEnemy(this, akz, ayj)) {
            ayj.awardStat(Stats.ITEM_USED.get(bei4));
        }
    }
    
    public void mineBlock(final Level bjw, final BlockState byj, final BlockPos fk, final Player ayj) {
        final Item bei6 = this.getItem();
        if (bei6.mineBlock(this, bjw, byj, fk, ayj)) {
            ayj.awardStat(Stats.ITEM_USED.get(bei6));
        }
    }
    
    public boolean canDestroySpecial(final BlockState byj) {
        return this.getItem().canDestroySpecial(byj);
    }
    
    public boolean interactEnemy(final Player ayj, final LivingEntity akz, final InteractionHand ajk) {
        return this.getItem().interactEnemy(this, ayj, akz, ajk);
    }
    
    public ItemStack copy() {
        if (this.isEmpty()) {
            return ItemStack.EMPTY;
        }
        final ItemStack ben2 = new ItemStack(this.getItem(), this.count);
        ben2.setPopTime(this.getPopTime());
        if (this.tag != null) {
            ben2.tag = this.tag.copy();
        }
        return ben2;
    }
    
    public static boolean tagMatches(final ItemStack ben1, final ItemStack ben2) {
        return (ben1.isEmpty() && ben2.isEmpty()) || (!ben1.isEmpty() && !ben2.isEmpty() && (ben1.tag != null || ben2.tag == null) && (ben1.tag == null || ben1.tag.equals(ben2.tag)));
    }
    
    public static boolean matches(final ItemStack ben1, final ItemStack ben2) {
        return (ben1.isEmpty() && ben2.isEmpty()) || (!ben1.isEmpty() && !ben2.isEmpty() && ben1.matches(ben2));
    }
    
    private boolean matches(final ItemStack ben) {
        return this.count == ben.count && this.getItem() == ben.getItem() && (this.tag != null || ben.tag == null) && (this.tag == null || this.tag.equals(ben.tag));
    }
    
    public static boolean isSame(final ItemStack ben1, final ItemStack ben2) {
        return ben1 == ben2 || (!ben1.isEmpty() && !ben2.isEmpty() && ben1.sameItem(ben2));
    }
    
    public static boolean isSameIgnoreDurability(final ItemStack ben1, final ItemStack ben2) {
        return ben1 == ben2 || (!ben1.isEmpty() && !ben2.isEmpty() && ben1.sameItemStackIgnoreDurability(ben2));
    }
    
    public boolean sameItem(final ItemStack ben) {
        return !ben.isEmpty() && this.getItem() == ben.getItem();
    }
    
    public boolean sameItemStackIgnoreDurability(final ItemStack ben) {
        if (this.isDamageableItem()) {
            return !ben.isEmpty() && this.getItem() == ben.getItem();
        }
        return this.sameItem(ben);
    }
    
    public String getDescriptionId() {
        return this.getItem().getDescriptionId(this);
    }
    
    @Override
    public String toString() {
        return this.count + " " + this.getItem();
    }
    
    public void inventoryTick(final Level bjw, final Entity akq, final int integer, final boolean boolean4) {
        if (this.popTime > 0) {
            --this.popTime;
        }
        if (this.getItem() != null) {
            this.getItem().inventoryTick(this, bjw, akq, integer, boolean4);
        }
    }
    
    public void onCraftedBy(final Level bjw, final Player ayj, final int integer) {
        ayj.awardStat(Stats.ITEM_CRAFTED.get(this.getItem()), integer);
        this.getItem().onCraftedBy(this, bjw, ayj);
    }
    
    public int getUseDuration() {
        return this.getItem().getUseDuration(this);
    }
    
    public UseAnim getUseAnimation() {
        return this.getItem().getUseAnimation(this);
    }
    
    public void releaseUsing(final Level bjw, final LivingEntity akz, final int integer) {
        this.getItem().releaseUsing(this, bjw, akz, integer);
    }
    
    public boolean useOnRelease() {
        return this.getItem().useOnRelease(this);
    }
    
    public boolean hasTag() {
        return !this.emptyCacheFlag && this.tag != null && !this.tag.isEmpty();
    }
    
    @Nullable
    public CompoundTag getTag() {
        return this.tag;
    }
    
    public CompoundTag getOrCreateTag() {
        if (this.tag == null) {
            this.setTag(new CompoundTag());
        }
        return this.tag;
    }
    
    public CompoundTag getOrCreateTagElement(final String string) {
        if (this.tag == null || !this.tag.contains(string, 10)) {
            final CompoundTag jt3 = new CompoundTag();
            this.addTagElement(string, jt3);
            return jt3;
        }
        return this.tag.getCompound(string);
    }
    
    @Nullable
    public CompoundTag getTagElement(final String string) {
        if (this.tag == null || !this.tag.contains(string, 10)) {
            return null;
        }
        return this.tag.getCompound(string);
    }
    
    public void removeTagKey(final String string) {
        if (this.tag != null && this.tag.contains(string)) {
            this.tag.remove(string);
            if (this.tag.isEmpty()) {
                this.tag = null;
            }
        }
    }
    
    public ListTag getEnchantmentTags() {
        if (this.tag != null) {
            return this.tag.getList("Enchantments", 10);
        }
        return new ListTag();
    }
    
    public void setTag(@Nullable final CompoundTag jt) {
        this.tag = jt;
        if (this.getItem().canBeDepleted()) {
            this.setDamageValue(this.getDamageValue());
        }
    }
    
    public Component getHoverName() {
        final CompoundTag jt2 = this.getTagElement("display");
        if (jt2 != null && jt2.contains("Name", 8)) {
            try {
                final Component lf3 = Component.Serializer.fromJson(jt2.getString("Name"));
                if (lf3 != null) {
                    return lf3;
                }
                jt2.remove("Name");
            }
            catch (JsonParseException jsonParseException3) {
                jt2.remove("Name");
            }
        }
        return this.getItem().getName(this);
    }
    
    public ItemStack setHoverName(@Nullable final Component lf) {
        final CompoundTag jt3 = this.getOrCreateTagElement("display");
        if (lf != null) {
            jt3.putString("Name", Component.Serializer.toJson(lf));
        }
        else {
            jt3.remove("Name");
        }
        return this;
    }
    
    public void resetHoverName() {
        final CompoundTag jt2 = this.getTagElement("display");
        if (jt2 != null) {
            jt2.remove("Name");
            if (jt2.isEmpty()) {
                this.removeTagKey("display");
            }
        }
        if (this.tag != null && this.tag.isEmpty()) {
            this.tag = null;
        }
    }
    
    public boolean hasCustomHoverName() {
        final CompoundTag jt2 = this.getTagElement("display");
        return jt2 != null && jt2.contains("Name", 8);
    }
    
    public List<Component> getTooltipLines(@Nullable final Player ayj, final TooltipFlag bfw) {
        final List<Component> list4 = Lists.newArrayList();
        final Component lf5 = new TextComponent("").append(this.getHoverName()).withStyle(this.getRarity().color);
        if (this.hasCustomHoverName()) {
            lf5.withStyle(ChatFormatting.ITALIC);
        }
        list4.add(lf5);
        if (!bfw.isAdvanced() && !this.hasCustomHoverName() && this.getItem() == Items.FILLED_MAP) {
            list4.add(new TextComponent("#" + MapItem.getMapId(this)).withStyle(ChatFormatting.GRAY));
        }
        int integer6 = 0;
        if (this.hasTag() && this.tag.contains("HideFlags", 99)) {
            integer6 = this.tag.getInt("HideFlags");
        }
        if ((integer6 & 0x20) == 0x0) {
            this.getItem().appendHoverText(this, (ayj == null) ? null : ayj.level, list4, bfw);
        }
        if (this.hasTag()) {
            if ((integer6 & 0x1) == 0x0) {
                appendEnchantmentNames(list4, this.getEnchantmentTags());
            }
            if (this.tag.contains("display", 10)) {
                final CompoundTag jt7 = this.tag.getCompound("display");
                if (jt7.contains("color", 3)) {
                    if (bfw.isAdvanced()) {
                        list4.add(new TranslatableComponent("item.color", new Object[] { String.format("#%06X", jt7.getInt("color")) }).withStyle(ChatFormatting.GRAY));
                    }
                    else {
                        list4.add(new TranslatableComponent("item.dyed", new Object[0]).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC));
                    }
                }
                if (jt7.getTagType("Lore") == 9) {
                    final ListTag jz8 = jt7.getList("Lore", 8);
                    for (int integer7 = 0; integer7 < jz8.size(); ++integer7) {
                        final String string10 = jz8.getString(integer7);
                        try {
                            final Component lf6 = Component.Serializer.fromJson(string10);
                            if (lf6 != null) {
                                list4.add(ComponentUtils.mergeStyles(lf6, new Style().setColor(ChatFormatting.DARK_PURPLE).setItalic(true)));
                            }
                        }
                        catch (JsonParseException jsonParseException11) {
                            jt7.remove("Lore");
                        }
                    }
                }
            }
        }
        for (final EquipmentSlot akv10 : EquipmentSlot.values()) {
            final Multimap<String, AttributeModifier> multimap11 = this.getAttributeModifiers(akv10);
            if (!multimap11.isEmpty() && (integer6 & 0x2) == 0x0) {
                list4.add(new TextComponent(""));
                list4.add(new TranslatableComponent("item.modifiers." + akv10.getName(), new Object[0]).withStyle(ChatFormatting.GRAY));
                for (final Map.Entry<String, AttributeModifier> entry13 : multimap11.entries()) {
                    final AttributeModifier als14 = entry13.getValue();
                    double double15 = als14.getAmount();
                    boolean boolean19 = false;
                    if (ayj != null) {
                        if (als14.getId() == Item.BASE_ATTACK_DAMAGE_UUID) {
                            double15 += ayj.getAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getBaseValue();
                            double15 += EnchantmentHelper.getDamageBonus(this, MobType.UNDEFINED);
                            boolean19 = true;
                        }
                        else if (als14.getId() == Item.BASE_ATTACK_SPEED_UUID) {
                            double15 += ayj.getAttribute(SharedMonsterAttributes.ATTACK_SPEED).getBaseValue();
                            boolean19 = true;
                        }
                    }
                    double double16;
                    if (als14.getOperation() == AttributeModifier.Operation.MULTIPLY_BASE || als14.getOperation() == AttributeModifier.Operation.MULTIPLY_TOTAL) {
                        double16 = double15 * 100.0;
                    }
                    else {
                        double16 = double15;
                    }
                    if (boolean19) {
                        list4.add(new TextComponent(" ").append(new TranslatableComponent("attribute.modifier.equals." + als14.getOperation().toValue(), new Object[] { ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(double16), new TranslatableComponent("attribute.name." + entry13.getKey(), new Object[0]) })).withStyle(ChatFormatting.DARK_GREEN));
                    }
                    else if (double15 > 0.0) {
                        list4.add(new TranslatableComponent("attribute.modifier.plus." + als14.getOperation().toValue(), new Object[] { ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(double16), new TranslatableComponent("attribute.name." + entry13.getKey(), new Object[0]) }).withStyle(ChatFormatting.BLUE));
                    }
                    else {
                        if (double15 >= 0.0) {
                            continue;
                        }
                        double16 *= -1.0;
                        list4.add(new TranslatableComponent("attribute.modifier.take." + als14.getOperation().toValue(), new Object[] { ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(double16), new TranslatableComponent("attribute.name." + entry13.getKey(), new Object[0]) }).withStyle(ChatFormatting.RED));
                    }
                }
            }
        }
        if (this.hasTag() && this.getTag().getBoolean("Unbreakable") && (integer6 & 0x4) == 0x0) {
            list4.add(new TranslatableComponent("item.unbreakable", new Object[0]).withStyle(ChatFormatting.BLUE));
        }
        if (this.hasTag() && this.tag.contains("CanDestroy", 9) && (integer6 & 0x8) == 0x0) {
            final ListTag jz9 = this.tag.getList("CanDestroy", 8);
            if (!jz9.isEmpty()) {
                list4.add(new TextComponent(""));
                list4.add(new TranslatableComponent("item.canBreak", new Object[0]).withStyle(ChatFormatting.GRAY));
                for (int integer8 = 0; integer8 < jz9.size(); ++integer8) {
                    list4.addAll(expandBlockState(jz9.getString(integer8)));
                }
            }
        }
        if (this.hasTag() && this.tag.contains("CanPlaceOn", 9) && (integer6 & 0x10) == 0x0) {
            final ListTag jz9 = this.tag.getList("CanPlaceOn", 8);
            if (!jz9.isEmpty()) {
                list4.add(new TextComponent(""));
                list4.add(new TranslatableComponent("item.canPlace", new Object[0]).withStyle(ChatFormatting.GRAY));
                for (int integer8 = 0; integer8 < jz9.size(); ++integer8) {
                    list4.addAll(expandBlockState(jz9.getString(integer8)));
                }
            }
        }
        if (bfw.isAdvanced()) {
            if (this.isDamaged()) {
                list4.add(new TranslatableComponent("item.durability", new Object[] { this.getMaxDamage() - this.getDamageValue(), this.getMaxDamage() }));
            }
            list4.add(new TextComponent(Registry.ITEM.getKey(this.getItem()).toString()).withStyle(ChatFormatting.DARK_GRAY));
            if (this.hasTag()) {
                list4.add(new TranslatableComponent("item.nbt_tags", new Object[] { this.getTag().getAllKeys().size() }).withStyle(ChatFormatting.DARK_GRAY));
            }
        }
        return list4;
    }
    
    public static void appendEnchantmentNames(final List<Component> list, final ListTag jz) {
        for (int integer3 = 0; integer3 < jz.size(); ++integer3) {
            final CompoundTag jt4 = jz.getCompound(integer3);
            Registry.ENCHANTMENT.getOptional(ResourceLocation.tryParse(jt4.getString("id"))).ifPresent(bhx -> list.add(bhx.getFullname(jt4.getInt("lvl"))));
        }
    }
    
    private static Collection<Component> expandBlockState(final String string) {
        try {
            final BlockStateParser dv2 = new BlockStateParser(new StringReader(string), true).parse(true);
            final BlockState byj3 = dv2.getState();
            final ResourceLocation sm4 = dv2.getTag();
            final boolean boolean5 = byj3 != null;
            final boolean boolean6 = sm4 != null;
            if (boolean5 || boolean6) {
                if (boolean5) {
                    return Lists.newArrayList(byj3.getBlock().getName().withStyle(ChatFormatting.DARK_GRAY));
                }
                final net.minecraft.tags.Tag<Block> aaz7 = BlockTags.getAllTags().getTag(sm4);
                if (aaz7 != null) {
                    final Collection<Block> collection8 = aaz7.getValues();
                    if (!collection8.isEmpty()) {
                        return collection8.stream().map(Block::getName).map(lf -> lf.withStyle(ChatFormatting.DARK_GRAY)).collect(Collectors.toList());
                    }
                }
            }
        }
        catch (CommandSyntaxException ex) {}
        return Lists.newArrayList(new TextComponent("missingno").withStyle(ChatFormatting.DARK_GRAY));
    }
    
    public boolean hasFoil() {
        return this.getItem().isFoil(this);
    }
    
    public Rarity getRarity() {
        return this.getItem().getRarity(this);
    }
    
    public boolean isEnchantable() {
        return this.getItem().isEnchantable(this) && !this.isEnchanted();
    }
    
    public void enchant(final Enchantment bhx, final int integer) {
        this.getOrCreateTag();
        if (!this.tag.contains("Enchantments", 9)) {
            this.tag.put("Enchantments", new ListTag());
        }
        final ListTag jz4 = this.tag.getList("Enchantments", 10);
        final CompoundTag jt5 = new CompoundTag();
        jt5.putString("id", String.valueOf(Registry.ENCHANTMENT.getKey(bhx)));
        jt5.putShort("lvl", (byte)integer);
        ((AbstractList<CompoundTag>)jz4).add(jt5);
    }
    
    public boolean isEnchanted() {
        return this.tag != null && this.tag.contains("Enchantments", 9) && !this.tag.getList("Enchantments", 10).isEmpty();
    }
    
    public void addTagElement(final String string, final Tag kj) {
        this.getOrCreateTag().put(string, kj);
    }
    
    public boolean isFramed() {
        return this.frame != null;
    }
    
    public void setFramed(@Nullable final ItemFrame avr) {
        this.frame = avr;
    }
    
    @Nullable
    public ItemFrame getFrame() {
        return this.emptyCacheFlag ? null : this.frame;
    }
    
    public int getBaseRepairCost() {
        if (this.hasTag() && this.tag.contains("RepairCost", 3)) {
            return this.tag.getInt("RepairCost");
        }
        return 0;
    }
    
    public void setRepairCost(final int integer) {
        this.getOrCreateTag().putInt("RepairCost", integer);
    }
    
    public Multimap<String, AttributeModifier> getAttributeModifiers(final EquipmentSlot akv) {
        Multimap<String, AttributeModifier> multimap3;
        if (this.hasTag() && this.tag.contains("AttributeModifiers", 9)) {
            multimap3 = HashMultimap.create();
            final ListTag jz4 = this.tag.getList("AttributeModifiers", 10);
            for (int integer5 = 0; integer5 < jz4.size(); ++integer5) {
                final CompoundTag jt6 = jz4.getCompound(integer5);
                final AttributeModifier als2 = SharedMonsterAttributes.loadAttributeModifier(jt6);
                if (als2 != null) {
                    if (!jt6.contains("Slot", 8) || jt6.getString("Slot").equals(akv.getName())) {
                        if (als2.getId().getLeastSignificantBits() != 0L && als2.getId().getMostSignificantBits() != 0L) {
                            multimap3.put(jt6.getString("AttributeName"), als2);
                        }
                    }
                }
            }
        }
        else {
            multimap3 = this.getItem().getDefaultAttributeModifiers(akv);
        }
        multimap3.values().forEach(als -> als.setSerialize(false));
        return multimap3;
    }
    
    public void addAttributeModifier(final String string, final AttributeModifier als, @Nullable final EquipmentSlot akv) {
        this.getOrCreateTag();
        if (!this.tag.contains("AttributeModifiers", 9)) {
            this.tag.put("AttributeModifiers", new ListTag());
        }
        final ListTag jz5 = this.tag.getList("AttributeModifiers", 10);
        final CompoundTag jt6 = SharedMonsterAttributes.saveAttributeModifier(als);
        jt6.putString("AttributeName", string);
        if (akv != null) {
            jt6.putString("Slot", akv.getName());
        }
        ((AbstractList<CompoundTag>)jz5).add(jt6);
    }
    
    public Component getDisplayName() {
        final Component lf2 = new TextComponent("").append(this.getHoverName());
        if (this.hasCustomHoverName()) {
            lf2.withStyle(ChatFormatting.ITALIC);
        }
        final Component lf3 = ComponentUtils.wrapInSquareBrackets(lf2);
        if (!this.emptyCacheFlag) {
            final CompoundTag jt4 = this.save(new CompoundTag());
            final HoverEvent hoverEvent;
            final CompoundTag compoundTag;
            lf3.withStyle(this.getRarity().color).withStyle(ln -> {
                new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponent(compoundTag.toString()));
                ln.setHoverEvent(hoverEvent);
                return;
            });
        }
        return lf3;
    }
    
    private static boolean areSameBlocks(final BlockInWorld byn1, @Nullable final BlockInWorld byn2) {
        return byn2 != null && byn1.getState() == byn2.getState() && ((byn1.getEntity() == null && byn2.getEntity() == null) || (byn1.getEntity() != null && byn2.getEntity() != null && Objects.equals(byn1.getEntity().save(new CompoundTag()), byn2.getEntity().save(new CompoundTag()))));
    }
    
    public boolean hasAdventureModeBreakTagForBlock(final TagManager abb, final BlockInWorld byn) {
        if (areSameBlocks(byn, this.cachedBreakBlock)) {
            return this.cachedBreakBlockResult;
        }
        this.cachedBreakBlock = byn;
        if (this.hasTag() && this.tag.contains("CanDestroy", 9)) {
            final ListTag jz4 = this.tag.getList("CanDestroy", 8);
            for (int integer5 = 0; integer5 < jz4.size(); ++integer5) {
                final String string6 = jz4.getString(integer5);
                try {
                    final Predicate<BlockInWorld> predicate7 = BlockPredicateArgument.blockPredicate().parse(new StringReader(string6)).create(abb);
                    if (predicate7.test(byn)) {
                        return this.cachedBreakBlockResult = true;
                    }
                }
                catch (CommandSyntaxException ex) {}
            }
        }
        return this.cachedBreakBlockResult = false;
    }
    
    public boolean hasAdventureModePlaceTagForBlock(final TagManager abb, final BlockInWorld byn) {
        if (areSameBlocks(byn, this.cachedPlaceBlock)) {
            return this.cachedPlaceBlockResult;
        }
        this.cachedPlaceBlock = byn;
        if (this.hasTag() && this.tag.contains("CanPlaceOn", 9)) {
            final ListTag jz4 = this.tag.getList("CanPlaceOn", 8);
            for (int integer5 = 0; integer5 < jz4.size(); ++integer5) {
                final String string6 = jz4.getString(integer5);
                try {
                    final Predicate<BlockInWorld> predicate7 = BlockPredicateArgument.blockPredicate().parse(new StringReader(string6)).create(abb);
                    if (predicate7.test(byn)) {
                        return this.cachedPlaceBlockResult = true;
                    }
                }
                catch (CommandSyntaxException ex) {}
            }
        }
        return this.cachedPlaceBlockResult = false;
    }
    
    public int getPopTime() {
        return this.popTime;
    }
    
    public void setPopTime(final int integer) {
        this.popTime = integer;
    }
    
    public int getCount() {
        return this.emptyCacheFlag ? 0 : this.count;
    }
    
    public void setCount(final int integer) {
        this.count = integer;
        this.updateEmptyCacheFlag();
    }
    
    public void grow(final int integer) {
        this.setCount(this.count + integer);
    }
    
    public void shrink(final int integer) {
        this.grow(-integer);
    }
    
    public void onUseTick(final Level bjw, final LivingEntity akz, final int integer) {
        this.getItem().onUseTick(bjw, akz, this, integer);
    }
    
    public boolean isEdible() {
        return this.getItem().isEdible();
    }
    
    public SoundEvent getDrinkingSound() {
        return this.getItem().getDrinkingSound();
    }
    
    public SoundEvent getEatingSound() {
        return this.getItem().getEatingSound();
    }
    
    static {
        LOGGER = LogManager.getLogger();
        EMPTY = new ItemStack((ItemLike)null);
        ATTRIBUTE_MODIFIER_FORMAT = getAttributeDecimalFormat();
    }
}
