package net.minecraft.world.entity.npc;

import net.minecraft.world.entity.Entity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.entity.MobSpawnType;
import java.util.List;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.entity.animal.Cat;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
import net.minecraft.world.entity.ai.village.poi.PoiType;
import net.minecraft.core.BlockPos;
import java.util.Random;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.SpawnPlacements;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.CustomSpawner;

public class CatSpawner implements CustomSpawner {
    private int nextTick;
    
    @Override
    public int tick(final ServerLevel zd, final boolean boolean2, final boolean boolean3) {
        if (!boolean3 || !zd.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
            return 0;
        }
        --this.nextTick;
        if (this.nextTick > 0) {
            return 0;
        }
        this.nextTick = 1200;
        final Player bec5 = zd.getRandomPlayer();
        if (bec5 == null) {
            return 0;
        }
        final Random random6 = zd.random;
        final int integer7 = (8 + random6.nextInt(24)) * (random6.nextBoolean() ? -1 : 1);
        final int integer8 = (8 + random6.nextInt(24)) * (random6.nextBoolean() ? -1 : 1);
        final BlockPos fu9 = bec5.blockPosition().offset(integer7, 0, integer8);
        if (!zd.hasChunksAt(fu9.getX() - 10, fu9.getY() - 10, fu9.getZ() - 10, fu9.getX() + 10, fu9.getY() + 10, fu9.getZ() + 10)) {
            return 0;
        }
        if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, zd, fu9, EntityType.CAT)) {
            if (zd.isCloseToVillage(fu9, 2)) {
                return this.spawnInVillage(zd, fu9);
            }
            if (zd.structureFeatureManager().getStructureAt(fu9, true, StructureFeature.SWAMP_HUT).isValid()) {
                return this.spawnInHut(zd, fu9);
            }
        }
        return 0;
    }
    
    private int spawnInVillage(final ServerLevel zd, final BlockPos fu) {
        final int integer4 = 48;
        if (zd.getPoiManager().getCountInRange(PoiType.HOME.getPredicate(), fu, 48, PoiManager.Occupancy.IS_OCCUPIED) > 4L) {
            final List<Cat> list5 = zd.<Cat>getEntitiesOfClass(Cat.class, new AABB(fu).inflate(48.0, 8.0, 48.0));
            if (list5.size() < 5) {
                return this.spawnCat(fu, zd);
            }
        }
        return 0;
    }
    
    private int spawnInHut(final Level bqb, final BlockPos fu) {
        final int integer4 = 16;
        final List<Cat> list5 = bqb.<Cat>getEntitiesOfClass(Cat.class, new AABB(fu).inflate(16.0, 8.0, 16.0));
        if (list5.size() < 1) {
            return this.spawnCat(fu, bqb);
        }
        return 0;
    }
    
    private int spawnCat(final BlockPos fu, final Level bqb) {
        final Cat aym4 = EntityType.CAT.create(bqb);
        if (aym4 == null) {
            return 0;
        }
        aym4.finalizeSpawn(bqb, bqb.getCurrentDifficultyAt(fu), MobSpawnType.NATURAL, null, null);
        aym4.moveTo(fu, 0.0f, 0.0f);
        bqb.addFreshEntity(aym4);
        return 1;
    }
}
