package net.minecraft.sounds;

import net.minecraft.core.RegistryMaterials;
import net.minecraft.resources.MinecraftKey;

import com.bergerkiller.generated.net.minecraft.core.RegistryMaterialsHandle;
import com.bergerkiller.generated.net.minecraft.resources.MinecraftKeyHandle;
import com.bergerkiller.generated.net.minecraft.sounds.SoundEffectHandle;
import com.bergerkiller.generated.net.minecraft.sounds.SoundCategoryHandle;

optional class SoundCategory {
#if version >= 1.18
    public String getName();
#else
    public String getName:a();
#endif

#if version >= 1.13
    public static (SoundCategoryHandle) SoundCategory byName(String name) {
        SoundCategory[] categories = SoundCategory.values();
        for (int i = 0; i < categories.length; i++) {
            SoundCategory cat = categories[i];
  #if version >= 1.18
            if (cat.getName().equals(name)) {
  #else
            if (cat.a().equals(name)) {
  #endif
                return cat;
            }
        }
        return null;
    }
#else
    public static (SoundCategoryHandle) SoundCategory byName:a(String name);
#endif
}

class SoundEffect {
#select version >=
#case 1.17:    private final (MinecraftKeyHandle) MinecraftKey name:location;
#case 1.16:    private final (MinecraftKeyHandle) MinecraftKey name:b;
#case 1.13.1:  private final (MinecraftKeyHandle) MinecraftKey name:a;
#case 1.9:     private final (MinecraftKeyHandle) MinecraftKey name:b;
#case else:    private final (MinecraftKeyHandle) MinecraftKeyHandle name;
#endselect

#if version >= 1.9
    #require SoundEffect public static  RegistryMaterials<MinecraftKey, SoundEffect> getSoundRegistry() {
  #if version >= 1.13.1
        return (RegistryMaterials) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT;
  #else
        return SoundEffect.a;
  #endif
    }
#endif

#if version >= 1.19.3
    public static (SoundEffectHandle) SoundEffect createVariableRangeEvent((MinecraftKeyHandle) MinecraftKey minecraftkey);
#else
    public static (SoundEffectHandle) SoundEffect createVariableRangeEvent((MinecraftKeyHandle) MinecraftKey minecraftkey) {
  #if version >= 1.9
        return new SoundEffect(minecraftkey);
  #else
        return SoundEffect.createVariableRangeEvent((Object) minecraftkey);
  #endif
    }
#endif

    public static (SoundEffectHandle) SoundEffect byName(String name) {
        com.bergerkiller.mountiplex.reflection.declarations.Template$StaticMethod createKeyRaw;
        createKeyRaw = (com.bergerkiller.mountiplex.reflection.declarations.Template$StaticMethod) com.bergerkiller.generated.net.minecraft.resources.MinecraftKeyHandle.T.createNew.raw;
        Object key = (MinecraftKey) createKeyRaw.invoke(name);
        if (key == null) {
            return null;
        } else {
            com.bergerkiller.mountiplex.reflection.declarations.Template$StaticMethod byKeyRaw;
            byKeyRaw = (com.bergerkiller.mountiplex.reflection.declarations.Template$StaticMethod) SoundEffectHandle.T.byKey.raw;
            return (SoundEffect) byKeyRaw.invoke(key);
        }
    }

    public static (SoundEffectHandle) SoundEffect byKey((MinecraftKeyHandle) MinecraftKey key) {
#if version >= 1.21.2
        return (SoundEffect) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.getValue((MinecraftKey) key);
#elseif version >= 1.13.1
        return (SoundEffect) ((RegistryMaterials) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT).get((MinecraftKey) key);
#elseif version >= 1.9
        return (SoundEffect) SoundEffect.a.get((Object) key);
#else
        return SoundEffect.createVariableRangeEvent((Object) key);
#endif
    }

#if version >= 1.18.2
    public static optional Object rawSoundEffectResourceKeyToHolder(Object resourceKey) {
        net.minecraft.resources.ResourceKey resourceKeyCasted = (net.minecraft.resources.ResourceKey) resourceKey;
        RegistryMaterials registry = (RegistryMaterials) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT;
  #if version >= 1.19.3
    #if version >= 1.21.2
        java.util.Optional holderOpt = registry.get(resourceKeyCasted);
    #else
        java.util.Optional holderOpt = registry.getHolder(resourceKeyCasted);
    #endif
        if (holderOpt.isPresent()) {
            return holderOpt.get();
        } else {
            return net.minecraft.core.Holder.direct(net.minecraft.sounds.SoundEffect.createVariableRangeEvent(resourceKeyCasted.location()));
        }
  #else
        return registry.getHolderOrThrow(resourceKeyCasted);
  #endif
    }
#else
    public static optional Object rawSoundEffectResourceKeyToHolder:###(Object resourceKey);
#endif

    public static (java.util.Collection<MinecraftKeyHandle>) java.util.Collection<MinecraftKey> getSoundNames() {
#if version >= 1.13.1
        return ((RegistryMaterials) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT).keySet();
#elseif version >= 1.9
        return SoundEffect.a.keySet();
#else
        // The only registry that exists is CraftSound. Sadge.
        org.bukkit.Sound[] values = org.bukkit.Sound.values();
        int len = values.length;
        java.util.List names = new java.util.ArrayList(len);
        for (int i = 0; i < len; i++) {
            String nameStr = org.bukkit.craftbukkit.CraftSound.getSound(values[i]);
            names.add(new MinecraftKey(nameStr));
        }
        return names;
#endif
    }

    <code>
    @Deprecated
    public static SoundEffectHandle createNew(MinecraftKeyHandle name) {
        return createVariableRangeEvent(name);
    }
    </code>
}
