package net.minecraft.world.level.material;

import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.tags.FluidTags;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.LevelAccessor;
import javax.annotation.Nullable;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.Item;

public abstract class WaterFluid extends FlowingFluid {
    @Override
    public Fluid getFlowing() {
        return Fluids.FLOWING_WATER;
    }
    
    @Override
    public Fluid getSource() {
        return Fluids.WATER;
    }
    
    @Override
    public Item getBucket() {
        return Items.WATER_BUCKET;
    }
    
    public void animateTick(final Level bjw, final BlockPos fk, final FluidState coj, final Random random) {
        if (!coj.isSource() && !coj.<Boolean>getValue((Property<Boolean>)WaterFluid.FALLING)) {
            if (random.nextInt(64) == 0) {
                bjw.playLocalSound(fk.getX() + 0.5, fk.getY() + 0.5, fk.getZ() + 0.5, SoundEvents.WATER_AMBIENT, SoundSource.BLOCKS, random.nextFloat() * 0.25f + 0.75f, random.nextFloat() + 0.5f, false);
            }
        }
        else if (random.nextInt(10) == 0) {
            bjw.addParticle(ParticleTypes.UNDERWATER, fk.getX() + (double)random.nextFloat(), fk.getY() + (double)random.nextFloat(), fk.getZ() + (double)random.nextFloat(), 0.0, 0.0, 0.0);
        }
    }
    
    @Nullable
    public ParticleOptions getDripParticle() {
        return ParticleTypes.DRIPPING_WATER;
    }
    
    @Override
    protected boolean canConvertToSource() {
        return true;
    }
    
    @Override
    protected void beforeDestroyingBlock(final LevelAccessor bjx, final BlockPos fk, final BlockState byj) {
        final BlockEntity bwl5 = byj.getBlock().isEntityBlock() ? bjx.getBlockEntity(fk) : null;
        Block.dropResources(byj, bjx.getLevel(), fk, bwl5);
    }
    
    public int getSlopeFindDistance(final LevelReader bjz) {
        return 4;
    }
    
    public BlockState createLegacyBlock(final FluidState coj) {
        return ((AbstractStateHolder<O, BlockState>)Blocks.WATER.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)LiquidBlock.LEVEL, FlowingFluid.getLegacyLevel(coj));
    }
    
    @Override
    public boolean isSame(final Fluid coi) {
        return coi == Fluids.WATER || coi == Fluids.FLOWING_WATER;
    }
    
    public int getDropOff(final LevelReader bjz) {
        return 1;
    }
    
    @Override
    public int getTickDelay(final LevelReader bjz) {
        return 5;
    }
    
    public boolean canBeReplacedWith(final FluidState coj, final BlockGetter bjg, final BlockPos fk, final Fluid coi, final Direction fp) {
        return fp == Direction.DOWN && !coi.is(FluidTags.WATER);
    }
    
    @Override
    protected float getExplosionResistance() {
        return 100.0f;
    }
    
    public static class Source extends WaterFluid {
        @Override
        public int getAmount(final FluidState coj) {
            return 8;
        }
        
        @Override
        public boolean isSource(final FluidState coj) {
            return true;
        }
    }
    
    public static class Flowing extends WaterFluid {
        @Override
        protected void createFluidStateDefinition(final StateDefinition.Builder<Fluid, FluidState> a) {
            super.createFluidStateDefinition(a);
            a.add(Flowing.LEVEL);
        }
        
        @Override
        public int getAmount(final FluidState coj) {
            return coj.<Integer>getValue((Property<Integer>)Flowing.LEVEL);
        }
        
        @Override
        public boolean isSource(final FluidState coj) {
            return false;
        }
    }
}
