package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.tags.Tag;
import net.minecraft.tags.EntityTypeTags;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.LevelAccessor;
import java.util.Iterator;
import javax.annotation.Nullable;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.IntegerProperty;

public class ChorusFlowerBlock extends Block {
    public static final IntegerProperty AGE;
    private final ChorusPlantBlock plant;
    
    protected ChorusFlowerBlock(final ChorusPlantBlock bwj, final Properties c) {
        super(c);
        this.plant = bwj;
        this.registerDefaultState(((StateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 0));
    }
    
    @Override
    public void tick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        if (!cfj.canSurvive(zd, fu)) {
            zd.destroyBlock(fu, true);
        }
    }
    
    @Override
    public boolean isRandomlyTicking(final BlockState cfj) {
        return cfj.<Integer>getValue((Property<Integer>)ChorusFlowerBlock.AGE) < 5;
    }
    
    @Override
    public void randomTick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        final BlockPos fu2 = fu.above();
        if (!zd.isEmptyBlock(fu2) || fu2.getY() >= 256) {
            return;
        }
        final int integer7 = cfj.<Integer>getValue((Property<Integer>)ChorusFlowerBlock.AGE);
        if (integer7 >= 5) {
            return;
        }
        boolean boolean8 = false;
        boolean boolean9 = false;
        final BlockState cfj2 = zd.getBlockState(fu.below());
        final Block bvr11 = cfj2.getBlock();
        if (bvr11 == Blocks.END_STONE) {
            boolean8 = true;
        }
        else if (bvr11 == this.plant) {
            int integer8 = 1;
            int integer9 = 0;
            while (integer9 < 4) {
                final Block bvr12 = zd.getBlockState(fu.below(integer8 + 1)).getBlock();
                if (bvr12 == this.plant) {
                    ++integer8;
                    ++integer9;
                }
                else {
                    if (bvr12 == Blocks.END_STONE) {
                        boolean9 = true;
                        break;
                    }
                    break;
                }
            }
            if (integer8 < 2 || integer8 <= random.nextInt(boolean9 ? 5 : 4)) {
                boolean8 = true;
            }
        }
        else if (cfj2.isAir()) {
            boolean8 = true;
        }
        if (boolean8 && allNeighborsEmpty(zd, fu2, null) && zd.isEmptyBlock(fu.above(2))) {
            zd.setBlock(fu, this.plant.getStateForPlacement(zd, fu), 2);
            this.placeGrownFlower(zd, fu2, integer7);
        }
        else if (integer7 < 4) {
            int integer8 = random.nextInt(4);
            if (boolean9) {
                ++integer8;
            }
            boolean boolean10 = false;
            for (int integer10 = 0; integer10 < integer8; ++integer10) {
                final Direction fz15 = Direction.Plane.HORIZONTAL.getRandomDirection(random);
                final BlockPos fu3 = fu.relative(fz15);
                if (zd.isEmptyBlock(fu3) && zd.isEmptyBlock(fu3.below()) && allNeighborsEmpty(zd, fu3, fz15.getOpposite())) {
                    this.placeGrownFlower(zd, fu3, integer7 + 1);
                    boolean10 = true;
                }
            }
            if (boolean10) {
                zd.setBlock(fu, this.plant.getStateForPlacement(zd, fu), 2);
            }
            else {
                this.placeDeadFlower(zd, fu);
            }
        }
        else {
            this.placeDeadFlower(zd, fu);
        }
    }
    
    private void placeGrownFlower(final Level bqb, final BlockPos fu, final int integer) {
        bqb.setBlock(fu, ((StateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, integer), 2);
        bqb.levelEvent(1033, fu, 0);
    }
    
    private void placeDeadFlower(final Level bqb, final BlockPos fu) {
        bqb.setBlock(fu, ((StateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 5), 2);
        bqb.levelEvent(1034, fu, 0);
    }
    
    private static boolean allNeighborsEmpty(final LevelReader bqd, final BlockPos fu, @Nullable final Direction fz) {
        for (final Direction fz2 : Direction.Plane.HORIZONTAL) {
            if (fz2 != fz && !bqd.isEmptyBlock(fu.relative(fz2))) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (fz != Direction.UP && !cfj1.canSurvive(bqc, fu5)) {
            bqc.getBlockTicks().scheduleTick(fu5, this, 1);
        }
        return super.updateShape(cfj1, fz, cfj3, bqc, fu5, fu6);
    }
    
    @Override
    public boolean canSurvive(final BlockState cfj, final LevelReader bqd, final BlockPos fu) {
        final BlockState cfj2 = bqd.getBlockState(fu.below());
        if (cfj2.getBlock() == this.plant || cfj2.is(Blocks.END_STONE)) {
            return true;
        }
        if (!cfj2.isAir()) {
            return false;
        }
        boolean boolean6 = false;
        for (final Direction fz8 : Direction.Plane.HORIZONTAL) {
            final BlockState cfj3 = bqd.getBlockState(fu.relative(fz8));
            if (cfj3.is(this.plant)) {
                if (boolean6) {
                    return false;
                }
                boolean6 = true;
            }
            else {
                if (!cfj3.isAir()) {
                    return false;
                }
                continue;
            }
        }
        return boolean6;
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(ChorusFlowerBlock.AGE);
    }
    
    public static void generatePlant(final LevelAccessor bqc, final BlockPos fu, final Random random, final int integer) {
        bqc.setBlock(fu, ((ChorusPlantBlock)Blocks.CHORUS_PLANT).getStateForPlacement(bqc, fu), 2);
        growTreeRecursive(bqc, fu, random, fu, integer, 0);
    }
    
    private static void growTreeRecursive(final LevelAccessor bqc, final BlockPos fu2, final Random random, final BlockPos fu4, final int integer5, final int integer6) {
        final ChorusPlantBlock bwj7 = (ChorusPlantBlock)Blocks.CHORUS_PLANT;
        int integer7 = random.nextInt(4) + 1;
        if (integer6 == 0) {
            ++integer7;
        }
        for (int integer8 = 0; integer8 < integer7; ++integer8) {
            final BlockPos fu5 = fu2.above(integer8 + 1);
            if (!allNeighborsEmpty(bqc, fu5, null)) {
                return;
            }
            bqc.setBlock(fu5, bwj7.getStateForPlacement(bqc, fu5), 2);
            bqc.setBlock(fu5.below(), bwj7.getStateForPlacement(bqc, fu5.below()), 2);
        }
        boolean boolean9 = false;
        if (integer6 < 4) {
            int integer9 = random.nextInt(4);
            if (integer6 == 0) {
                ++integer9;
            }
            for (int integer10 = 0; integer10 < integer9; ++integer10) {
                final Direction fz12 = Direction.Plane.HORIZONTAL.getRandomDirection(random);
                final BlockPos fu6 = fu2.above(integer7).relative(fz12);
                if (Math.abs(fu6.getX() - fu4.getX()) < integer5) {
                    if (Math.abs(fu6.getZ() - fu4.getZ()) < integer5) {
                        if (bqc.isEmptyBlock(fu6) && bqc.isEmptyBlock(fu6.below()) && allNeighborsEmpty(bqc, fu6, fz12.getOpposite())) {
                            boolean9 = true;
                            bqc.setBlock(fu6, bwj7.getStateForPlacement(bqc, fu6), 2);
                            bqc.setBlock(fu6.relative(fz12.getOpposite()), bwj7.getStateForPlacement(bqc, fu6.relative(fz12.getOpposite())), 2);
                            growTreeRecursive(bqc, fu6, random, fu4, integer5, integer6 + 1);
                        }
                    }
                }
            }
        }
        if (!boolean9) {
            bqc.setBlock(fu2.above(integer7), ((StateHolder<O, BlockState>)Blocks.CHORUS_FLOWER.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 5), 2);
        }
    }
    
    @Override
    public void onProjectileHit(final Level bqb, final BlockState cfj, final BlockHitResult deh, final Projectile bes) {
        if (bes.getType().is(EntityTypeTags.IMPACT_PROJECTILES)) {
            final BlockPos fu6 = deh.getBlockPos();
            bqb.destroyBlock(fu6, true, bes);
        }
    }
    
    static {
        AGE = BlockStateProperties.AGE_5;
    }
}
