package net.minecraft.world.level.levelgen.feature;

import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.levelgen.structure.OceanMonumentPieces;
import java.util.Random;
import net.minecraft.core.Direction;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import com.google.common.collect.Lists;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import java.util.Iterator;
import java.util.Set;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.biome.Biome;
import java.util.List;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;

public class OceanMonumentFeature extends StructureFeature<NoneFeatureConfiguration> {
    private static final List<Biome.SpawnerData> MONUMENT_ENEMIES;
    
    public OceanMonumentFeature(final Codec<NoneFeatureConfiguration> codec) {
        super(codec);
    }
    
    @Override
    protected boolean linearSeparation() {
        return false;
    }
    
    @Override
    protected boolean isFeatureChunk(final ChunkGenerator cha, final BiomeSource brh, final long long3, final WorldgenRandom ciy, final int integer5, final int integer6, final Biome bre, final ChunkPos bph, final NoneFeatureConfiguration coa) {
        final Set<Biome> set12 = brh.getBiomesWithin(integer5 * 16 + 9, cha.getSeaLevel(), integer6 * 16 + 9, 16);
        for (final Biome bre2 : set12) {
            if (!bre2.isValidStart(this)) {
                return false;
            }
        }
        final Set<Biome> set13 = brh.getBiomesWithin(integer5 * 16 + 9, cha.getSeaLevel(), integer6 * 16 + 9, 29);
        for (final Biome bre3 : set13) {
            if (bre3.getBiomeCategory() != Biome.BiomeCategory.OCEAN && bre3.getBiomeCategory() != Biome.BiomeCategory.RIVER) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public StructureStartFactory<NoneFeatureConfiguration> getStartFactory() {
        return OceanMonumentStart::new;
    }
    
    @Override
    public List<Biome.SpawnerData> getSpecialEnemies() {
        return OceanMonumentFeature.MONUMENT_ENEMIES;
    }
    
    static {
        MONUMENT_ENEMIES = Lists.<Biome.SpawnerData>newArrayList(new Biome.SpawnerData(EntityType.GUARDIAN, 1, 2, 4));
    }
    
    public static class OceanMonumentStart extends StructureStart<NoneFeatureConfiguration> {
        private boolean isCreated;
        
        public OceanMonumentStart(final StructureFeature<NoneFeatureConfiguration> cml, final int integer2, final int integer3, final BoundingBox ctd, final int integer5, final long long6) {
            super(cml, integer2, integer3, ctd, integer5, long6);
        }
        
        @Override
        public void generatePieces(final ChunkGenerator cha, final StructureManager cva, final int integer3, final int integer4, final Biome bre, final NoneFeatureConfiguration coa) {
            this.generatePieces(integer3, integer4);
        }
        
        private void generatePieces(final int integer1, final int integer2) {
            final int integer3 = integer1 * 16 - 29;
            final int integer4 = integer2 * 16 - 29;
            final Direction fz6 = Direction.Plane.HORIZONTAL.getRandomDirection(this.random);
            this.pieces.add(new OceanMonumentPieces.MonumentBuilding(this.random, integer3, integer4, fz6));
            this.calculateBoundingBox();
            this.isCreated = true;
        }
        
        @Override
        public void placeInChunk(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BoundingBox ctd, final ChunkPos bph) {
            if (!this.isCreated) {
                this.pieces.clear();
                this.generatePieces(this.getChunkX(), this.getChunkZ());
            }
            super.placeInChunk(bqu, bqq, cha, random, ctd, bph);
        }
    }
}
