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.level.material.Fluid;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.level.LevelReader;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.FluidState;
import java.util.Random;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
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.BooleanProperty;

public class BubbleColumnBlock extends Block implements BucketPickup {
    public static final BooleanProperty DRAG_DOWN;
    
    public BubbleColumnBlock(final Properties c) {
        super(c);
        this.registerDefaultState(((StateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, true));
    }
    
    @Override
    public void entityInside(final BlockState cfj, final Level bqb, final BlockPos fu, final Entity aom) {
        final BlockState cfj2 = bqb.getBlockState(fu.above());
        if (cfj2.isAir()) {
            aom.onAboveBubbleCol(cfj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN));
            if (!bqb.isClientSide) {
                final ServerLevel zd7 = (ServerLevel)bqb;
                for (int integer8 = 0; integer8 < 2; ++integer8) {
                    zd7.<SimpleParticleType>sendParticles(ParticleTypes.SPLASH, fu.getX() + bqb.random.nextDouble(), fu.getY() + 1, fu.getZ() + bqb.random.nextDouble(), 1, 0.0, 0.0, 0.0, 1.0);
                    zd7.<SimpleParticleType>sendParticles(ParticleTypes.BUBBLE, fu.getX() + bqb.random.nextDouble(), fu.getY() + 1, fu.getZ() + bqb.random.nextDouble(), 1, 0.0, 0.01, 0.0, 0.2);
                }
            }
        }
        else {
            aom.onInsideBubbleColumn(cfj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN));
        }
    }
    
    @Override
    public void onPlace(final BlockState cfj1, final Level bqb, final BlockPos fu, final BlockState cfj4, final boolean boolean5) {
        growColumn(bqb, fu.above(), getDrag(bqb, fu.below()));
    }
    
    @Override
    public void tick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        growColumn(zd, fu.above(), getDrag(zd, fu));
    }
    
    @Override
    public FluidState getFluidState(final BlockState cfj) {
        return Fluids.WATER.getSource(false);
    }
    
    public static void growColumn(final LevelAccessor bqc, final BlockPos fu, final boolean boolean3) {
        if (canExistIn(bqc, fu)) {
            bqc.setBlock(fu, ((StateHolder<O, BlockState>)Blocks.BUBBLE_COLUMN.defaultBlockState()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, boolean3), 2);
        }
    }
    
    public static boolean canExistIn(final LevelAccessor bqc, final BlockPos fu) {
        final FluidState cxa3 = bqc.getFluidState(fu);
        return bqc.getBlockState(fu).is(Blocks.WATER) && cxa3.getAmount() >= 8 && cxa3.isSource();
    }
    
    private static boolean getDrag(final BlockGetter bpg, final BlockPos fu) {
        final BlockState cfj3 = bpg.getBlockState(fu);
        if (cfj3.is(Blocks.BUBBLE_COLUMN)) {
            return cfj3.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN);
        }
        return !cfj3.is(Blocks.SOUL_SAND);
    }
    
    @Override
    public void animateTick(final BlockState cfj, final Level bqb, final BlockPos fu, final Random random) {
        final double double6 = fu.getX();
        final double double7 = fu.getY();
        final double double8 = fu.getZ();
        if (cfj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN)) {
            bqb.addAlwaysVisibleParticle(ParticleTypes.CURRENT_DOWN, double6 + 0.5, double7 + 0.8, double8, 0.0, 0.0, 0.0);
            if (random.nextInt(200) == 0) {
                bqb.playLocalSound(double6, double7, double8, SoundEvents.BUBBLE_COLUMN_WHIRLPOOL_AMBIENT, SoundSource.BLOCKS, 0.2f + random.nextFloat() * 0.2f, 0.9f + random.nextFloat() * 0.15f, false);
            }
        }
        else {
            bqb.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, double6 + 0.5, double7, double8 + 0.5, 0.0, 0.04, 0.0);
            bqb.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, double6 + random.nextFloat(), double7 + random.nextFloat(), double8 + random.nextFloat(), 0.0, 0.04, 0.0);
            if (random.nextInt(200) == 0) {
                bqb.playLocalSound(double6, double7, double8, SoundEvents.BUBBLE_COLUMN_UPWARDS_AMBIENT, SoundSource.BLOCKS, 0.2f + random.nextFloat() * 0.2f, 0.9f + random.nextFloat() * 0.15f, false);
            }
        }
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (!cfj1.canSurvive(bqc, fu5)) {
            return Blocks.WATER.defaultBlockState();
        }
        if (fz == Direction.DOWN) {
            bqc.setBlock(fu5, ((StateHolder<O, BlockState>)Blocks.BUBBLE_COLUMN.defaultBlockState()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, getDrag(bqc, fu6)), 2);
        }
        else if (fz == Direction.UP && !cfj3.is(Blocks.BUBBLE_COLUMN) && canExistIn(bqc, fu6)) {
            bqc.getBlockTicks().scheduleTick(fu5, this, 5);
        }
        bqc.getLiquidTicks().scheduleTick(fu5, Fluids.WATER, Fluids.WATER.getTickDelay(bqc));
        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());
        return cfj2.is(Blocks.BUBBLE_COLUMN) || cfj2.is(Blocks.MAGMA_BLOCK) || cfj2.is(Blocks.SOUL_SAND);
    }
    
    @Override
    public VoxelShape getShape(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final CollisionContext der) {
        return Shapes.empty();
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState cfj) {
        return RenderShape.INVISIBLE;
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(BubbleColumnBlock.DRAG_DOWN);
    }
    
    @Override
    public Fluid takeLiquid(final LevelAccessor bqc, final BlockPos fu, final BlockState cfj) {
        bqc.setBlock(fu, Blocks.AIR.defaultBlockState(), 11);
        return Fluids.WATER;
    }
    
    static {
        DRAG_DOWN = BlockStateProperties.DRAG;
    }
}
