package net.minecraft.world.level;

import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;

import net.minecraft.world.level.SpawnData;

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

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

class BaseSpawner {
    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) Level world, (IntVector3) BlockPos blockPosition) {
#if version >= 1.18
        if (world instanceof ServerLevel) {
            instance.serverTick((ServerLevel) world, blockPosition);
        }
#elseif version >= 1.17
        if (world instanceof ServerLevel) {
            instance.a((ServerLevel) world, blockPosition);
        }
#else
        instance.c();
#endif
    }

#if version >= 1.18
    public (IdentifierHandle) Identifier getMobName() {
        // No API :( will need to read NBT directly
        CompoundTag spawnedEntityNBT = instance.nextSpawnData.getEntityToSpawn();
  #if version >= 1.21.5
        return Identifier.tryParse(spawnedEntityNBT.getStringOr("id", ""));
  #else
        return Identifier.tryParse(spawnedEntityNBT.getString("id"));
  #endif
    }
    public void setMobName((IdentifierHandle) Identifier 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 BaseSpawner private net.minecraft.util.random.WeightedList<SpawnData> spawnPotentials;
        instance#spawnPotentials = net.minecraft.util.random.WeightedList.of();
  #else
        #require BaseSpawner private net.minecraft.util.random.SimpleWeightedRandomList<SpawnData> spawnPotentials;
        instance#spawnPotentials = net.minecraft.util.random.SimpleWeightedRandomList.empty();
  #endif
    }
#elseif version >= 1.17
    public (IdentifierHandle) Identifier getMobName() {
        // They added 2 params for debug uses
        return instance.getMobName(null, null);
    }
    public void setMobName((IdentifierHandle) Identifier nameKey) {
        instance.setMobName((EntityType) BuiltInRegistries.ENTITY_TYPE.get(nameKey));
    }
#elseif version >= 1.13.1
    public (IdentifierHandle) Identifier getMobName();
    public void setMobName((IdentifierHandle) Identifier nameKey) {
        instance.setMobName((EntityType) BuiltInRegistries.ENTITY_TYPE.get(nameKey));
    }
#elseif version >= 1.13
    public (IdentifierHandle) Identifier getMobName();
    public void setMobName((IdentifierHandle) Identifier nameKey) {
        instance.setMobName((EntityType) EntityType.REGISTRY.get(nameKey));
    }
#elseif version >= 1.11
    public (IdentifierHandle) Identifier getMobName();
    public void setMobName((IdentifierHandle) Identifier nameKey);
#else
    public (IdentifierHandle) String getMobName();
    public void setMobName((IdentifierHandle) String nameKey);
#endif
}
