package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.core.Direction;
import net.minecraft.world.item.BlockPlaceContext;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.state.properties.RailShape;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.shapes.VoxelShape;

public abstract class BaseRailBlock extends Block {
    protected static final VoxelShape FLAT_AABB;
    protected static final VoxelShape HALF_BLOCK_AABB;
    private final boolean isStraight;
    
    public static boolean isRail(final Level bjw, final BlockPos fk) {
        return isRail(bjw.getBlockState(fk));
    }
    
    public static boolean isRail(final BlockState byj) {
        return byj.is(BlockTags.RAILS);
    }
    
    protected BaseRailBlock(final boolean boolean1, final Properties c) {
        super(c);
        this.isStraight = boolean1;
    }
    
    public boolean isStraight() {
        return this.isStraight;
    }
    
    @Override
    public VoxelShape getShape(final BlockState byj, final BlockGetter bjg, final BlockPos fk, final CollisionContext cvq) {
        final RailShape bzn6 = (byj.getBlock() == this) ? byj.<RailShape>getValue(this.getShapeProperty()) : null;
        if (bzn6 != null && bzn6.isAscending()) {
            return BaseRailBlock.HALF_BLOCK_AABB;
        }
        return BaseRailBlock.FLAT_AABB;
    }
    
    @Override
    public boolean canSurvive(final BlockState byj, final LevelReader bjz, final BlockPos fk) {
        return Block.canSupportRigidBlock(bjz, fk.below());
    }
    
    @Override
    public void onPlace(BlockState byj1, final Level bjw, final BlockPos fk, final BlockState byj4, final boolean boolean5) {
        if (byj4.getBlock() == byj1.getBlock()) {
            return;
        }
        byj1 = this.updateDir(bjw, fk, byj1, true);
        if (this.isStraight) {
            byj1.neighborChanged(bjw, fk, this, fk, boolean5);
        }
    }
    
    @Override
    public void neighborChanged(final BlockState byj, final Level bjw, final BlockPos fk3, final Block bph, final BlockPos fk5, final boolean boolean6) {
        if (bjw.isClientSide) {
            return;
        }
        final RailShape bzn8 = byj.<RailShape>getValue(this.getShapeProperty());
        boolean boolean7 = false;
        final BlockPos fk6 = fk3.below();
        if (!Block.canSupportRigidBlock(bjw, fk6)) {
            boolean7 = true;
        }
        final BlockPos fk7 = fk3.east();
        if (bzn8 == RailShape.ASCENDING_EAST && !Block.canSupportRigidBlock(bjw, fk7)) {
            boolean7 = true;
        }
        else {
            final BlockPos fk8 = fk3.west();
            if (bzn8 == RailShape.ASCENDING_WEST && !Block.canSupportRigidBlock(bjw, fk8)) {
                boolean7 = true;
            }
            else {
                final BlockPos fk9 = fk3.north();
                if (bzn8 == RailShape.ASCENDING_NORTH && !Block.canSupportRigidBlock(bjw, fk9)) {
                    boolean7 = true;
                }
                else {
                    final BlockPos fk10 = fk3.south();
                    if (bzn8 == RailShape.ASCENDING_SOUTH && !Block.canSupportRigidBlock(bjw, fk10)) {
                        boolean7 = true;
                    }
                }
            }
        }
        if (boolean7 && !bjw.isEmptyBlock(fk3)) {
            if (!boolean6) {
                Block.dropResources(byj, bjw, fk3);
            }
            bjw.removeBlock(fk3, boolean6);
        }
        else {
            this.updateState(byj, bjw, fk3, bph);
        }
    }
    
    protected void updateState(final BlockState byj, final Level bjw, final BlockPos fk, final Block bph) {
    }
    
    protected BlockState updateDir(final Level bjw, final BlockPos fk, final BlockState byj, final boolean boolean4) {
        if (bjw.isClientSide) {
            return byj;
        }
        final RailShape bzn6 = byj.<RailShape>getValue(this.getShapeProperty());
        return new RailState(bjw, fk, byj).place(bjw.hasNeighborSignal(fk), boolean4, bzn6).getState();
    }
    
    @Override
    public PushReaction getPistonPushReaction(final BlockState byj) {
        return PushReaction.NORMAL;
    }
    
    @Override
    public void onRemove(final BlockState byj1, final Level bjw, final BlockPos fk, final BlockState byj4, final boolean boolean5) {
        if (boolean5) {
            return;
        }
        super.onRemove(byj1, bjw, fk, byj4, boolean5);
        if (byj1.<RailShape>getValue(this.getShapeProperty()).isAscending()) {
            bjw.updateNeighborsAt(fk.above(), this);
        }
        if (this.isStraight) {
            bjw.updateNeighborsAt(fk, this);
            bjw.updateNeighborsAt(fk.below(), this);
        }
    }
    
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bcq) {
        final BlockState byj3 = super.defaultBlockState();
        final Direction fp4 = bcq.getHorizontalDirection();
        final boolean boolean5 = fp4 == Direction.EAST || fp4 == Direction.WEST;
        return ((AbstractStateHolder<O, BlockState>)byj3).<RailShape, RailShape>setValue(this.getShapeProperty(), boolean5 ? RailShape.EAST_WEST : RailShape.NORTH_SOUTH);
    }
    
    public abstract Property<RailShape> getShapeProperty();
    
    static {
        FLAT_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 2.0, 16.0);
        HALF_BLOCK_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 8.0, 16.0);
    }
}
