package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.tags.Tag;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import java.util.Random;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import javax.annotation.Nullable;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.item.BlockPlaceContext;
import net.minecraft.world.Containers;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Entity;
import java.util.Optional;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.stats.Stats;
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.shapes.VoxelShape;

public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {
    protected static final VoxelShape SHAPE;
    public static final BooleanProperty LIT;
    public static final BooleanProperty SIGNAL_FIRE;
    public static final BooleanProperty WATERLOGGED;
    public static final DirectionProperty FACING;
    private static final VoxelShape VIRTUAL_FENCE_POST;
    private final boolean spawnParticles;
    private final int fireDamage;
    
    public CampfireBlock(final boolean boolean1, final int integer, final Properties c) {
        super(c);
        this.spawnParticles = boolean1;
        this.fireDamage = integer;
        this.registerDefaultState((((((StateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)CampfireBlock.LIT, true)).setValue((Property<Comparable>)CampfireBlock.SIGNAL_FIRE, false)).setValue((Property<Comparable>)CampfireBlock.WATERLOGGED, false)).<Comparable, Direction>setValue((Property<Comparable>)CampfireBlock.FACING, Direction.NORTH));
    }
    
    @Override
    public InteractionResult use(final BlockState cfj, final Level bqb, final BlockPos fu, final Player bec, final InteractionHand anf, final BlockHitResult deh) {
        final BlockEntity cdl8 = bqb.getBlockEntity(fu);
        if (cdl8 instanceof CampfireBlockEntity) {
            final CampfireBlockEntity cdo9 = (CampfireBlockEntity)cdl8;
            final ItemStack bki10 = bec.getItemInHand(anf);
            final Optional<CampfireCookingRecipe> optional11 = cdo9.getCookableRecipe(bki10);
            if (optional11.isPresent()) {
                if (!bqb.isClientSide && cdo9.placeFood(bec.abilities.instabuild ? bki10.copy() : bki10, optional11.get().getCookingTime())) {
                    bec.awardStat(Stats.INTERACT_WITH_CAMPFIRE);
                    return InteractionResult.SUCCESS;
                }
                return InteractionResult.CONSUME;
            }
        }
        return InteractionResult.PASS;
    }
    
    @Override
    public void entityInside(final BlockState cfj, final Level bqb, final BlockPos fu, final Entity aom) {
        if (!aom.fireImmune() && cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT) && aom instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity)aom)) {
            aom.hurt(DamageSource.IN_FIRE, (float)this.fireDamage);
        }
        super.entityInside(cfj, bqb, fu, aom);
    }
    
    @Override
    public void onRemove(final BlockState cfj1, final Level bqb, final BlockPos fu, final BlockState cfj4, final boolean boolean5) {
        if (cfj1.is(cfj4.getBlock())) {
            return;
        }
        final BlockEntity cdl7 = bqb.getBlockEntity(fu);
        if (cdl7 instanceof CampfireBlockEntity) {
            Containers.dropContents(bqb, fu, ((CampfireBlockEntity)cdl7).getItems());
        }
        super.onRemove(cfj1, bqb, fu, cfj4, boolean5);
    }
    
    @Nullable
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bin) {
        final LevelAccessor bqc3 = bin.getLevel();
        final BlockPos fu4 = bin.getClickedPos();
        final boolean boolean5 = bqc3.getFluidState(fu4).getType() == Fluids.WATER;
        return (((((StateHolder<O, BlockState>)this.defaultBlockState()).setValue((Property<Comparable>)CampfireBlock.WATERLOGGED, boolean5)).setValue((Property<Comparable>)CampfireBlock.SIGNAL_FIRE, this.isSmokeSource(bqc3.getBlockState(fu4.below())))).setValue((Property<Comparable>)CampfireBlock.LIT, !boolean5)).<Comparable, Direction>setValue((Property<Comparable>)CampfireBlock.FACING, bin.getHorizontalDirection());
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (cfj1.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
            bqc.getLiquidTicks().scheduleTick(fu5, Fluids.WATER, Fluids.WATER.getTickDelay(bqc));
        }
        if (fz == Direction.DOWN) {
            return ((StateHolder<O, BlockState>)cfj1).<Comparable, Boolean>setValue((Property<Comparable>)CampfireBlock.SIGNAL_FIRE, this.isSmokeSource(cfj3));
        }
        return super.updateShape(cfj1, fz, cfj3, bqc, fu5, fu6);
    }
    
    private boolean isSmokeSource(final BlockState cfj) {
        return cfj.is(Blocks.HAY_BLOCK);
    }
    
    @Override
    public VoxelShape getShape(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final CollisionContext der) {
        return CampfireBlock.SHAPE;
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState cfj) {
        return RenderShape.MODEL;
    }
    
    @Override
    public void animateTick(final BlockState cfj, final Level bqb, final BlockPos fu, final Random random) {
        if (!cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT)) {
            return;
        }
        if (random.nextInt(10) == 0) {
            bqb.playLocalSound(fu.getX() + 0.5, fu.getY() + 0.5, fu.getZ() + 0.5, SoundEvents.CAMPFIRE_CRACKLE, SoundSource.BLOCKS, 0.5f + random.nextFloat(), random.nextFloat() * 0.7f + 0.6f, false);
        }
        if (this.spawnParticles && random.nextInt(5) == 0) {
            for (int integer6 = 0; integer6 < random.nextInt(1) + 1; ++integer6) {
                bqb.addParticle(ParticleTypes.LAVA, fu.getX() + 0.5, fu.getY() + 0.5, fu.getZ() + 0.5, random.nextFloat() / 2.0f, 5.0E-5, random.nextFloat() / 2.0f);
            }
        }
    }
    
    public static void dowse(final LevelAccessor bqc, final BlockPos fu, final BlockState cfj) {
        if (bqc.isClientSide()) {
            for (int integer4 = 0; integer4 < 20; ++integer4) {
                makeParticles(bqc.getLevel(), fu, cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.SIGNAL_FIRE), true);
            }
        }
        final BlockEntity cdl4 = bqc.getBlockEntity(fu);
        if (cdl4 instanceof CampfireBlockEntity) {
            ((CampfireBlockEntity)cdl4).dowse();
        }
    }
    
    @Override
    public boolean placeLiquid(final LevelAccessor bqc, final BlockPos fu, final BlockState cfj, final FluidState cxa) {
        if (!cfj.<Boolean>getValue((Property<Boolean>)BlockStateProperties.WATERLOGGED) && cxa.getType() == Fluids.WATER) {
            final boolean boolean6 = cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT);
            if (boolean6) {
                if (!bqc.isClientSide()) {
                    bqc.playSound(null, fu, SoundEvents.GENERIC_EXTINGUISH_FIRE, SoundSource.BLOCKS, 1.0f, 1.0f);
                }
                dowse(bqc, fu, cfj);
            }
            bqc.setBlock(fu, (((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)CampfireBlock.WATERLOGGED, true)).<Comparable, Boolean>setValue((Property<Comparable>)CampfireBlock.LIT, false), 3);
            bqc.getLiquidTicks().scheduleTick(fu, cxa.getType(), cxa.getType().getTickDelay(bqc));
            return true;
        }
        return false;
    }
    
    @Override
    public void onProjectileHit(final Level bqb, final BlockState cfj, final BlockHitResult deh, final Projectile bes) {
        if (!bqb.isClientSide && bes.isOnFire()) {
            final Entity aom6 = bes.getOwner();
            final boolean boolean7 = aom6 == null || aom6 instanceof Player || bqb.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
            if (boolean7 && !cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT) && !cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
                final BlockPos fu8 = deh.getBlockPos();
                bqb.setBlock(fu8, ((StateHolder<O, BlockState>)cfj).<Comparable, Boolean>setValue((Property<Comparable>)BlockStateProperties.LIT, true), 11);
            }
        }
    }
    
    public static void makeParticles(final Level bqb, final BlockPos fu, final boolean boolean3, final boolean boolean4) {
        final Random random5 = bqb.getRandom();
        final SimpleParticleType hi6 = boolean3 ? ParticleTypes.CAMPFIRE_SIGNAL_SMOKE : ParticleTypes.CAMPFIRE_COSY_SMOKE;
        bqb.addAlwaysVisibleParticle(hi6, true, fu.getX() + 0.5 + random5.nextDouble() / 3.0 * (random5.nextBoolean() ? 1 : -1), fu.getY() + random5.nextDouble() + random5.nextDouble(), fu.getZ() + 0.5 + random5.nextDouble() / 3.0 * (random5.nextBoolean() ? 1 : -1), 0.0, 0.07, 0.0);
        if (boolean4) {
            bqb.addParticle(ParticleTypes.SMOKE, fu.getX() + 0.25 + random5.nextDouble() / 2.0 * (random5.nextBoolean() ? 1 : -1), fu.getY() + 0.4, fu.getZ() + 0.25 + random5.nextDouble() / 2.0 * (random5.nextBoolean() ? 1 : -1), 0.0, 0.005, 0.0);
        }
    }
    
    public static boolean isSmokeyPos(final Level bqb, final BlockPos fu) {
        for (int integer3 = 1; integer3 <= 5; ++integer3) {
            final BlockPos fu2 = fu.below(integer3);
            final BlockState cfj5 = bqb.getBlockState(fu2);
            if (isLitCampfire(cfj5)) {
                return true;
            }
            final boolean boolean6 = Shapes.joinIsNotEmpty(CampfireBlock.VIRTUAL_FENCE_POST, cfj5.getCollisionShape(bqb, fu, CollisionContext.empty()), BooleanOp.AND);
            if (boolean6) {
                final BlockState cfj6 = bqb.getBlockState(fu2.below());
                return isLitCampfire(cfj6);
            }
        }
        return false;
    }
    
    public static boolean isLitCampfire(final BlockState cfj) {
        return cfj.<Comparable>hasProperty((Property<Comparable>)CampfireBlock.LIT) && cfj.is(BlockTags.CAMPFIRES) && cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT);
    }
    
    @Override
    public FluidState getFluidState(final BlockState cfj) {
        if (cfj.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
            return Fluids.WATER.getSource(false);
        }
        return super.getFluidState(cfj);
    }
    
    @Override
    public BlockState rotate(final BlockState cfj, final Rotation cap) {
        return ((StateHolder<O, BlockState>)cfj).<Comparable, Direction>setValue((Property<Comparable>)CampfireBlock.FACING, cap.rotate(cfj.<Direction>getValue((Property<Direction>)CampfireBlock.FACING)));
    }
    
    @Override
    public BlockState mirror(final BlockState cfj, final Mirror bzj) {
        return cfj.rotate(bzj.getRotation(cfj.<Direction>getValue((Property<Direction>)CampfireBlock.FACING)));
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(CampfireBlock.LIT, CampfireBlock.SIGNAL_FIRE, CampfireBlock.WATERLOGGED, CampfireBlock.FACING);
    }
    
    @Override
    public BlockEntity newBlockEntity(final BlockGetter bpg) {
        return new CampfireBlockEntity();
    }
    
    @Override
    public boolean isPathfindable(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final PathComputationType czg) {
        return false;
    }
    
    public static boolean canLight(final BlockState cfj) {
        return cfj.is(BlockTags.CAMPFIRES, a -> a.<Comparable>hasProperty((Property<Comparable>)BlockStateProperties.WATERLOGGED) && a.<Comparable>hasProperty((Property<Comparable>)BlockStateProperties.LIT)) && !cfj.<Boolean>getValue((Property<Boolean>)BlockStateProperties.WATERLOGGED) && !cfj.<Boolean>getValue((Property<Boolean>)BlockStateProperties.LIT);
    }
    
    static {
        SHAPE = Block.box(0.0, 0.0, 0.0, 16.0, 7.0, 16.0);
        LIT = BlockStateProperties.LIT;
        SIGNAL_FIRE = BlockStateProperties.SIGNAL_FIRE;
        WATERLOGGED = BlockStateProperties.WATERLOGGED;
        FACING = BlockStateProperties.HORIZONTAL_FACING;
        VIRTUAL_FENCE_POST = Block.box(6.0, 0.0, 6.0, 10.0, 16.0, 10.0);
    }
}
