package net.minecraft.world.item;

import net.minecraft.core.RegistryMaterials;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.PatchedDataComponentMap;

class Item {
    public static Iterable<?> getRegistry() {
        // Must initialize the server to initialize the item-storing registries
        com.bergerkiller.bukkit.common.internal.CommonBootstrap.initServer();

#if version >= 1.14
        #require net.minecraft.core.registries.BuiltInRegistries public static final net.minecraft.core.RegistryBlocks<net.minecraft.world.item.Item> REGISTRY:ITEM;
#elseif version >= 1.13.1
        #require net.minecraft.core.IRegistry public static final net.minecraft.core.IRegistry<net.minecraft.world.item.Item> REGISTRY:ITEM;
#else
        #require net.minecraft.world.item.Item public static final net.minecraft.core.RegistryMaterials<MinecraftKey, net.minecraft.world.item.Item> REGISTRY;
#endif
        return #REGISTRY;
    }

#if version >= 1.20.5
    public int getMaxStackSize:getDefaultMaxStackSize();

    public void setMaxStackSize(int maxStackSize) {
        // Read current item components
        #require Item private final DataComponentMap components;
        DataComponentMap components = instance#components;

        // Make writable and modify the max stack size
        PatchedDataComponentMap writable = (components instanceof PatchedDataComponentMap)
                ? (PatchedDataComponentMap) components : new PatchedDataComponentMap(components);
        if (maxStackSize == 1) {
            writable.remove(DataComponents.MAX_STACK_SIZE);
        } else {
            writable.set(DataComponents.MAX_STACK_SIZE, (Object) Integer.valueOf(maxStackSize));
        }

        // Make read-only again and set it in the item
        // TODO: Is there a way to make a read-only version?
        components = writable.isEmpty() ? DataComponentMap.EMPTY : writable;
        instance#components = components;
    }
#else
    public int getMaxStackSize();

    public void setMaxStackSize(int maxStackSize) {
        #require net.minecraft.world.item.Item private final int maxStackSize;
        instance#maxStackSize = maxStackSize;
    }
#endif

#if version >= 1.20.5
    public int getMaxDurability() {
        Integer maxDamage = (Integer) instance.components().get(DataComponents.MAX_DAMAGE);
        return (maxDamage != null) ? maxDamage.intValue() : 0;
    }
    public boolean usesDurability() {
        Integer maxDamage = (Integer) instance.components().get(DataComponents.MAX_DAMAGE);
        return maxDamage != null && maxDamage.intValue() != 0;
    }
#elseif version >= 1.18
    public int getMaxDurability:getMaxDamage();
    public boolean usesDurability:canBeDepleted();
#else
    public int getMaxDurability();
    public boolean usesDurability();
#endif

#if version >= 1.21.2
    // Name can no longer be changed per item stack
    public String getInternalName((org.bukkit.inventory.ItemStack) ItemStack itemstack) {
        return instance.getDescriptionId();
    }
#else

  #select version >=
  #case 1.18:   public String getInternalName:getDescriptionId((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.17:   public String getInternalName:j((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.14:   public String getInternalName:f((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.13:   public String getInternalName:h((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.11:   public String getInternalName:a((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.9:    public String getInternalName:f_((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.8.6:  public String getInternalName:e_((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case 1.8.5:  public String getInternalName:f_((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #case else:   public String getInternalName:e_((org.bukkit.inventory.ItemStack) ItemStack itemstack);
  #endselect
#endif

    <code>
    public static ItemHandle fromMaterial(org.bukkit.Material material) {
        return createHandle(com.bergerkiller.generated.org.bukkit.craftbukkit.util.CraftMagicNumbersHandle.getItemFromMaterial(material));
    }
    </code>
}
