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.Random;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.TickPriority;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import javax.annotation.Nullable;
import java.util.List;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.ComparatorBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.ComparatorMode;
import net.minecraft.world.level.block.state.properties.EnumProperty;

public class ComparatorBlock extends DiodeBlock implements EntityBlock {
    public static final EnumProperty<ComparatorMode> MODE;
    
    public ComparatorBlock(final Properties c) {
        super(c);
        this.registerDefaultState(((((StateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)ComparatorBlock.FACING, Direction.NORTH)).setValue((Property<Comparable>)ComparatorBlock.POWERED, false)).<ComparatorMode, ComparatorMode>setValue(ComparatorBlock.MODE, ComparatorMode.COMPARE));
    }
    
    @Override
    protected int getDelay(final BlockState cfj) {
        return 2;
    }
    
    @Override
    protected int getOutputSignal(final BlockGetter bpg, final BlockPos fu, final BlockState cfj) {
        final BlockEntity cdl5 = bpg.getBlockEntity(fu);
        if (cdl5 instanceof ComparatorBlockEntity) {
            return ((ComparatorBlockEntity)cdl5).getOutputSignal();
        }
        return 0;
    }
    
    private int calculateOutputSignal(final Level bqb, final BlockPos fu, final BlockState cfj) {
        if (cfj.<ComparatorMode>getValue(ComparatorBlock.MODE) == ComparatorMode.SUBTRACT) {
            return Math.max(this.getInputSignal(bqb, fu, cfj) - this.getAlternateSignal(bqb, fu, cfj), 0);
        }
        return this.getInputSignal(bqb, fu, cfj);
    }
    
    @Override
    protected boolean shouldTurnOn(final Level bqb, final BlockPos fu, final BlockState cfj) {
        final int integer5 = this.getInputSignal(bqb, fu, cfj);
        if (integer5 == 0) {
            return false;
        }
        final int integer6 = this.getAlternateSignal(bqb, fu, cfj);
        return integer5 > integer6 || (integer5 == integer6 && cfj.<ComparatorMode>getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE);
    }
    
    @Override
    protected int getInputSignal(final Level bqb, final BlockPos fu, final BlockState cfj) {
        int integer5 = super.getInputSignal(bqb, fu, cfj);
        final Direction fz6 = cfj.<Direction>getValue((Property<Direction>)ComparatorBlock.FACING);
        BlockPos fu2 = fu.relative(fz6);
        BlockState cfj2 = bqb.getBlockState(fu2);
        if (cfj2.hasAnalogOutputSignal()) {
            integer5 = cfj2.getAnalogOutputSignal(bqb, fu2);
        }
        else if (integer5 < 15 && cfj2.isRedstoneConductor(bqb, fu2)) {
            fu2 = fu2.relative(fz6);
            cfj2 = bqb.getBlockState(fu2);
            final ItemFrame bba9 = this.getItemFrame(bqb, fz6, fu2);
            final int integer6 = Math.max((bba9 == null) ? Integer.MIN_VALUE : bba9.getAnalogOutput(), cfj2.hasAnalogOutputSignal() ? cfj2.getAnalogOutputSignal(bqb, fu2) : Integer.MIN_VALUE);
            if (integer6 != Integer.MIN_VALUE) {
                integer5 = integer6;
            }
        }
        return integer5;
    }
    
    @Nullable
    private ItemFrame getItemFrame(final Level bqb, final Direction fz, final BlockPos fu) {
        final List<ItemFrame> list5 = bqb.<ItemFrame>getEntitiesOfClass(ItemFrame.class, new AABB(fu.getX(), fu.getY(), fu.getZ(), fu.getX() + 1, fu.getY() + 1, fu.getZ() + 1), bba -> bba != null && bba.getDirection() == fz);
        if (list5.size() == 1) {
            return list5.get(0);
        }
        return null;
    }
    
    @Override
    public InteractionResult use(BlockState cfj, final Level bqb, final BlockPos fu, final Player bec, final InteractionHand anf, final BlockHitResult deh) {
        if (!bec.abilities.mayBuild) {
            return InteractionResult.PASS;
        }
        cfj = ((StateHolder<O, BlockState>)cfj).<ComparatorMode>cycle(ComparatorBlock.MODE);
        final float float8 = (cfj.<ComparatorMode>getValue(ComparatorBlock.MODE) == ComparatorMode.SUBTRACT) ? 0.55f : 0.5f;
        bqb.playSound(bec, fu, SoundEvents.COMPARATOR_CLICK, SoundSource.BLOCKS, 0.3f, float8);
        bqb.setBlock(fu, cfj, 2);
        this.refreshOutputState(bqb, fu, cfj);
        return InteractionResult.sidedSuccess(bqb.isClientSide);
    }
    
    @Override
    protected void checkTickOnNeighbor(final Level bqb, final BlockPos fu, final BlockState cfj) {
        if (bqb.getBlockTicks().willTickThisTick(fu, this)) {
            return;
        }
        final int integer5 = this.calculateOutputSignal(bqb, fu, cfj);
        final BlockEntity cdl6 = bqb.getBlockEntity(fu);
        final int integer6 = (cdl6 instanceof ComparatorBlockEntity) ? ((ComparatorBlockEntity)cdl6).getOutputSignal() : 0;
        if (integer5 != integer6 || cfj.<Boolean>getValue((Property<Boolean>)ComparatorBlock.POWERED) != this.shouldTurnOn(bqb, fu, cfj)) {
            final TickPriority bqt8 = this.shouldPrioritize(bqb, fu, cfj) ? TickPriority.HIGH : TickPriority.NORMAL;
            bqb.getBlockTicks().scheduleTick(fu, this, 2, bqt8);
        }
    }
    
    private void refreshOutputState(final Level bqb, final BlockPos fu, final BlockState cfj) {
        final int integer5 = this.calculateOutputSignal(bqb, fu, cfj);
        final BlockEntity cdl6 = bqb.getBlockEntity(fu);
        int integer6 = 0;
        if (cdl6 instanceof ComparatorBlockEntity) {
            final ComparatorBlockEntity cdr8 = (ComparatorBlockEntity)cdl6;
            integer6 = cdr8.getOutputSignal();
            cdr8.setOutputSignal(integer5);
        }
        if (integer6 != integer5 || cfj.<ComparatorMode>getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE) {
            final boolean boolean8 = this.shouldTurnOn(bqb, fu, cfj);
            final boolean boolean9 = cfj.<Boolean>getValue((Property<Boolean>)ComparatorBlock.POWERED);
            if (boolean9 && !boolean8) {
                bqb.setBlock(fu, ((StateHolder<O, BlockState>)cfj).<Comparable, Boolean>setValue((Property<Comparable>)ComparatorBlock.POWERED, false), 2);
            }
            else if (!boolean9 && boolean8) {
                bqb.setBlock(fu, ((StateHolder<O, BlockState>)cfj).<Comparable, Boolean>setValue((Property<Comparable>)ComparatorBlock.POWERED, true), 2);
            }
            this.updateNeighborsInFront(bqb, fu, cfj);
        }
    }
    
    @Override
    public void tick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        this.refreshOutputState(zd, fu, cfj);
    }
    
    @Override
    public boolean triggerEvent(final BlockState cfj, final Level bqb, final BlockPos fu, final int integer4, final int integer5) {
        super.triggerEvent(cfj, bqb, fu, integer4, integer5);
        final BlockEntity cdl7 = bqb.getBlockEntity(fu);
        return cdl7 != null && cdl7.triggerEvent(integer4, integer5);
    }
    
    @Override
    public BlockEntity newBlockEntity(final BlockGetter bpg) {
        return new ComparatorBlockEntity();
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(ComparatorBlock.FACING, ComparatorBlock.MODE, ComparatorBlock.POWERED);
    }
    
    static {
        MODE = BlockStateProperties.MODE_COMPARATOR;
    }
}
