package net.minecraft.sounds;

import net.minecraft.core.MappedRegistry;
import net.minecraft.resources.Identifier;

import com.bergerkiller.generated.net.minecraft.core.MappedRegistryHandle;
import com.bergerkiller.generated.net.minecraft.resources.IdentifierHandle;
import com.bergerkiller.generated.net.minecraft.sounds.SoundEventHandle;
import com.bergerkiller.generated.net.minecraft.sounds.SoundSourceHandle;

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

#if version >= 1.13
    public static (SoundSourceHandle) SoundSource byName(String name) {
        SoundSource[] categories = SoundSource.values();
        for (int i = 0; i < categories.length; i++) {
            SoundSource 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 (SoundSourceHandle) SoundSource byName:a(String name);
#endif
}

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

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

#if version >= 1.19.3
    public static (SoundEventHandle) SoundEvent createVariableRangeEvent((IdentifierHandle) Identifier minecraftkey);
#else
    public static (SoundEventHandle) SoundEvent createVariableRangeEvent((IdentifierHandle) Identifier minecraftkey) {
  #if version >= 1.9
        return new SoundEvent(minecraftkey);
  #else
        return SoundEvent.createVariableRangeEvent((Object) minecraftkey);
  #endif
    }
#endif

    public static (SoundEventHandle) SoundEvent 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.IdentifierHandle.T.createNew.raw;
        Object key = (Identifier) 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) SoundEventHandle.T.byKey.raw;
            return (SoundEvent) byKeyRaw.invoke(key);
        }
    }

    public static (SoundEventHandle) SoundEvent byKey((IdentifierHandle) Identifier key) {
#if version >= 1.21.2
        return (SoundEvent) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.getValue((Identifier) key);
#elseif version >= 1.13.1
        return (SoundEvent) ((MappedRegistry) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT).get((Identifier) key);
#elseif version >= 1.9
        return (SoundEvent) SoundEvent.a.get((Object) key);
#else
        return SoundEvent.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;
        MappedRegistry registry = (MappedRegistry) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT;
  #if version >= 1.21.11
        java.util.Optional holderOpt = registry.get(resourceKeyCasted);
        if (holderOpt.isPresent()) {
            return holderOpt.get();
        } else {
            return net.minecraft.core.Holder.direct(net.minecraft.sounds.SoundEvent.createVariableRangeEvent(resourceKeyCasted.identifier()));
        }
  #elseif 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.SoundEvent.createVariableRangeEvent(resourceKeyCasted.location()));
        }
  #else
        return registry.getHolderOrThrow(resourceKeyCasted);
  #endif
    }
#else
    public static optional Object rawSoundEffectResourceKeyToHolder:###(Object resourceKey);
#endif

    public static (java.util.Collection<IdentifierHandle>) java.util.Collection<Identifier> getSoundNames() {
#if version >= 1.13.1
        return ((MappedRegistry) net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT).keySet();
#elseif version >= 1.9
        return SoundEvent.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 Identifier(nameStr));
        }
        return names;
#endif
    }

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