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.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.LevelAccessor;
import javax.annotation.Nullable;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.GameRules;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.level.BlockGetter;
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 LavaFluid extends FlowingFluid {
    @Override
    public Fluid getFlowing() {
        return Fluids.FLOWING_LAVA;
    }
    
    @Override
    public Fluid getSource() {
        return Fluids.LAVA;
    }
    
    @Override
    public Item getBucket() {
        return Items.LAVA_BUCKET;
    }
    
    public void animateTick(final Level bjw, final BlockPos fk, final FluidState coj, final Random random) {
        final BlockPos fk2 = fk.above();
        if (bjw.getBlockState(fk2).isAir() && !bjw.getBlockState(fk2).isSolidRender(bjw, fk2)) {
            if (random.nextInt(100) == 0) {
                final double double7 = fk.getX() + random.nextFloat();
                final double double8 = fk.getY() + 1;
                final double double9 = fk.getZ() + random.nextFloat();
                bjw.addParticle(ParticleTypes.LAVA, double7, double8, double9, 0.0, 0.0, 0.0);
                bjw.playLocalSound(double7, double8, double9, SoundEvents.LAVA_POP, SoundSource.BLOCKS, 0.2f + random.nextFloat() * 0.2f, 0.9f + random.nextFloat() * 0.15f, false);
            }
            if (random.nextInt(200) == 0) {
                bjw.playLocalSound(fk.getX(), fk.getY(), fk.getZ(), SoundEvents.LAVA_AMBIENT, SoundSource.BLOCKS, 0.2f + random.nextFloat() * 0.2f, 0.9f + random.nextFloat() * 0.15f, false);
            }
        }
    }
    
    public void randomTick(final Level bjw, final BlockPos fk, final FluidState coj, final Random random) {
        if (!bjw.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
            return;
        }
        final int integer6 = random.nextInt(3);
        if (integer6 > 0) {
            BlockPos fk2 = fk;
            for (int integer7 = 0; integer7 < integer6; ++integer7) {
                fk2 = fk2.offset(random.nextInt(3) - 1, 1, random.nextInt(3) - 1);
                if (!bjw.isLoaded(fk2)) {
                    return;
                }
                final BlockState byj9 = bjw.getBlockState(fk2);
                if (byj9.isAir()) {
                    if (this.hasFlammableNeighbours(bjw, fk2)) {
                        bjw.setBlockAndUpdate(fk2, Blocks.FIRE.defaultBlockState());
                        return;
                    }
                }
                else if (byj9.getMaterial().blocksMotion()) {
                    return;
                }
            }
        }
        else {
            for (int integer8 = 0; integer8 < 3; ++integer8) {
                final BlockPos fk3 = fk.offset(random.nextInt(3) - 1, 0, random.nextInt(3) - 1);
                if (!bjw.isLoaded(fk3)) {
                    return;
                }
                if (bjw.isEmptyBlock(fk3.above()) && this.isFlammable(bjw, fk3)) {
                    bjw.setBlockAndUpdate(fk3.above(), Blocks.FIRE.defaultBlockState());
                }
            }
        }
    }
    
    private boolean hasFlammableNeighbours(final LevelReader bjz, final BlockPos fk) {
        for (final Direction fp7 : Direction.values()) {
            if (this.isFlammable(bjz, fk.relative(fp7))) {
                return true;
            }
        }
        return false;
    }
    
    private boolean isFlammable(final LevelReader bjz, final BlockPos fk) {
        return (fk.getY() < 0 || fk.getY() >= 256 || bjz.hasChunkAt(fk)) && bjz.getBlockState(fk).getMaterial().isFlammable();
    }
    
    @Nullable
    public ParticleOptions getDripParticle() {
        return ParticleTypes.DRIPPING_LAVA;
    }
    
    @Override
    protected void beforeDestroyingBlock(final LevelAccessor bjx, final BlockPos fk, final BlockState byj) {
        this.fizz(bjx, fk);
    }
    
    public int getSlopeFindDistance(final LevelReader bjz) {
        return bjz.getDimension().isUltraWarm() ? 4 : 2;
    }
    
    public BlockState createLegacyBlock(final FluidState coj) {
        return ((AbstractStateHolder<O, BlockState>)Blocks.LAVA.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)LiquidBlock.LEVEL, FlowingFluid.getLegacyLevel(coj));
    }
    
    @Override
    public boolean isSame(final Fluid coi) {
        return coi == Fluids.LAVA || coi == Fluids.FLOWING_LAVA;
    }
    
    public int getDropOff(final LevelReader bjz) {
        return bjz.getDimension().isUltraWarm() ? 1 : 2;
    }
    
    public boolean canBeReplacedWith(final FluidState coj, final BlockGetter bjg, final BlockPos fk, final Fluid coi, final Direction fp) {
        return coj.getHeight(bjg, fk) >= 0.44444445f && coi.is(FluidTags.WATER);
    }
    
    @Override
    public int getTickDelay(final LevelReader bjz) {
        return bjz.getDimension().isHasCeiling() ? 10 : 30;
    }
    
    public int getSpreadDelay(final Level bjw, final BlockPos fk, final FluidState coj3, final FluidState coj4) {
        int integer6 = this.getTickDelay(bjw);
        if (!coj3.isEmpty() && !coj4.isEmpty() && !coj3.<Boolean>getValue((Property<Boolean>)LavaFluid.FALLING) && !coj4.<Boolean>getValue((Property<Boolean>)LavaFluid.FALLING) && coj4.getHeight(bjw, fk) > coj3.getHeight(bjw, fk) && bjw.getRandom().nextInt(4) != 0) {
            integer6 *= 4;
        }
        return integer6;
    }
    
    private void fizz(final LevelAccessor bjx, final BlockPos fk) {
        bjx.levelEvent(1501, fk, 0);
    }
    
    @Override
    protected boolean canConvertToSource() {
        return false;
    }
    
    @Override
    protected void spreadTo(final LevelAccessor bjx, final BlockPos fk, final BlockState byj, final Direction fp, final FluidState coj) {
        if (fp == Direction.DOWN) {
            final FluidState coj2 = bjx.getFluidState(fk);
            if (this.is(FluidTags.LAVA) && coj2.is(FluidTags.WATER)) {
                if (byj.getBlock() instanceof LiquidBlock) {
                    bjx.setBlock(fk, Blocks.STONE.defaultBlockState(), 3);
                }
                this.fizz(bjx, fk);
                return;
            }
        }
        super.spreadTo(bjx, fk, byj, fp, coj);
    }
    
    @Override
    protected boolean isRandomlyTicking() {
        return true;
    }
    
    @Override
    protected float getExplosionResistance() {
        return 100.0f;
    }
    
    public static class Source extends LavaFluid {
        @Override
        public int getAmount(final FluidState coj) {
            return 8;
        }
        
        @Override
        public boolean isSource(final FluidState coj) {
            return true;
        }
    }
    
    public static class Flowing extends LavaFluid {
        @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;
        }
    }
}
