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

import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import javax.annotation.Nullable;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Iterator;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.LevelWriter;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.core.Direction;
import net.minecraft.core.BlockPos;
import java.util.Random;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.levelgen.feature.configurations.ReplaceSpheroidConfiguration;

public class ReplaceBlobsFeature extends Feature<ReplaceSpheroidConfiguration> {
    public ReplaceBlobsFeature(final Codec<ReplaceSpheroidConfiguration> codec) {
        super(codec);
    }
    
    @Override
    public boolean place(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BlockPos fu, final ReplaceSpheroidConfiguration coj) {
        final Block bvr8 = coj.targetState.getBlock();
        final BlockPos fu2 = findTarget(bqu, fu.mutable().clamp(Direction.Axis.Y, 1, bqu.getMaxBuildHeight() - 1), bvr8);
        if (fu2 == null) {
            return false;
        }
        final Vec3i gr10 = calculateReach(random, coj);
        final int integer11 = Math.max(gr10.getX(), Math.max(gr10.getY(), gr10.getZ()));
        boolean boolean12 = false;
        for (final BlockPos fu3 : BlockPos.withinManhattan(fu2, gr10.getX(), gr10.getY(), gr10.getZ())) {
            if (fu3.distManhattan(fu2) > integer11) {
                break;
            }
            final BlockState cfj15 = bqu.getBlockState(fu3);
            if (!cfj15.is(bvr8)) {
                continue;
            }
            this.setBlock(bqu, fu3, coj.replaceState);
            boolean12 = true;
        }
        return boolean12;
    }
    
    @Nullable
    private static BlockPos findTarget(final LevelAccessor bqc, final BlockPos.MutableBlockPos a, final Block bvr) {
        while (a.getY() > 1) {
            final BlockState cfj4 = bqc.getBlockState(a);
            if (cfj4.is(bvr)) {
                return a;
            }
            a.move(Direction.DOWN);
        }
        return null;
    }
    
    private static Vec3i calculateReach(final Random random, final ReplaceSpheroidConfiguration coj) {
        return new Vec3i(coj.minimumReach.getX() + random.nextInt(coj.maximumReach.getX() - coj.minimumReach.getX() + 1), coj.minimumReach.getY() + random.nextInt(coj.maximumReach.getY() - coj.minimumReach.getY() + 1), coj.minimumReach.getZ() + random.nextInt(coj.maximumReach.getZ() - coj.minimumReach.getZ() + 1));
    }
}
