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

import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.block.Blocks;
import javax.annotation.Nullable;
import net.minecraft.world.level.levelgen.feature.configurations.MegaTreeConfiguration;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.BlockGetter;
import java.util.Random;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.LevelAccessor;

public abstract class AbstractMegaTreeGrower extends AbstractTreeGrower {
    @Override
    public boolean growTree(final LevelAccessor bjx, final ChunkGenerator<?> caa, final BlockPos fk, final BlockState byj, final Random random) {
        for (int integer7 = 0; integer7 >= -1; --integer7) {
            for (int integer8 = 0; integer8 >= -1; --integer8) {
                if (isTwoByTwoSapling(byj, bjx, fk, integer7, integer8)) {
                    return this.placeMega(bjx, caa, fk, byj, random, integer7, integer8);
                }
            }
        }
        return super.growTree(bjx, caa, fk, byj, random);
    }
    
    @Nullable
    protected abstract ConfiguredFeature<MegaTreeConfiguration, ?> getConfiguredMegaFeature(final Random random);
    
    public boolean placeMega(final LevelAccessor bjx, final ChunkGenerator<?> caa, final BlockPos fk, final BlockState byj, final Random random, final int integer6, final int integer7) {
        final ConfiguredFeature<MegaTreeConfiguration, ?> cdc9 = this.getConfiguredMegaFeature(random);
        if (cdc9 == null) {
            return false;
        }
        final BlockState byj2 = Blocks.AIR.defaultBlockState();
        bjx.setBlock(fk.offset(integer6, 0, integer7), byj2, 4);
        bjx.setBlock(fk.offset(integer6 + 1, 0, integer7), byj2, 4);
        bjx.setBlock(fk.offset(integer6, 0, integer7 + 1), byj2, 4);
        bjx.setBlock(fk.offset(integer6 + 1, 0, integer7 + 1), byj2, 4);
        if (cdc9.place(bjx, caa, random, fk.offset(integer6, 0, integer7))) {
            return true;
        }
        bjx.setBlock(fk.offset(integer6, 0, integer7), byj, 4);
        bjx.setBlock(fk.offset(integer6 + 1, 0, integer7), byj, 4);
        bjx.setBlock(fk.offset(integer6, 0, integer7 + 1), byj, 4);
        bjx.setBlock(fk.offset(integer6 + 1, 0, integer7 + 1), byj, 4);
        return false;
    }
    
    public static boolean isTwoByTwoSapling(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final int integer4, final int integer5) {
        final Block bph6 = byj.getBlock();
        return bph6 == bjg.getBlockState(fk.offset(integer4, 0, integer5)).getBlock() && bph6 == bjg.getBlockState(fk.offset(integer4 + 1, 0, integer5)).getBlock() && bph6 == bjg.getBlockState(fk.offset(integer4, 0, integer5 + 1)).getBlock() && bph6 == bjg.getBlockState(fk.offset(integer4 + 1, 0, integer5 + 1)).getBlock();
    }
}
