content: package org.allaymc.api.item.type;
  
  import org.allaymc.api.block.type.BlockType;
  import org.allaymc.api.item.ItemStack;
  import org.allaymc.api.item.ItemStackInitInfo;
  import org.allaymc.api.item.data.ItemData;
  import org.allaymc.api.item.data.ItemTag;
  import org.allaymc.api.utils.identifier.Identified;
  import org.jetbrains.annotations.Unmodifiable;
  
  import java.util.Set;
  
  /**
   * Represents a type of item, providing methods to create instances of the item as well as to retrieve its properties.
   *
   * @param <T> the specific type of {@link ItemStack} this ItemType represents
   * @author daoge_cmd
   */
  public interface ItemType<T extends ItemStack> extends Identified {
      /**
       * Create an {@link ItemStack} with the given {@link ItemStackInitInfo}.
       *
       * @param info The {@link ItemStackInitInfo} to create the {@link ItemStack} with
       * @return The created {@link ItemStack}
       */
      T createItemStack(ItemStackInitInfo info);
  
      /**
       * Create an {@link ItemStack} with a count of 1 and a meta of 0.
       *
       * @return The created {@link ItemStack}
       */
      default T createItemStack() {
          return createItemStack(1);
      }
  
      /**
       * Create an {@link ItemStack} with the given count and a meta of 0.
       *
       * @param count The count of the {@link ItemStack}
       * @return The created {@link ItemStack}
       */
      default T createItemStack(int count) {
          return createItemStack(count, 0);
      }
  
      /**
       * Create an {@link ItemStack} with the given count and meta.
       *
       * @param count The count of the {@link ItemStack}
       * @param meta  The meta of the {@link ItemStack}
       * @return The created {@link ItemStack}
       */
      default T createItemStack(int count, int meta) {
          return createItemStack(ItemStackInitInfo.builder().count(count).meta(meta).build());
      }
  
      /**
       * Get the runtime ID of the item.
       * <p>
       * The runtime id of an item is mutable and will change
       * between different versions of the game.
       *
       * @return The runtime ID of the item
       */
      int getRuntimeId();
  
      /**
       * Get the block type of the item.
       *
       * @return The block type of the item
       */
      BlockType<?> getBlockType();
  
      /**
       * Get the item tags of the item.
       *
       * @return The item tags of the item
       */
      @Unmodifiable
      Set<ItemTag> getItemTags();
  
      /**
       * Check if the item has the given item tag.
       *
       * @param itemTag The item tag to check
       * @return {@code true} if the item has the item tag, {@code false} otherwise.
       */
      default boolean hasItemTag(ItemTag itemTag) {
          return getItemTags().contains(itemTag);
      }
  
      /**
       * Get the data of this item.
       *
       * @return The data of this item
       */
      ItemData getItemData();
  }
  