package org.bukkit;

import org.bukkit.FeatureFlag;
import com.bergerkiller.generated.net.minecraft.resources.IdentifierHandle;

class World {

    public boolean hasFeatureFlag(String featureFlagName) {
#if exists org.bukkit.FeatureFlag public static final net.kyori.adventure.util.Index<net.kyori.adventure.key.Key, FeatureFlag> ALL_FLAGS;
        // Paper API using the Adventure-keyed lookup table
        net.kyori.adventure.key.Key key;
        try {
            key = net.kyori.adventure.key.Key.key(featureFlagName);
        } catch (net.kyori.adventure.key.InvalidKeyException ex) {
            return false;
        }
        FeatureFlag flag = (FeatureFlag) FeatureFlag.ALL_FLAGS.valueOr(key, null);
        if (flag != null) {
            return instance.getFeatureFlags().contains(flag);
        }
#elseif version >= 1.20
        // Look up the feature flag from the registry (Spigot)
        org.bukkit.NamespacedKey key = org.bukkit.NamespacedKey.fromString(featureFlagName);
        if (key != null) {
            for (java.util.Iterator iter = instance.getFeatureFlags().iterator(); iter.hasNext();) {
                org.bukkit.NamespacedKey existingKey = ((FeatureFlag) iter.next()).getKey();
                if (key.equals(existingKey)) {
                    return true;
                }
            }
        }
#endif

        return false;
    }

#if version >= 1.11
    // Bukkit API supports SoundCategory
    public void playSound(Location loc, IdentifierHandle sound, (String) org.bukkit.SoundCategory category, float volume, float pitch) {
        if (category == null) {
            return; // Not supported?
        }

  #if version >= 1.13
        // Since 1.13 namespace can also be specified (Identifier in packet)
        instance.playSound(loc, sound.toString(), category, volume, pitch);
  #else
        instance.playSound(loc, sound.getName(), category, volume, pitch);
  #endif
    }
#elseif version >= 1.9
    // Server has a sound category (sound source) but Bukkit has no API for it yet on 1.9 - 1.10.2. Call the NMS API directly.
    public void playSound(Location loc, IdentifierHandle sound, (String) net.minecraft.sounds.SoundSource category, float volume, float pitch) {
        if (category == null) {
            return; // Not supported?
        }

        // Same as CraftWorld playSound, but with the extra sound category parameter.
        if (loc == null || sound == null) return;

        double x = loc.getX();
        double y = loc.getY();
        double z = loc.getZ();

        net.minecraft.server.level.ServerLevel worldServer = ((org.bukkit.craftbukkit.CraftWorld) instance).getHandle();
        net.minecraft.world.level.Level world = worldServer;
        net.minecraft.network.protocol.game.ClientboundCustomSoundPacket packet = new net.minecraft.network.protocol.game.ClientboundCustomSoundPacket(sound.getName(), category, x, y, z, volume, pitch);
        world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, worldServer.dimension, packet);
    }
#else
    public void playSound(Location loc, IdentifierHandle sound, (String) String category, float volume, float pitch) {
        // Sound category not supported. Just play the sound using NMS.
        net.minecraft.world.level.Level worldHandle = ((org.bukkit.craftbukkit.CraftWorld) instance).getHandle();
        worldHandle.makeSound(loc.getX(), loc.getY(), loc.getZ(), sound.getName(), volume, pitch);
    }
#endif

    <code>
    public void playSound(Location loc, IdentifierHandle sound, float volume, float pitch) {
        playSound(loc, sound, "master", volume, pitch);
    }
    </code>

#if version >= 1.17
    public int getMinHeight();
#else
    public int getMinHeight() {
        return 0;
    }
#endif

#if version >= 1.16.5
    public void setClearWeatherDuration(int duration);
#else
    public void setClearWeatherDuration(int duration) {
        // API does not exist yet. Implement a fallback.
        net.minecraft.world.level.Level worldHandle = ((org.bukkit.craftbukkit.CraftWorld) instance).getHandle();

  #if version >= 1.16
        net.minecraft.server.level.ServerLevel worldServerHandle = (net.minecraft.server.level.ServerLevel) worldHandle;
        worldServerHandle.worldDataServer.a(duration);
  #elseif version >= 1.13
        worldHandle.getWorldData().g(duration);
  #else
        worldHandle.getWorldData().i(duration);
  #endif
    }
#endif
}
