package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.block.state.StateDefinition;
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.AbstractArrow;
import net.minecraft.world.entity.projectile.Fireball;
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.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;
    
    public CampfireBlock(final Properties c) {
        super(c);
        this.registerDefaultState((((((AbstractStateHolder<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 byj, final Level bjw, final BlockPos fk, final Player ayj, final InteractionHand ajk, final BlockHitResult cvg) {
        if (byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT)) {
            final BlockEntity bwl8 = bjw.getBlockEntity(fk);
            if (bwl8 instanceof CampfireBlockEntity) {
                final CampfireBlockEntity bwo9 = (CampfireBlockEntity)bwl8;
                final ItemStack ben10 = ayj.getItemInHand(ajk);
                final Optional<CampfireCookingRecipe> optional11 = bwo9.getCookableRecipe(ben10);
                if (optional11.isPresent()) {
                    if (!bjw.isClientSide && bwo9.placeFood(ayj.abilities.instabuild ? ben10.copy() : ben10, optional11.get().getCookingTime())) {
                        ayj.awardStat(Stats.INTERACT_WITH_CAMPFIRE);
                        return InteractionResult.SUCCESS;
                    }
                    return InteractionResult.CONSUME;
                }
            }
        }
        return InteractionResult.PASS;
    }
    
    @Override
    public void entityInside(final BlockState byj, final Level bjw, final BlockPos fk, final Entity akq) {
        if (!akq.fireImmune() && byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT) && akq instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity)akq)) {
            akq.hurt(DamageSource.IN_FIRE, 1.0f);
        }
        super.entityInside(byj, bjw, fk, akq);
    }
    
    @Override
    public void onRemove(final BlockState byj1, final Level bjw, final BlockPos fk, final BlockState byj4, final boolean boolean5) {
        if (byj1.getBlock() == byj4.getBlock()) {
            return;
        }
        final BlockEntity bwl7 = bjw.getBlockEntity(fk);
        if (bwl7 instanceof CampfireBlockEntity) {
            Containers.dropContents(bjw, fk, ((CampfireBlockEntity)bwl7).getItems());
        }
        super.onRemove(byj1, bjw, fk, byj4, boolean5);
    }
    
    @Nullable
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bcq) {
        final LevelAccessor bjx3 = bcq.getLevel();
        final BlockPos fk4 = bcq.getClickedPos();
        final boolean boolean5 = bjx3.getFluidState(fk4).getType() == Fluids.WATER;
        return (((((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).setValue((Property<Comparable>)CampfireBlock.WATERLOGGED, boolean5)).setValue((Property<Comparable>)CampfireBlock.SIGNAL_FIRE, this.isSmokeSource(bjx3.getBlockState(fk4.below())))).setValue((Property<Comparable>)CampfireBlock.LIT, !boolean5)).<Comparable, Direction>setValue((Property<Comparable>)CampfireBlock.FACING, bcq.getHorizontalDirection());
    }
    
    @Override
    public BlockState updateShape(final BlockState byj1, final Direction fp, final BlockState byj3, final LevelAccessor bjx, final BlockPos fk5, final BlockPos fk6) {
        if (byj1.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
            bjx.getLiquidTicks().scheduleTick(fk5, Fluids.WATER, Fluids.WATER.getTickDelay(bjx));
        }
        if (fp == Direction.DOWN) {
            return ((AbstractStateHolder<O, BlockState>)byj1).<Comparable, Boolean>setValue((Property<Comparable>)CampfireBlock.SIGNAL_FIRE, this.isSmokeSource(byj3));
        }
        return super.updateShape(byj1, fp, byj3, bjx, fk5, fk6);
    }
    
    private boolean isSmokeSource(final BlockState byj) {
        return byj.getBlock() == Blocks.HAY_BLOCK;
    }
    
    @Override
    public int getLightEmission(final BlockState byj) {
        return byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT) ? super.getLightEmission(byj) : 0;
    }
    
    @Override
    public VoxelShape getShape(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final CollisionContext cvq) {
        return CampfireBlock.SHAPE;
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState byj) {
        return RenderShape.MODEL;
    }
    
    @Override
    public void animateTick(final BlockState byj, final Level bjw, final BlockPos fk, final Random random) {
        if (!byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT)) {
            return;
        }
        if (random.nextInt(10) == 0) {
            bjw.playLocalSound(fk.getX() + 0.5f, fk.getY() + 0.5f, fk.getZ() + 0.5f, SoundEvents.CAMPFIRE_CRACKLE, SoundSource.BLOCKS, 0.5f + random.nextFloat(), random.nextFloat() * 0.7f + 0.6f, false);
        }
        if (random.nextInt(5) == 0) {
            for (int integer6 = 0; integer6 < random.nextInt(1) + 1; ++integer6) {
                bjw.addParticle(ParticleTypes.LAVA, fk.getX() + 0.5f, fk.getY() + 0.5f, fk.getZ() + 0.5f, random.nextFloat() / 2.0f, 5.0E-5, random.nextFloat() / 2.0f);
            }
        }
    }
    
    @Override
    public boolean placeLiquid(final LevelAccessor bjx, final BlockPos fk, final BlockState byj, final FluidState coj) {
        if (!byj.<Boolean>getValue((Property<Boolean>)BlockStateProperties.WATERLOGGED) && coj.getType() == Fluids.WATER) {
            final boolean boolean6 = byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT);
            if (boolean6) {
                if (bjx.isClientSide()) {
                    for (int integer7 = 0; integer7 < 20; ++integer7) {
                        makeParticles(bjx.getLevel(), fk, byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.SIGNAL_FIRE), true);
                    }
                }
                else {
                    bjx.playSound(null, fk, SoundEvents.GENERIC_EXTINGUISH_FIRE, SoundSource.BLOCKS, 1.0f, 1.0f);
                }
                final BlockEntity bwl7 = bjx.getBlockEntity(fk);
                if (bwl7 instanceof CampfireBlockEntity) {
                    ((CampfireBlockEntity)bwl7).dowse();
                }
            }
            bjx.setBlock(fk, (((AbstractStateHolder<O, BlockState>)byj).setValue((Property<Comparable>)CampfireBlock.WATERLOGGED, true)).<Comparable, Boolean>setValue((Property<Comparable>)CampfireBlock.LIT, false), 3);
            bjx.getLiquidTicks().scheduleTick(fk, coj.getType(), coj.getType().getTickDelay(bjx));
            return true;
        }
        return false;
    }
    
    @Nullable
    private Entity getShooter(final Entity akq) {
        if (akq instanceof Fireball) {
            return ((Fireball)akq).owner;
        }
        if (akq instanceof AbstractArrow) {
            return ((AbstractArrow)akq).getOwner();
        }
        return null;
    }
    
    @Override
    public void onProjectileHit(final Level bjw, final BlockState byj, final BlockHitResult cvg, final Entity akq) {
        if (!bjw.isClientSide) {
            final boolean boolean6 = akq instanceof Fireball || (akq instanceof AbstractArrow && akq.isOnFire());
            if (boolean6) {
                final Entity akq2 = this.getShooter(akq);
                final boolean boolean7 = akq2 == null || akq2 instanceof Player || bjw.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
                if (boolean7 && !byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT) && !byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
                    final BlockPos fk9 = cvg.getBlockPos();
                    bjw.setBlock(fk9, ((AbstractStateHolder<O, BlockState>)byj).<Comparable, Boolean>setValue((Property<Comparable>)BlockStateProperties.LIT, true), 11);
                }
            }
        }
    }
    
    public static void makeParticles(final Level bjw, final BlockPos fk, final boolean boolean3, final boolean boolean4) {
        final Random random5 = bjw.getRandom();
        final SimpleParticleType gw6 = boolean3 ? ParticleTypes.CAMPFIRE_SIGNAL_SMOKE : ParticleTypes.CAMPFIRE_COSY_SMOKE;
        bjw.addAlwaysVisibleParticle(gw6, true, fk.getX() + 0.5 + random5.nextDouble() / 3.0 * (random5.nextBoolean() ? 1 : -1), fk.getY() + random5.nextDouble() + random5.nextDouble(), fk.getZ() + 0.5 + random5.nextDouble() / 3.0 * (random5.nextBoolean() ? 1 : -1), 0.0, 0.07, 0.0);
        if (boolean4) {
            bjw.addParticle(ParticleTypes.SMOKE, fk.getX() + 0.25 + random5.nextDouble() / 2.0 * (random5.nextBoolean() ? 1 : -1), fk.getY() + 0.4, fk.getZ() + 0.25 + random5.nextDouble() / 2.0 * (random5.nextBoolean() ? 1 : -1), 0.0, 0.005, 0.0);
        }
    }
    
    public static boolean isSmokeyPos(final Level bjw, final BlockPos fk, final int integer) {
        for (int integer2 = 1; integer2 <= integer; ++integer2) {
            final BlockPos fk2 = fk.below(integer2);
            final BlockState byj6 = bjw.getBlockState(fk2);
            if (isLitCampfire(byj6)) {
                return true;
            }
            final boolean boolean7 = Shapes.joinIsNotEmpty(CampfireBlock.VIRTUAL_FENCE_POST, byj6.getCollisionShape(bjw, fk, CollisionContext.empty()), BooleanOp.AND);
            if (boolean7) {
                final BlockState byj7 = bjw.getBlockState(fk2.below());
                return isLitCampfire(byj7);
            }
        }
        return false;
    }
    
    private static boolean isLitCampfire(final BlockState byj) {
        return byj.getBlock() == Blocks.CAMPFIRE && byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.LIT);
    }
    
    @Override
    public FluidState getFluidState(final BlockState byj) {
        if (byj.<Boolean>getValue((Property<Boolean>)CampfireBlock.WATERLOGGED)) {
            return Fluids.WATER.getSource(false);
        }
        return super.getFluidState(byj);
    }
    
    @Override
    public BlockState rotate(final BlockState byj, final Rotation btu) {
        return ((AbstractStateHolder<O, BlockState>)byj).<Comparable, Direction>setValue((Property<Comparable>)CampfireBlock.FACING, btu.rotate(byj.<Direction>getValue((Property<Direction>)CampfireBlock.FACING)));
    }
    
    @Override
    public BlockState mirror(final BlockState byj, final Mirror bsu) {
        return byj.rotate(bsu.getRotation(byj.<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 bjg) {
        return new CampfireBlockEntity();
    }
    
    @Override
    public boolean isPathfindable(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final PathComputationType cqr) {
        return false;
    }
    
    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);
    }
}
