package net.minecraft.world.level.block.grower;

import java.util.Iterator;
import net.minecraft.world.level.block.Block;
import net.minecraft.tags.Tag;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.server.level.ServerLevel;
import javax.annotation.Nullable;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import java.util.Random;

public abstract class AbstractTreeGrower {
    @Nullable
    protected abstract ConfiguredFeature<TreeConfiguration, ?> getConfiguredFeature(final Random random, final boolean boolean2);
    
    public boolean growTree(final ServerLevel zd, final ChunkGenerator cha, final BlockPos fu, final BlockState cfj, final Random random) {
        final ConfiguredFeature<TreeConfiguration, ?> ckb7 = this.getConfiguredFeature(random, this.hasFlowers(zd, fu));
        if (ckb7 == null) {
            return false;
        }
        zd.setBlock(fu, Blocks.AIR.defaultBlockState(), 4);
        ckb7.config.setFromSapling();
        if (ckb7.place(zd, zd.structureFeatureManager(), cha, random, fu)) {
            return true;
        }
        zd.setBlock(fu, cfj, 4);
        return false;
    }
    
    private boolean hasFlowers(final LevelAccessor bqc, final BlockPos fu) {
        for (final BlockPos fu2 : BlockPos.betweenClosed(fu.below().north(2).west(2), fu.above().south(2).east(2))) {
            if (bqc.getBlockState(fu2).is(BlockTags.FLOWERS)) {
                return true;
            }
        }
        return false;
    }
}
