package net.minecraft.world.level.block;

import net.minecraft.world.level.material.PushReaction;
import net.minecraft.core.Vec3i;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import java.util.Random;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.VoxelShape;

public abstract class BasePressurePlateBlock extends Block {
    protected static final VoxelShape PRESSED_AABB;
    protected static final VoxelShape AABB;
    protected static final AABB TOUCH_AABB;
    
    protected BasePressurePlateBlock(final Properties c) {
        super(c);
    }
    
    @Override
    public VoxelShape getShape(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final CollisionContext der) {
        return (this.getSignalForState(cfj) > 0) ? BasePressurePlateBlock.PRESSED_AABB : BasePressurePlateBlock.AABB;
    }
    
    protected int getPressedTime() {
        return 20;
    }
    
    @Override
    public boolean isPossibleToRespawnInThis() {
        return true;
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (fz == Direction.DOWN && !cfj1.canSurvive(bqc, fu5)) {
            return Blocks.AIR.defaultBlockState();
        }
        return super.updateShape(cfj1, fz, cfj3, bqc, fu5, fu6);
    }
    
    @Override
    public boolean canSurvive(final BlockState cfj, final LevelReader bqd, final BlockPos fu) {
        final BlockPos fu2 = fu.below();
        return Block.canSupportRigidBlock(bqd, fu2) || Block.canSupportCenter(bqd, fu2, Direction.UP);
    }
    
    @Override
    public void tick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        final int integer6 = this.getSignalForState(cfj);
        if (integer6 > 0) {
            this.checkPressed(zd, fu, cfj, integer6);
        }
    }
    
    @Override
    public void entityInside(final BlockState cfj, final Level bqb, final BlockPos fu, final Entity aom) {
        if (bqb.isClientSide) {
            return;
        }
        final int integer6 = this.getSignalForState(cfj);
        if (integer6 == 0) {
            this.checkPressed(bqb, fu, cfj, integer6);
        }
    }
    
    protected void checkPressed(final Level bqb, final BlockPos fu, final BlockState cfj, final int integer) {
        final int integer2 = this.getSignalStrength(bqb, fu);
        final boolean boolean7 = integer > 0;
        final boolean boolean8 = integer2 > 0;
        if (integer != integer2) {
            final BlockState cfj2 = this.setSignalForState(cfj, integer2);
            bqb.setBlock(fu, cfj2, 2);
            this.updateNeighbours(bqb, fu);
            bqb.setBlocksDirty(fu, cfj, cfj2);
        }
        if (!boolean8 && boolean7) {
            this.playOffSound(bqb, fu);
        }
        else if (boolean8 && !boolean7) {
            this.playOnSound(bqb, fu);
        }
        if (boolean8) {
            bqb.getBlockTicks().scheduleTick(new BlockPos(fu), this, this.getPressedTime());
        }
    }
    
    protected abstract void playOnSound(final LevelAccessor bqc, final BlockPos fu);
    
    protected abstract void playOffSound(final LevelAccessor bqc, final BlockPos fu);
    
    @Override
    public void onRemove(final BlockState cfj1, final Level bqb, final BlockPos fu, final BlockState cfj4, final boolean boolean5) {
        if (boolean5 || cfj1.is(cfj4.getBlock())) {
            return;
        }
        if (this.getSignalForState(cfj1) > 0) {
            this.updateNeighbours(bqb, fu);
        }
        super.onRemove(cfj1, bqb, fu, cfj4, boolean5);
    }
    
    protected void updateNeighbours(final Level bqb, final BlockPos fu) {
        bqb.updateNeighborsAt(fu, this);
        bqb.updateNeighborsAt(fu.below(), this);
    }
    
    @Override
    public int getSignal(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final Direction fz) {
        return this.getSignalForState(cfj);
    }
    
    @Override
    public int getDirectSignal(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final Direction fz) {
        if (fz == Direction.UP) {
            return this.getSignalForState(cfj);
        }
        return 0;
    }
    
    @Override
    public boolean isSignalSource(final BlockState cfj) {
        return true;
    }
    
    @Override
    public PushReaction getPistonPushReaction(final BlockState cfj) {
        return PushReaction.DESTROY;
    }
    
    protected abstract int getSignalStrength(final Level bqb, final BlockPos fu);
    
    protected abstract int getSignalForState(final BlockState cfj);
    
    protected abstract BlockState setSignalForState(final BlockState cfj, final int integer);
    
    static {
        PRESSED_AABB = Block.box(1.0, 0.0, 1.0, 15.0, 0.5, 15.0);
        AABB = Block.box(1.0, 0.0, 1.0, 15.0, 1.0, 15.0);
        TOUCH_AABB = new AABB(0.125, 0.0, 0.125, 0.875, 0.25, 0.875);
    }
}
