package net.minecraft.world.level.material;

import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.tags.Tag;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.phys.Vec3;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import javax.annotation.Nullable;
import net.minecraft.core.particles.ParticleOptions;
import java.util.Random;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.core.IdMapper;

public abstract class Fluid {
    public static final IdMapper<FluidState> FLUID_STATE_REGISTRY;
    protected final StateDefinition<Fluid, FluidState> stateDefinition;
    private FluidState defaultFluidState;
    
    protected Fluid() {
        final StateDefinition.Builder<Fluid, FluidState> a2 = new StateDefinition.Builder<Fluid, FluidState>(this);
        this.createFluidStateDefinition(a2);
        this.stateDefinition = a2.create(Fluid::defaultFluidState, FluidState::new);
        this.registerDefaultState(this.stateDefinition.any());
    }
    
    protected void createFluidStateDefinition(final StateDefinition.Builder<Fluid, FluidState> a) {
    }
    
    public StateDefinition<Fluid, FluidState> getStateDefinition() {
        return this.stateDefinition;
    }
    
    protected final void registerDefaultState(final FluidState cxa) {
        this.defaultFluidState = cxa;
    }
    
    public final FluidState defaultFluidState() {
        return this.defaultFluidState;
    }
    
    public abstract Item getBucket();
    
    protected void animateTick(final Level bqb, final BlockPos fu, final FluidState cxa, final Random random) {
    }
    
    protected void tick(final Level bqb, final BlockPos fu, final FluidState cxa) {
    }
    
    protected void randomTick(final Level bqb, final BlockPos fu, final FluidState cxa, final Random random) {
    }
    
    @Nullable
    protected ParticleOptions getDripParticle() {
        return null;
    }
    
    protected abstract boolean canBeReplacedWith(final FluidState cxa, final BlockGetter bpg, final BlockPos fu, final Fluid cwz, final Direction fz);
    
    protected abstract Vec3 getFlow(final BlockGetter bpg, final BlockPos fu, final FluidState cxa);
    
    public abstract int getTickDelay(final LevelReader bqd);
    
    protected boolean isRandomlyTicking() {
        return false;
    }
    
    protected boolean isEmpty() {
        return false;
    }
    
    protected abstract float getExplosionResistance();
    
    public abstract float getHeight(final FluidState cxa, final BlockGetter bpg, final BlockPos fu);
    
    public abstract float getOwnHeight(final FluidState cxa);
    
    protected abstract BlockState createLegacyBlock(final FluidState cxa);
    
    public abstract boolean isSource(final FluidState cxa);
    
    public abstract int getAmount(final FluidState cxa);
    
    public boolean isSame(final Fluid cwz) {
        return cwz == this;
    }
    
    public boolean is(final Tag<Fluid> adf) {
        return adf.contains(this);
    }
    
    public abstract VoxelShape getShape(final FluidState cxa, final BlockGetter bpg, final BlockPos fu);
    
    static {
        FLUID_STATE_REGISTRY = new IdMapper<FluidState>();
    }
}
