package net.minecraft.world.level;

import net.minecraft.core.BlockPosition;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.World;

import com.bergerkiller.bukkit.common.bases.IntVector3;

import com.bergerkiller.generated.net.minecraft.resources.MinecraftKeyHandle;

class MobSpawnerAbstract {
    public int spawnDelay;

    private int minSpawnDelay;
    private int maxSpawnDelay;
    private int spawnCount;

#if version >= 1.17
    private (org.bukkit.entity.Entity) Entity entity:displayEntity;
#elseif version >= 1.13
    private (org.bukkit.entity.Entity) Entity entity:j;
#elseif version >= 1.9
    private (org.bukkit.entity.Entity) Entity entity:i;
#else
    private (org.bukkit.entity.Entity) Entity entity:j;
#endif

    private int maxNearbyEntities;
    private int requiredPlayerRange;
    private int spawnRange;

    public void onTick((org.bukkit.World) World world, (IntVector3) BlockPosition blockPosition) {
#if version >= 1.18
        if (world instanceof WorldServer) {
            instance.serverTick((WorldServer) world, blockPosition);
        }
#elseif version >= 1.17
        if (world instanceof WorldServer) {
            instance.a((WorldServer) world, blockPosition);
        }
#else
        instance.c();
#endif
    }

#if version >= 1.18
    public (MinecraftKeyHandle) MinecraftKey getMobName() {
        // No API :( will need to read NBT directly
        NBTTagCompound spawnedEntityNBT = instance.nextSpawnData.getEntityToSpawn();
  #if version >= 1.21.5
        return MinecraftKey.tryParse(spawnedEntityNBT.getStringOr("id", ""));
  #else
        return MinecraftKey.tryParse(spawnedEntityNBT.getString("id"));
  #endif
    }
    public void setMobName((MinecraftKeyHandle) MinecraftKey nameKey) {
        // Set NBT directly
        instance.nextSpawnData.getEntityToSpawn().putString("id", nameKey.toString());

        // Note: spawnPotentials is private on some forge servers
  #if version >= 1.21.5
        #require MobSpawnerAbstract private net.minecraft.util.random.WeightedList<MobSpawnerData> spawnPotentials;
        instance#spawnPotentials = net.minecraft.util.random.WeightedList.of();
  #else
        #require MobSpawnerAbstract private net.minecraft.util.random.SimpleWeightedRandomList<MobSpawnerData> spawnPotentials;
        instance#spawnPotentials = net.minecraft.util.random.SimpleWeightedRandomList.empty();
  #endif
    }
#elseif version >= 1.17
    public (MinecraftKeyHandle) MinecraftKey getMobName() {
        // They added 2 params for debug uses
        return instance.getMobName(null, null);
    }
    public void setMobName((MinecraftKeyHandle) MinecraftKey nameKey) {
        instance.setMobName((EntityTypes) BuiltInRegistries.ENTITY_TYPE.get(nameKey));
    }
#elseif version >= 1.13.1
    public (MinecraftKeyHandle) MinecraftKey getMobName();
    public void setMobName((MinecraftKeyHandle) MinecraftKey nameKey) {
        instance.setMobName((EntityTypes) BuiltInRegistries.ENTITY_TYPE.get(nameKey));
    }
#elseif version >= 1.13
    public (MinecraftKeyHandle) MinecraftKey getMobName();
    public void setMobName((MinecraftKeyHandle) MinecraftKey nameKey) {
        instance.setMobName((EntityTypes) EntityTypes.REGISTRY.get(nameKey));
    }
#elseif version >= 1.11
    public (MinecraftKeyHandle) MinecraftKey getMobName();
    public void setMobName((MinecraftKeyHandle) MinecraftKey nameKey);
#else
    public (MinecraftKeyHandle) String getMobName();
    public void setMobName((MinecraftKeyHandle) String nameKey);
#endif
}
