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

import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LightLayer;
import net.minecraft.core.SectionPos;
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.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.configurations.BlockStateConfiguration;

public class LakeFeature extends Feature<BlockStateConfiguration> {
    private static final BlockState AIR;
    
    public LakeFeature(final Codec<BlockStateConfiguration> codec) {
        super(codec);
    }
    
    @Override
    public boolean place(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, BlockPos fu, final BlockStateConfiguration cng) {
        while (fu.getY() > 5 && bqu.isEmptyBlock(fu)) {
            fu = fu.below();
        }
        if (fu.getY() <= 4) {
            return false;
        }
        fu = fu.below(4);
        if (bqq.startsForFeature(SectionPos.of(fu), StructureFeature.VILLAGE).findAny().isPresent()) {
            return false;
        }
        final boolean[] arr8 = new boolean[2048];
        for (int integer9 = random.nextInt(4) + 4, integer10 = 0; integer10 < integer9; ++integer10) {
            final double double11 = random.nextDouble() * 6.0 + 3.0;
            final double double12 = random.nextDouble() * 4.0 + 2.0;
            final double double13 = random.nextDouble() * 6.0 + 3.0;
            final double double14 = random.nextDouble() * (16.0 - double11 - 2.0) + 1.0 + double11 / 2.0;
            final double double15 = random.nextDouble() * (8.0 - double12 - 4.0) + 2.0 + double12 / 2.0;
            final double double16 = random.nextDouble() * (16.0 - double13 - 2.0) + 1.0 + double13 / 2.0;
            for (int integer11 = 1; integer11 < 15; ++integer11) {
                for (int integer12 = 1; integer12 < 15; ++integer12) {
                    for (int integer13 = 1; integer13 < 7; ++integer13) {
                        final double double17 = (integer11 - double14) / (double11 / 2.0);
                        final double double18 = (integer13 - double15) / (double12 / 2.0);
                        final double double19 = (integer12 - double16) / (double13 / 2.0);
                        final double double20 = double17 * double17 + double18 * double18 + double19 * double19;
                        if (double20 < 1.0) {
                            arr8[(integer11 * 16 + integer12) * 8 + integer13] = true;
                        }
                    }
                }
            }
        }
        for (int integer10 = 0; integer10 < 16; ++integer10) {
            for (int integer14 = 0; integer14 < 16; ++integer14) {
                for (int integer15 = 0; integer15 < 8; ++integer15) {
                    final boolean boolean13 = !arr8[(integer10 * 16 + integer14) * 8 + integer15] && ((integer10 < 15 && arr8[((integer10 + 1) * 16 + integer14) * 8 + integer15]) || (integer10 > 0 && arr8[((integer10 - 1) * 16 + integer14) * 8 + integer15]) || (integer14 < 15 && arr8[(integer10 * 16 + integer14 + 1) * 8 + integer15]) || (integer14 > 0 && arr8[(integer10 * 16 + (integer14 - 1)) * 8 + integer15]) || (integer15 < 7 && arr8[(integer10 * 16 + integer14) * 8 + integer15 + 1]) || (integer15 > 0 && arr8[(integer10 * 16 + integer14) * 8 + (integer15 - 1)]));
                    if (boolean13) {
                        final Material cxd14 = bqu.getBlockState(fu.offset(integer10, integer15, integer14)).getMaterial();
                        if (integer15 >= 4 && cxd14.isLiquid()) {
                            return false;
                        }
                        if (integer15 < 4 && !cxd14.isSolid() && bqu.getBlockState(fu.offset(integer10, integer15, integer14)) != cng.state) {
                            return false;
                        }
                    }
                }
            }
        }
        for (int integer10 = 0; integer10 < 16; ++integer10) {
            for (int integer14 = 0; integer14 < 16; ++integer14) {
                for (int integer15 = 0; integer15 < 8; ++integer15) {
                    if (arr8[(integer10 * 16 + integer14) * 8 + integer15]) {
                        bqu.setBlock(fu.offset(integer10, integer15, integer14), (integer15 >= 4) ? LakeFeature.AIR : cng.state, 2);
                    }
                }
            }
        }
        for (int integer10 = 0; integer10 < 16; ++integer10) {
            for (int integer14 = 0; integer14 < 16; ++integer14) {
                for (int integer15 = 4; integer15 < 8; ++integer15) {
                    if (arr8[(integer10 * 16 + integer14) * 8 + integer15]) {
                        final BlockPos fu2 = fu.offset(integer10, integer15 - 1, integer14);
                        if (Feature.isDirt(bqu.getBlockState(fu2).getBlock()) && bqu.getBrightness(LightLayer.SKY, fu.offset(integer10, integer15, integer14)) > 0) {
                            final Biome bre14 = bqu.getBiome(fu2);
                            if (bre14.getSurfaceBuilderConfig().getTopMaterial().is(Blocks.MYCELIUM)) {
                                bqu.setBlock(fu2, Blocks.MYCELIUM.defaultBlockState(), 2);
                            }
                            else {
                                bqu.setBlock(fu2, Blocks.GRASS_BLOCK.defaultBlockState(), 2);
                            }
                        }
                    }
                }
            }
        }
        if (cng.state.getMaterial() == Material.LAVA) {
            for (int integer10 = 0; integer10 < 16; ++integer10) {
                for (int integer14 = 0; integer14 < 16; ++integer14) {
                    for (int integer15 = 0; integer15 < 8; ++integer15) {
                        final boolean boolean13 = !arr8[(integer10 * 16 + integer14) * 8 + integer15] && ((integer10 < 15 && arr8[((integer10 + 1) * 16 + integer14) * 8 + integer15]) || (integer10 > 0 && arr8[((integer10 - 1) * 16 + integer14) * 8 + integer15]) || (integer14 < 15 && arr8[(integer10 * 16 + integer14 + 1) * 8 + integer15]) || (integer14 > 0 && arr8[(integer10 * 16 + (integer14 - 1)) * 8 + integer15]) || (integer15 < 7 && arr8[(integer10 * 16 + integer14) * 8 + integer15 + 1]) || (integer15 > 0 && arr8[(integer10 * 16 + integer14) * 8 + (integer15 - 1)]));
                        if (boolean13 && (integer15 < 4 || random.nextInt(2) != 0) && bqu.getBlockState(fu.offset(integer10, integer15, integer14)).getMaterial().isSolid()) {
                            bqu.setBlock(fu.offset(integer10, integer15, integer14), Blocks.STONE.defaultBlockState(), 2);
                        }
                    }
                }
            }
        }
        if (cng.state.getMaterial() == Material.WATER) {
            for (int integer10 = 0; integer10 < 16; ++integer10) {
                for (int integer14 = 0; integer14 < 16; ++integer14) {
                    final int integer15 = 4;
                    final BlockPos fu2 = fu.offset(integer10, 4, integer14);
                    if (bqu.getBiome(fu2).shouldFreeze(bqu, fu2, false)) {
                        bqu.setBlock(fu2, Blocks.ICE.defaultBlockState(), 2);
                    }
                }
            }
        }
        return true;
    }
    
    static {
        AIR = Blocks.CAVE_AIR.defaultBlockState();
    }
}
