// Path: src/main/java/org/cyclops/everlastingabilities/RegistryEntries.java
// public class RegistryEntries {
// 
//     @ObjectHolder("everlastingabilities:ability_bottle")
//     public static final Item ITEM_ABILITY_BOTTLE = null;
//     @ObjectHolder("everlastingabilities:ability_totem")
//     public static final Item ITEM_ABILITY_TOTEM = null;
// 
//     @ObjectHolder("everlastingabilities:ability_container")
//     public static final ContainerType<ContainerAbilityContainer> CONTAINER_ABILITYCONTAINER = null;
// 
//     @ObjectHolder("everlastingabilities:crafting_special_totem_recycle")
//     public static final SpecialRecipeSerializer<TotemRecycleRecipe> RECIPESERIALIZER_TOTEM_RECYCLE = null;
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/Ability.java
// public class Ability implements Comparable<Ability> {
// 
//     public static final Ability EMPTY = new Ability(new AbilityType("", "", () -> Rarity.COMMON, () -> 0, () -> 0, () -> true, () -> true, () -> true, () -> true), 0);
// 
//     private final IAbilityType abilityType;
//     private final int level;
// 
//     public Ability(@Nonnull IAbilityType abilityType, int level) {
//         this.abilityType = Objects.requireNonNull(abilityType);
//         this.level = level;
//     }
// 
//     public IAbilityType getAbilityType() {
//         return abilityType;
//     }
// 
//     public int getLevel() {
//         return level;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("[%s @ %s]", abilityType.getTranslationKey(), level);
//     }
// 
//     @Override
//     public int compareTo(Ability other) {
//         return this.toString().compareTo(other.toString());
//     }
// 
//     public ITextComponent getTextComponent() {
//         return new StringTextComponent("[")
//                 .append(new TranslationTextComponent(abilityType.getTranslationKey()))
//                 .appendString(" @ " + level + "]");
//     }
// 
//     public boolean isEmpty() {
//         return getLevel() <= 0;
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/AbilityTypes.java
// @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
// public class AbilityTypes {
// 
//     public static IForgeRegistry<IAbilityType> REGISTRY;
// 
//     @SubscribeEvent
//     public static void onRegistriesCreate(RegistryEvent.NewRegistry event) {
//         REGISTRY = new RegistryBuilder<IAbilityType>()
//                 .setName(new ResourceLocation("everlastingabilities", "abilities"))
//                 .setType(IAbilityType.class)
//                 .create();
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/IAbilityType.java
// public interface IAbilityType extends IForgeRegistryEntry<IAbilityType> {
// 
//     public String getTranslationKey();
//     public String getUnlocalizedDescription();
//     public Rarity getRarity();
//     public int getMaxLevel();
//     public default int getMaxLevelInfinitySafe() {
//         return getMaxLevel() < 0 ? Integer.MAX_VALUE : getMaxLevel();
//     }
//     public int getBaseXpPerLevel();
//     public boolean isObtainableOnPlayerSpawn();
//     public boolean isObtainableOnMobSpawn();
//     public boolean isObtainableOnCraft();
//     public boolean isObtainableOnLoot();
// 
//     public void onTick(PlayerEntity player, int level);
//     public void onChangedLevel(PlayerEntity player, int oldLevel, int newLevel);
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/capability/MutableAbilityStoreConfig.java
// public class MutableAbilityStoreConfig extends CapabilityConfig {
// 
//     /**
//      * The unique instance.
//      */
//     public static MutableAbilityStoreConfig _instance;
// 
//     @CapabilityInject(IMutableAbilityStore.class)
//     public static Capability<IMutableAbilityStore> CAPABILITY = null;
// 
//     /**
//      * Make a new instance.
//      */
//     public MutableAbilityStoreConfig() {
//         super(EverlastingAbilities._instance,
//                 "mutableAbilityStore",
//                 IMutableAbilityStore.class,
//                 new AbilityStoreStorage(),
//                 DefaultMutableAbilityStore::new);
//     }
// }


import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Rarity;
import net.minecraft.util.NonNullList;
import org.cyclops.everlastingabilities.RegistryEntries;
import org.cyclops.everlastingabilities.api.Ability;
import org.cyclops.everlastingabilities.api.AbilityTypes;
import org.cyclops.everlastingabilities.api.IAbilityType;
import org.cyclops.everlastingabilities.capability.MutableAbilityStoreConfig;
package org.cyclops.everlastingabilities.item;


/**
 * A totem with abilities.
 * @author rubensworks
 */
public class ItemAbilityTotem extends ItemGuiAbilityContainer {

    public ItemAbilityTotem(Properties properties) {
        super(properties);
    }

    @Override
    public boolean canMoveFromPlayer() {
        return false;
    }

    @Override
    public Rarity getRarity(ItemStack itemStack) {
        return itemStack.getCapability(MutableAbilityStoreConfig.CAPABILITY, null)
                .map(abilityStore -> {
                    int maxRarity = 0;
                    for (Ability ability : abilityStore.getAbilities()) {
                        maxRarity = Math.max(maxRarity, ability.getAbilityType().getRarity().ordinal());
                    }
                    return Rarity.values()[maxRarity];
                })
                .orElse(super.getRarity(itemStack));
    }

    public static ItemStack getTotem(Ability ability) {
        ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_ABILITY_TOTEM);
        itemStack.getCapability(MutableAbilityStoreConfig.CAPABILITY, null)
                .ifPresent(mutableAbilityStore -> mutableAbilityStore.addAbility(ability, true));
        return itemStack;
    }

    @Override
    public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items) {
        if (this.isInGroup(group)) {
// Path: src/main/java/org/cyclops/everlastingabilities/RegistryEntries.java
// public class RegistryEntries {
// 
//     @ObjectHolder("everlastingabilities:ability_bottle")
//     public static final Item ITEM_ABILITY_BOTTLE = null;
//     @ObjectHolder("everlastingabilities:ability_totem")
//     public static final Item ITEM_ABILITY_TOTEM = null;
// 
//     @ObjectHolder("everlastingabilities:ability_container")
//     public static final ContainerType<ContainerAbilityContainer> CONTAINER_ABILITYCONTAINER = null;
// 
//     @ObjectHolder("everlastingabilities:crafting_special_totem_recycle")
//     public static final SpecialRecipeSerializer<TotemRecycleRecipe> RECIPESERIALIZER_TOTEM_RECYCLE = null;
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/Ability.java
// public class Ability implements Comparable<Ability> {
// 
//     public static final Ability EMPTY = new Ability(new AbilityType("", "", () -> Rarity.COMMON, () -> 0, () -> 0, () -> true, () -> true, () -> true, () -> true), 0);
// 
//     private final IAbilityType abilityType;
//     private final int level;
// 
//     public Ability(@Nonnull IAbilityType abilityType, int level) {
//         this.abilityType = Objects.requireNonNull(abilityType);
//         this.level = level;
//     }
// 
//     public IAbilityType getAbilityType() {
//         return abilityType;
//     }
// 
//     public int getLevel() {
//         return level;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("[%s @ %s]", abilityType.getTranslationKey(), level);
//     }
// 
//     @Override
//     public int compareTo(Ability other) {
//         return this.toString().compareTo(other.toString());
//     }
// 
//     public ITextComponent getTextComponent() {
//         return new StringTextComponent("[")
//                 .append(new TranslationTextComponent(abilityType.getTranslationKey()))
//                 .appendString(" @ " + level + "]");
//     }
// 
//     public boolean isEmpty() {
//         return getLevel() <= 0;
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/AbilityTypes.java
// @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
// public class AbilityTypes {
// 
//     public static IForgeRegistry<IAbilityType> REGISTRY;
// 
//     @SubscribeEvent
//     public static void onRegistriesCreate(RegistryEvent.NewRegistry event) {
//         REGISTRY = new RegistryBuilder<IAbilityType>()
//                 .setName(new ResourceLocation("everlastingabilities", "abilities"))
//                 .setType(IAbilityType.class)
//                 .create();
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/IAbilityType.java
// public interface IAbilityType extends IForgeRegistryEntry<IAbilityType> {
// 
//     public String getTranslationKey();
//     public String getUnlocalizedDescription();
//     public Rarity getRarity();
//     public int getMaxLevel();
//     public default int getMaxLevelInfinitySafe() {
//         return getMaxLevel() < 0 ? Integer.MAX_VALUE : getMaxLevel();
//     }
//     public int getBaseXpPerLevel();
//     public boolean isObtainableOnPlayerSpawn();
//     public boolean isObtainableOnMobSpawn();
//     public boolean isObtainableOnCraft();
//     public boolean isObtainableOnLoot();
// 
//     public void onTick(PlayerEntity player, int level);
//     public void onChangedLevel(PlayerEntity player, int oldLevel, int newLevel);
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/capability/MutableAbilityStoreConfig.java
// public class MutableAbilityStoreConfig extends CapabilityConfig {
// 
//     /**
//      * The unique instance.
//      */
//     public static MutableAbilityStoreConfig _instance;
// 
//     @CapabilityInject(IMutableAbilityStore.class)
//     public static Capability<IMutableAbilityStore> CAPABILITY = null;
// 
//     /**
//      * Make a new instance.
//      */
//     public MutableAbilityStoreConfig() {
//         super(EverlastingAbilities._instance,
//                 "mutableAbilityStore",
//                 IMutableAbilityStore.class,
//                 new AbilityStoreStorage(),
//                 DefaultMutableAbilityStore::new);
//     }
// }


// Path: src/main/java/org/cyclops/everlastingabilities/item/ItemAbilityTotem.java
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Rarity;
import net.minecraft.util.NonNullList;
import org.cyclops.everlastingabilities.RegistryEntries;
import org.cyclops.everlastingabilities.api.Ability;
import org.cyclops.everlastingabilities.api.AbilityTypes;
import org.cyclops.everlastingabilities.api.IAbilityType;
import org.cyclops.everlastingabilities.capability.MutableAbilityStoreConfig;

package org.cyclops.everlastingabilities.item;


/**
 * A totem with abilities.
 * @author rubensworks
 */
public class ItemAbilityTotem extends ItemGuiAbilityContainer {

    public ItemAbilityTotem(Properties properties) {
        super(properties);
    }

    @Override
    public boolean canMoveFromPlayer() {
        return false;
    }

    @Override
    public Rarity getRarity(ItemStack itemStack) {
        return itemStack.getCapability(MutableAbilityStoreConfig.CAPABILITY, null)
                .map(abilityStore -> {
                    int maxRarity = 0;
                    for (Ability ability : abilityStore.getAbilities()) {
                        maxRarity = Math.max(maxRarity, ability.getAbilityType().getRarity().ordinal());
                    }
                    return Rarity.values()[maxRarity];
                })
                .orElse(super.getRarity(itemStack));
    }

    public static ItemStack getTotem(Ability ability) {
        ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_ABILITY_TOTEM);
        itemStack.getCapability(MutableAbilityStoreConfig.CAPABILITY, null)
                .ifPresent(mutableAbilityStore -> mutableAbilityStore.addAbility(ability, true));
        return itemStack;
    }

    @Override
    public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items) {
        if (this.isInGroup(group)) {
            for (IAbilityType abilityType : AbilityTypes.REGISTRY.getValues()) {