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

import java.util.function.Function;
import net.minecraft.world.level.LevelSimulatedReader;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.LevelSimulatedRW;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import java.util.Set;
import net.minecraft.core.BlockPos;
import java.util.List;
import java.util.Random;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
import com.mojang.serialization.Codec;

public class AlterGroundDecorator extends TreeDecorator {
    public static final Codec<AlterGroundDecorator> CODEC;
    private final BlockStateProvider provider;
    
    public AlterGroundDecorator(final BlockStateProvider cpo) {
        this.provider = cpo;
    }
    
    @Override
    protected TreeDecoratorType<?> type() {
        return TreeDecoratorType.ALTER_GROUND;
    }
    
    @Override
    public void place(final LevelAccessor bqc, final Random random, final List<BlockPos> list3, final List<BlockPos> list4, final Set<BlockPos> set, final BoundingBox ctd) {
        final int integer8 = list3.get(0).getY();
        int integer9;
        int integer10;
        int integer11;
        int integer12;
        list3.stream().filter(fu -> fu.getY() == integer8).forEach(fu -> {
            this.placeCircle(bqc, random, fu.west().north());
            this.placeCircle(bqc, random, fu.east(2).north());
            this.placeCircle(bqc, random, fu.west().south(2));
            this.placeCircle(bqc, random, fu.east(2).south(2));
            for (integer9 = 0; integer9 < 5; ++integer9) {
                integer10 = random.nextInt(64);
                integer11 = integer10 % 8;
                integer12 = integer10 / 8;
                if (integer11 == 0 || integer11 == 7 || integer12 == 0 || integer12 == 7) {
                    this.placeCircle(bqc, random, fu.offset(-3 + integer11, 0, -3 + integer12));
                }
            }
        });
    }
    
    private void placeCircle(final LevelSimulatedRW bqf, final Random random, final BlockPos fu) {
        for (int integer5 = -2; integer5 <= 2; ++integer5) {
            for (int integer6 = -2; integer6 <= 2; ++integer6) {
                if (Math.abs(integer5) != 2 || Math.abs(integer6) != 2) {
                    this.placeBlockAt(bqf, random, fu.offset(integer5, 0, integer6));
                }
            }
        }
    }
    
    private void placeBlockAt(final LevelSimulatedRW bqf, final Random random, final BlockPos fu) {
        for (int integer5 = 2; integer5 >= -3; --integer5) {
            final BlockPos fu2 = fu.above(integer5);
            if (Feature.isGrassOrDirt(bqf, fu2)) {
                bqf.setBlock(fu2, this.provider.getState(random, fu), 19);
                break;
            }
            if (!Feature.isAir(bqf, fu2) && integer5 < 0) {
                break;
            }
        }
    }
    
    static {
        CODEC = BlockStateProvider.CODEC.fieldOf("provider").xmap((Function)AlterGroundDecorator::new, cqi -> cqi.provider).codec();
    }
}
