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

import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.types.DynamicOps;
import net.minecraft.world.level.LevelSimulatedReader;
import net.minecraft.world.level.levelgen.feature.AbstractTreeFeature;
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.resources.ResourceLocation;
import java.util.function.Supplier;
import net.minecraft.core.Registry;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProviderType;
import com.mojang.datafixers.Dynamic;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;

public class AlterGroundDecorator extends TreeDecorator {
    private final BlockStateProvider provider;
    
    public AlterGroundDecorator(final BlockStateProvider chw) {
        super(TreeDecoratorType.ALTER_GROUND);
        this.provider = chw;
    }
    
    public <T> AlterGroundDecorator(final Dynamic<T> dynamic) {
        this(Registry.BLOCKSTATE_PROVIDER_TYPES.get(new ResourceLocation(dynamic.get("provider").get("type").asString().<Throwable>orElseThrow(RuntimeException::new))).deserialize(dynamic.get("provider").orElseEmptyMap()));
    }
    
    @Override
    public void place(final LevelAccessor bjx, final Random random, final List<BlockPos> list3, final List<BlockPos> list4, final Set<BlockPos> set, final BoundingBox clb) {
        final int integer8 = list3.get(0).getY();
        int integer9;
        int integer10;
        int integer11;
        int integer12;
        list3.stream().filter(fk -> fk.getY() == integer8).forEach(fk -> {
            this.placeCircle(bjx, random, fk.west().north());
            this.placeCircle(bjx, random, fk.east(2).north());
            this.placeCircle(bjx, random, fk.west().south(2));
            this.placeCircle(bjx, random, fk.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(bjx, random, fk.offset(-3 + integer11, 0, -3 + integer12));
                }
            }
        });
    }
    
    private void placeCircle(final LevelSimulatedRW bkb, final Random random, final BlockPos fk) {
        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(bkb, random, fk.offset(integer5, 0, integer6));
                }
            }
        }
    }
    
    private void placeBlockAt(final LevelSimulatedRW bkb, final Random random, final BlockPos fk) {
        for (int integer5 = 2; integer5 >= -3; --integer5) {
            final BlockPos fk2 = fk.above(integer5);
            if (AbstractTreeFeature.isGrassOrDirt(bkb, fk2)) {
                bkb.setBlock(fk2, this.provider.getState(random, fk), 19);
                break;
            }
            if (!AbstractTreeFeature.isAir(bkb, fk2) && integer5 < 0) {
                break;
            }
        }
    }
    
    @Override
    public <T> T serialize(final DynamicOps<T> dynamicOps) {
        return (T)new Dynamic((DynamicOps)dynamicOps, dynamicOps.createMap((Map)ImmutableMap.of(dynamicOps.createString("type"), dynamicOps.createString(Registry.TREE_DECORATOR_TYPES.getKey(this.type).toString()), dynamicOps.createString("provider"), this.provider.<V>serialize((com.mojang.datafixers.types.DynamicOps<V>)dynamicOps)))).getValue();
    }
}
