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.level.material.Fluids;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.phys.shapes.CollisionContext;
import java.util.Collections;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.core.Direction;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
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 com.google.common.collect.Lists;
import net.minecraft.world.level.material.FluidState;
import java.util.List;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.block.state.properties.IntegerProperty;

public class LiquidBlock extends Block implements BucketPickup {
    public static final IntegerProperty LEVEL;
    protected final FlowingFluid fluid;
    private final List<FluidState> stateCache;
    
    protected LiquidBlock(final FlowingFluid coh, final Properties c) {
        super(c);
        this.fluid = coh;
        (this.stateCache = Lists.newArrayList()).add(coh.getSource(false));
        for (int integer4 = 1; integer4 < 8; ++integer4) {
            this.stateCache.add(coh.getFlowing(8 - integer4, false));
        }
        this.stateCache.add(coh.getFlowing(8, true));
        this.registerDefaultState(((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Integer>setValue((Property<Comparable>)LiquidBlock.LEVEL, 0));
    }
    
    @Override
    public void randomTick(final BlockState byj, final ServerLevel xd, final BlockPos fk, final Random random) {
        xd.getFluidState(fk).randomTick(xd, fk, random);
    }
    
    @Override
    public boolean propagatesSkylightDown(final BlockState byj, final BlockGetter bjg, final BlockPos fk) {
        return false;
    }
    
    @Override
    public boolean isPathfindable(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final PathComputationType cqr) {
        return !this.fluid.is(FluidTags.LAVA);
    }
    
    @Override
    public FluidState getFluidState(final BlockState byj) {
        final int integer3 = byj.<Integer>getValue((Property<Integer>)LiquidBlock.LEVEL);
        return this.stateCache.get(Math.min(integer3, 8));
    }
    
    @Override
    public boolean skipRendering(final BlockState byj1, final BlockState byj2, final Direction fp) {
        return byj2.getFluidState().getType().isSame(this.fluid);
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState byj) {
        return RenderShape.INVISIBLE;
    }
    
    @Override
    public List<ItemStack> getDrops(final BlockState byj, final LootContext.Builder a) {
        return Collections.<ItemStack>emptyList();
    }
    
    @Override
    public VoxelShape getShape(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final CollisionContext cvq) {
        return Shapes.empty();
    }
    
    @Override
    public int getTickDelay(final LevelReader bjz) {
        return this.fluid.getTickDelay(bjz);
    }
    
    @Override
    public void onPlace(final BlockState byj1, final Level bjw, final BlockPos fk, final BlockState byj4, final boolean boolean5) {
        if (this.shouldSpreadLiquid(bjw, fk, byj1)) {
            bjw.getLiquidTicks().scheduleTick(fk, byj1.getFluidState().getType(), this.getTickDelay(bjw));
        }
    }
    
    @Override
    public BlockState updateShape(final BlockState byj1, final Direction fp, final BlockState byj3, final LevelAccessor bjx, final BlockPos fk5, final BlockPos fk6) {
        if (byj1.getFluidState().isSource() || byj3.getFluidState().isSource()) {
            bjx.getLiquidTicks().scheduleTick(fk5, byj1.getFluidState().getType(), this.getTickDelay(bjx));
        }
        return super.updateShape(byj1, fp, byj3, bjx, fk5, fk6);
    }
    
    @Override
    public void neighborChanged(final BlockState byj, final Level bjw, final BlockPos fk3, final Block bph, final BlockPos fk5, final boolean boolean6) {
        if (this.shouldSpreadLiquid(bjw, fk3, byj)) {
            bjw.getLiquidTicks().scheduleTick(fk3, byj.getFluidState().getType(), this.getTickDelay(bjw));
        }
    }
    
    public boolean shouldSpreadLiquid(final Level bjw, final BlockPos fk, final BlockState byj) {
        if (this.fluid.is(FluidTags.LAVA)) {
            boolean boolean5 = false;
            for (final Direction fp9 : Direction.values()) {
                if (fp9 != Direction.DOWN && bjw.getFluidState(fk.relative(fp9)).is(FluidTags.WATER)) {
                    boolean5 = true;
                    break;
                }
            }
            if (boolean5) {
                final FluidState coj6 = bjw.getFluidState(fk);
                if (coj6.isSource()) {
                    bjw.setBlockAndUpdate(fk, Blocks.OBSIDIAN.defaultBlockState());
                    this.fizz(bjw, fk);
                    return false;
                }
                if (coj6.getHeight(bjw, fk) >= 0.44444445f) {
                    bjw.setBlockAndUpdate(fk, Blocks.COBBLESTONE.defaultBlockState());
                    this.fizz(bjw, fk);
                    return false;
                }
            }
        }
        return true;
    }
    
    private void fizz(final LevelAccessor bjx, final BlockPos fk) {
        bjx.levelEvent(1501, fk, 0);
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(LiquidBlock.LEVEL);
    }
    
    @Override
    public Fluid takeLiquid(final LevelAccessor bjx, final BlockPos fk, final BlockState byj) {
        if (byj.<Integer>getValue((Property<Integer>)LiquidBlock.LEVEL) == 0) {
            bjx.setBlock(fk, Blocks.AIR.defaultBlockState(), 11);
            return this.fluid;
        }
        return Fluids.EMPTY;
    }
    
    @Override
    public void entityInside(final BlockState byj, final Level bjw, final BlockPos fk, final Entity akq) {
        if (this.fluid.is(FluidTags.LAVA)) {
            akq.setInLava();
        }
    }
    
    static {
        LEVEL = BlockStateProperties.LEVEL;
    }
}
