package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.entity.Entity;
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.properties.IntegerProperty;

public class ChorusFlowerBlock extends Block {
    public static final IntegerProperty AGE;
    private final ChorusPlantBlock plant;
    
    protected ChorusFlowerBlock(final ChorusPlantBlock bpy, final Properties c) {
        super(c);
        this.plant = bpy;
        this.registerDefaultState(((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 0));
    }
    
    @Override
    public void tick(final BlockState byj, final ServerLevel xd, final BlockPos fk, final Random random) {
        if (!byj.canSurvive(xd, fk)) {
            xd.destroyBlock(fk, true);
            return;
        }
        final BlockPos fk2 = fk.above();
        if (!xd.isEmptyBlock(fk2) || fk2.getY() >= 256) {
            return;
        }
        final int integer7 = byj.<Integer>getValue((Property<Integer>)ChorusFlowerBlock.AGE);
        if (integer7 >= 5) {
            return;
        }
        boolean boolean8 = false;
        boolean boolean9 = false;
        final BlockState byj2 = xd.getBlockState(fk.below());
        final Block bph11 = byj2.getBlock();
        if (bph11 == Blocks.END_STONE) {
            boolean8 = true;
        }
        else if (bph11 == this.plant) {
            int integer8 = 1;
            int integer9 = 0;
            while (integer9 < 4) {
                final Block bph12 = xd.getBlockState(fk.below(integer8 + 1)).getBlock();
                if (bph12 == this.plant) {
                    ++integer8;
                    ++integer9;
                }
                else {
                    if (bph12 == Blocks.END_STONE) {
                        boolean9 = true;
                        break;
                    }
                    break;
                }
            }
            if (integer8 < 2 || integer8 <= random.nextInt(boolean9 ? 5 : 4)) {
                boolean8 = true;
            }
        }
        else if (byj2.isAir()) {
            boolean8 = true;
        }
        if (boolean8 && allNeighborsEmpty(xd, fk2, null) && xd.isEmptyBlock(fk.above(2))) {
            xd.setBlock(fk, this.plant.getStateForPlacement(xd, fk), 2);
            this.placeGrownFlower(xd, fk2, 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 fp15 = Direction.Plane.HORIZONTAL.getRandomDirection(random);
                final BlockPos fk3 = fk.relative(fp15);
                if (xd.isEmptyBlock(fk3) && xd.isEmptyBlock(fk3.below()) && allNeighborsEmpty(xd, fk3, fp15.getOpposite())) {
                    this.placeGrownFlower(xd, fk3, integer7 + 1);
                    boolean10 = true;
                }
            }
            if (boolean10) {
                xd.setBlock(fk, this.plant.getStateForPlacement(xd, fk), 2);
            }
            else {
                this.placeDeadFlower(xd, fk);
            }
        }
        else {
            this.placeDeadFlower(xd, fk);
        }
    }
    
    private void placeGrownFlower(final Level bjw, final BlockPos fk, final int integer) {
        bjw.setBlock(fk, ((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, integer), 2);
        bjw.levelEvent(1033, fk, 0);
    }
    
    private void placeDeadFlower(final Level bjw, final BlockPos fk) {
        bjw.setBlock(fk, ((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 5), 2);
        bjw.levelEvent(1034, fk, 0);
    }
    
    private static boolean allNeighborsEmpty(final LevelReader bjz, final BlockPos fk, @Nullable final Direction fp) {
        for (final Direction fp2 : Direction.Plane.HORIZONTAL) {
            if (fp2 != fp && !bjz.isEmptyBlock(fk.relative(fp2))) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public BlockState updateShape(final BlockState byj1, final Direction fp, final BlockState byj3, final LevelAccessor bjx, final BlockPos fk5, final BlockPos fk6) {
        if (fp != Direction.UP && !byj1.canSurvive(bjx, fk5)) {
            bjx.getBlockTicks().scheduleTick(fk5, this, 1);
        }
        return super.updateShape(byj1, fp, byj3, bjx, fk5, fk6);
    }
    
    @Override
    public boolean canSurvive(final BlockState byj, final LevelReader bjz, final BlockPos fk) {
        final BlockState byj2 = bjz.getBlockState(fk.below());
        final Block bph6 = byj2.getBlock();
        if (bph6 == this.plant || bph6 == Blocks.END_STONE) {
            return true;
        }
        if (!byj2.isAir()) {
            return false;
        }
        boolean boolean7 = false;
        for (final Direction fp9 : Direction.Plane.HORIZONTAL) {
            final BlockState byj3 = bjz.getBlockState(fk.relative(fp9));
            if (byj3.getBlock() == this.plant) {
                if (boolean7) {
                    return false;
                }
                boolean7 = true;
            }
            else {
                if (!byj3.isAir()) {
                    return false;
                }
                continue;
            }
        }
        return boolean7;
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(ChorusFlowerBlock.AGE);
    }
    
    public static void generatePlant(final LevelAccessor bjx, final BlockPos fk, final Random random, final int integer) {
        bjx.setBlock(fk, ((ChorusPlantBlock)Blocks.CHORUS_PLANT).getStateForPlacement(bjx, fk), 2);
        growTreeRecursive(bjx, fk, random, fk, integer, 0);
    }
    
    private static void growTreeRecursive(final LevelAccessor bjx, final BlockPos fk2, final Random random, final BlockPos fk4, final int integer5, final int integer6) {
        final ChorusPlantBlock bpy7 = (ChorusPlantBlock)Blocks.CHORUS_PLANT;
        int integer7 = random.nextInt(4) + 1;
        if (integer6 == 0) {
            ++integer7;
        }
        for (int integer8 = 0; integer8 < integer7; ++integer8) {
            final BlockPos fk5 = fk2.above(integer8 + 1);
            if (!allNeighborsEmpty(bjx, fk5, null)) {
                return;
            }
            bjx.setBlock(fk5, bpy7.getStateForPlacement(bjx, fk5), 2);
            bjx.setBlock(fk5.below(), bpy7.getStateForPlacement(bjx, fk5.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 fp12 = Direction.Plane.HORIZONTAL.getRandomDirection(random);
                final BlockPos fk6 = fk2.above(integer7).relative(fp12);
                if (Math.abs(fk6.getX() - fk4.getX()) < integer5) {
                    if (Math.abs(fk6.getZ() - fk4.getZ()) < integer5) {
                        if (bjx.isEmptyBlock(fk6) && bjx.isEmptyBlock(fk6.below()) && allNeighborsEmpty(bjx, fk6, fp12.getOpposite())) {
                            boolean9 = true;
                            bjx.setBlock(fk6, bpy7.getStateForPlacement(bjx, fk6), 2);
                            bjx.setBlock(fk6.relative(fp12.getOpposite()), bpy7.getStateForPlacement(bjx, fk6.relative(fp12.getOpposite())), 2);
                            growTreeRecursive(bjx, fk6, random, fk4, integer5, integer6 + 1);
                        }
                    }
                }
            }
        }
        if (!boolean9) {
            bjx.setBlock(fk2.above(integer7), ((AbstractStateHolder<O, BlockState>)Blocks.CHORUS_FLOWER.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)ChorusFlowerBlock.AGE, 5), 2);
        }
    }
    
    @Override
    public void onProjectileHit(final Level bjw, final BlockState byj, final BlockHitResult cvg, final Entity akq) {
        final BlockPos fk6 = cvg.getBlockPos();
        bjw.destroyBlock(fk6, true, akq);
    }
    
    static {
        AGE = BlockStateProperties.AGE_5;
    }
}
