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.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.core.Direction;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.level.LevelReader;
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.properties.BooleanProperty;

public class BubbleColumnBlock extends Block implements BucketPickup {
    public static final BooleanProperty DRAG_DOWN;
    
    public BubbleColumnBlock(final Properties c) {
        super(c);
        this.registerDefaultState(((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, true));
    }
    
    @Override
    public void entityInside(final BlockState byj, final Level bjw, final BlockPos fk, final Entity akq) {
        final BlockState byj2 = bjw.getBlockState(fk.above());
        if (byj2.isAir()) {
            akq.onAboveBubbleCol(byj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN));
            if (!bjw.isClientSide) {
                final ServerLevel xd7 = (ServerLevel)bjw;
                for (int integer8 = 0; integer8 < 2; ++integer8) {
                    xd7.<SimpleParticleType>sendParticles(ParticleTypes.SPLASH, fk.getX() + bjw.random.nextFloat(), fk.getY() + 1, fk.getZ() + bjw.random.nextFloat(), 1, 0.0, 0.0, 0.0, 1.0);
                    xd7.<SimpleParticleType>sendParticles(ParticleTypes.BUBBLE, fk.getX() + bjw.random.nextFloat(), fk.getY() + 1, fk.getZ() + bjw.random.nextFloat(), 1, 0.0, 0.01, 0.0, 0.2);
                }
            }
        }
        else {
            akq.onInsideBubbleColumn(byj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN));
        }
    }
    
    @Override
    public void onPlace(final BlockState byj1, final Level bjw, final BlockPos fk, final BlockState byj4, final boolean boolean5) {
        growColumn(bjw, fk.above(), getDrag(bjw, fk.below()));
    }
    
    @Override
    public void tick(final BlockState byj, final ServerLevel xd, final BlockPos fk, final Random random) {
        growColumn(xd, fk.above(), getDrag(xd, fk));
    }
    
    @Override
    public FluidState getFluidState(final BlockState byj) {
        return Fluids.WATER.getSource(false);
    }
    
    public static void growColumn(final LevelAccessor bjx, final BlockPos fk, final boolean boolean3) {
        if (canExistIn(bjx, fk)) {
            bjx.setBlock(fk, ((AbstractStateHolder<O, BlockState>)Blocks.BUBBLE_COLUMN.defaultBlockState()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, boolean3), 2);
        }
    }
    
    public static boolean canExistIn(final LevelAccessor bjx, final BlockPos fk) {
        final FluidState coj3 = bjx.getFluidState(fk);
        return bjx.getBlockState(fk).getBlock() == Blocks.WATER && coj3.getAmount() >= 8 && coj3.isSource();
    }
    
    private static boolean getDrag(final BlockGetter bjg, final BlockPos fk) {
        final BlockState byj3 = bjg.getBlockState(fk);
        final Block bph4 = byj3.getBlock();
        if (bph4 == Blocks.BUBBLE_COLUMN) {
            return byj3.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN);
        }
        return bph4 != Blocks.SOUL_SAND;
    }
    
    @Override
    public int getTickDelay(final LevelReader bjz) {
        return 5;
    }
    
    @Override
    public void animateTick(final BlockState byj, final Level bjw, final BlockPos fk, final Random random) {
        final double double6 = fk.getX();
        final double double7 = fk.getY();
        final double double8 = fk.getZ();
        if (byj.<Boolean>getValue((Property<Boolean>)BubbleColumnBlock.DRAG_DOWN)) {
            bjw.addAlwaysVisibleParticle(ParticleTypes.CURRENT_DOWN, double6 + 0.5, double7 + 0.8, double8, 0.0, 0.0, 0.0);
            if (random.nextInt(200) == 0) {
                bjw.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 {
            bjw.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, double6 + 0.5, double7, double8 + 0.5, 0.0, 0.04, 0.0);
            bjw.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) {
                bjw.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 byj1, final Direction fp, final BlockState byj3, final LevelAccessor bjx, final BlockPos fk5, final BlockPos fk6) {
        if (!byj1.canSurvive(bjx, fk5)) {
            return Blocks.WATER.defaultBlockState();
        }
        if (fp == Direction.DOWN) {
            bjx.setBlock(fk5, ((AbstractStateHolder<O, BlockState>)Blocks.BUBBLE_COLUMN.defaultBlockState()).<Comparable, Boolean>setValue((Property<Comparable>)BubbleColumnBlock.DRAG_DOWN, getDrag(bjx, fk6)), 2);
        }
        else if (fp == Direction.UP && byj3.getBlock() != Blocks.BUBBLE_COLUMN && canExistIn(bjx, fk6)) {
            bjx.getBlockTicks().scheduleTick(fk5, this, this.getTickDelay(bjx));
        }
        bjx.getLiquidTicks().scheduleTick(fk5, Fluids.WATER, Fluids.WATER.getTickDelay(bjx));
        return super.updateShape(byj1, fp, byj3, bjx, fk5, fk6);
    }
    
    @Override
    public boolean canSurvive(final BlockState byj, final LevelReader bjz, final BlockPos fk) {
        final Block bph5 = bjz.getBlockState(fk.below()).getBlock();
        return bph5 == Blocks.BUBBLE_COLUMN || bph5 == Blocks.MAGMA_BLOCK || bph5 == Blocks.SOUL_SAND;
    }
    
    @Override
    public VoxelShape getShape(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final CollisionContext cvq) {
        return Shapes.empty();
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState byj) {
        return RenderShape.INVISIBLE;
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(BubbleColumnBlock.DRAG_DOWN);
    }
    
    @Override
    public Fluid takeLiquid(final LevelAccessor bjx, final BlockPos fk, final BlockState byj) {
        bjx.setBlock(fk, Blocks.AIR.defaultBlockState(), 11);
        return Fluids.WATER;
    }
    
    static {
        DRAG_DOWN = BlockStateProperties.DRAG;
    }
}
