package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.StateDefinition;
import java.util.Iterator;
import java.util.List;
import net.minecraft.core.Vec3i;
import java.util.Random;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.item.BlockPlaceContext;
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.properties.Property;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.core.Direction;
import java.util.Map;
import net.minecraft.world.level.block.state.properties.BooleanProperty;

public class TripWireBlock extends Block {
    public static final BooleanProperty POWERED;
    public static final BooleanProperty ATTACHED;
    public static final BooleanProperty DISARMED;
    public static final BooleanProperty NORTH;
    public static final BooleanProperty EAST;
    public static final BooleanProperty SOUTH;
    public static final BooleanProperty WEST;
    private static final Map<Direction, BooleanProperty> PROPERTY_BY_DIRECTION;
    protected static final VoxelShape AABB;
    protected static final VoxelShape NOT_ATTACHED_AABB;
    private final TripWireHookBlock hook;
    
    public TripWireBlock(final TripWireHookBlock ccg, final Properties c) {
        super(c);
        this.registerDefaultState(((((((((StateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)TripWireBlock.POWERED, false)).setValue((Property<Comparable>)TripWireBlock.ATTACHED, false)).setValue((Property<Comparable>)TripWireBlock.DISARMED, false)).setValue((Property<Comparable>)TripWireBlock.NORTH, false)).setValue((Property<Comparable>)TripWireBlock.EAST, false)).setValue((Property<Comparable>)TripWireBlock.SOUTH, false)).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.WEST, false));
        this.hook = ccg;
    }
    
    @Override
    public VoxelShape getShape(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final CollisionContext der) {
        return cfj.<Boolean>getValue((Property<Boolean>)TripWireBlock.ATTACHED) ? TripWireBlock.AABB : TripWireBlock.NOT_ATTACHED_AABB;
    }
    
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bin) {
        final BlockGetter bpg3 = bin.getLevel();
        final BlockPos fu4 = bin.getClickedPos();
        return (((((StateHolder<O, BlockState>)this.defaultBlockState()).setValue((Property<Comparable>)TripWireBlock.NORTH, this.shouldConnectTo(bpg3.getBlockState(fu4.north()), Direction.NORTH))).setValue((Property<Comparable>)TripWireBlock.EAST, this.shouldConnectTo(bpg3.getBlockState(fu4.east()), Direction.EAST))).setValue((Property<Comparable>)TripWireBlock.SOUTH, this.shouldConnectTo(bpg3.getBlockState(fu4.south()), Direction.SOUTH))).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.WEST, this.shouldConnectTo(bpg3.getBlockState(fu4.west()), Direction.WEST));
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (fz.getAxis().isHorizontal()) {
            return ((StateHolder<O, BlockState>)cfj1).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.PROPERTY_BY_DIRECTION.get(fz), this.shouldConnectTo(cfj3, fz));
        }
        return super.updateShape(cfj1, fz, cfj3, bqc, fu5, fu6);
    }
    
    @Override
    public void onPlace(final BlockState cfj1, final Level bqb, final BlockPos fu, final BlockState cfj4, final boolean boolean5) {
        if (cfj4.is(cfj1.getBlock())) {
            return;
        }
        this.updateSource(bqb, fu, cfj1);
    }
    
    @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;
        }
        this.updateSource(bqb, fu, ((StateHolder<O, BlockState>)cfj1).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.POWERED, true));
    }
    
    @Override
    public void playerWillDestroy(final Level bqb, final BlockPos fu, final BlockState cfj, final Player bec) {
        if (!bqb.isClientSide && !bec.getMainHandItem().isEmpty() && bec.getMainHandItem().getItem() == Items.SHEARS) {
            bqb.setBlock(fu, ((StateHolder<O, BlockState>)cfj).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.DISARMED, true), 4);
        }
        super.playerWillDestroy(bqb, fu, cfj, bec);
    }
    
    private void updateSource(final Level bqb, final BlockPos fu, final BlockState cfj) {
        for (final Direction fz8 : new Direction[] { Direction.SOUTH, Direction.WEST }) {
            int integer9 = 1;
            while (integer9 < 42) {
                final BlockPos fu2 = fu.relative(fz8, integer9);
                final BlockState cfj2 = bqb.getBlockState(fu2);
                if (cfj2.is(this.hook)) {
                    if (cfj2.<Comparable>getValue((Property<Comparable>)TripWireHookBlock.FACING) == fz8.getOpposite()) {
                        this.hook.calculateState(bqb, fu2, cfj2, false, true, integer9, cfj);
                        break;
                    }
                    break;
                }
                else {
                    if (!cfj2.is(this)) {
                        break;
                    }
                    ++integer9;
                }
            }
        }
    }
    
    @Override
    public void entityInside(final BlockState cfj, final Level bqb, final BlockPos fu, final Entity aom) {
        if (bqb.isClientSide) {
            return;
        }
        if (cfj.<Boolean>getValue((Property<Boolean>)TripWireBlock.POWERED)) {
            return;
        }
        this.checkPressed(bqb, fu);
    }
    
    @Override
    public void tick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        if (!zd.getBlockState(fu).<Boolean>getValue((Property<Boolean>)TripWireBlock.POWERED)) {
            return;
        }
        this.checkPressed(zd, fu);
    }
    
    private void checkPressed(final Level bqb, final BlockPos fu) {
        BlockState cfj4 = bqb.getBlockState(fu);
        final boolean boolean5 = cfj4.<Boolean>getValue((Property<Boolean>)TripWireBlock.POWERED);
        boolean boolean6 = false;
        final List<? extends Entity> list7 = bqb.getEntities(null, cfj4.getShape(bqb, fu).bounds().move(fu));
        if (!list7.isEmpty()) {
            for (final Entity aom9 : list7) {
                if (!aom9.isIgnoringBlockTriggers()) {
                    boolean6 = true;
                    break;
                }
            }
        }
        if (boolean6 != boolean5) {
            cfj4 = ((StateHolder<O, BlockState>)cfj4).<Comparable, Boolean>setValue((Property<Comparable>)TripWireBlock.POWERED, boolean6);
            bqb.setBlock(fu, cfj4, 3);
            this.updateSource(bqb, fu, cfj4);
        }
        if (boolean6) {
            bqb.getBlockTicks().scheduleTick(new BlockPos(fu), this, 10);
        }
    }
    
    public boolean shouldConnectTo(final BlockState cfj, final Direction fz) {
        final Block bvr4 = cfj.getBlock();
        if (bvr4 == this.hook) {
            return cfj.<Comparable>getValue((Property<Comparable>)TripWireHookBlock.FACING) == fz.getOpposite();
        }
        return bvr4 == this;
    }
    
    @Override
    public BlockState rotate(final BlockState cfj, final Rotation cap) {
        switch (cap) {
            case CLOCKWISE_180: {
                return (((((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)TripWireBlock.NORTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.SOUTH))).setValue((Property<Comparable>)TripWireBlock.EAST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.WEST))).setValue((Property<Comparable>)TripWireBlock.SOUTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.NORTH))).<Comparable, Comparable>setValue((Property<Comparable>)TripWireBlock.WEST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.EAST));
            }
            case COUNTERCLOCKWISE_90: {
                return (((((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)TripWireBlock.NORTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.EAST))).setValue((Property<Comparable>)TripWireBlock.EAST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.SOUTH))).setValue((Property<Comparable>)TripWireBlock.SOUTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.WEST))).<Comparable, Comparable>setValue((Property<Comparable>)TripWireBlock.WEST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.NORTH));
            }
            case CLOCKWISE_90: {
                return (((((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)TripWireBlock.NORTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.WEST))).setValue((Property<Comparable>)TripWireBlock.EAST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.NORTH))).setValue((Property<Comparable>)TripWireBlock.SOUTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.EAST))).<Comparable, Comparable>setValue((Property<Comparable>)TripWireBlock.WEST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.SOUTH));
            }
            default: {
                return cfj;
            }
        }
    }
    
    @Override
    public BlockState mirror(final BlockState cfj, final Mirror bzj) {
        switch (bzj) {
            case LEFT_RIGHT: {
                return (((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)TripWireBlock.NORTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.SOUTH))).<Comparable, Comparable>setValue((Property<Comparable>)TripWireBlock.SOUTH, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.NORTH));
            }
            case FRONT_BACK: {
                return (((StateHolder<O, BlockState>)cfj).setValue((Property<Comparable>)TripWireBlock.EAST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.WEST))).<Comparable, Comparable>setValue((Property<Comparable>)TripWireBlock.WEST, (Comparable)cfj.<V>getValue((Property<V>)TripWireBlock.EAST));
            }
            default: {
                return super.mirror(cfj, bzj);
            }
        }
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(TripWireBlock.POWERED, TripWireBlock.ATTACHED, TripWireBlock.DISARMED, TripWireBlock.NORTH, TripWireBlock.EAST, TripWireBlock.WEST, TripWireBlock.SOUTH);
    }
    
    static {
        POWERED = BlockStateProperties.POWERED;
        ATTACHED = BlockStateProperties.ATTACHED;
        DISARMED = BlockStateProperties.DISARMED;
        NORTH = PipeBlock.NORTH;
        EAST = PipeBlock.EAST;
        SOUTH = PipeBlock.SOUTH;
        WEST = PipeBlock.WEST;
        PROPERTY_BY_DIRECTION = CrossCollisionBlock.PROPERTY_BY_DIRECTION;
        AABB = Block.box(0.0, 1.0, 0.0, 16.0, 2.5, 16.0);
        NOT_ATTACHED_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 8.0, 16.0);
    }
}
