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 net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.monster.Ravager;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LevelReader;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import java.util.Random;
import net.minecraft.server.level.ServerLevel;
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.world.level.block.state.properties.IntegerProperty;

public class CropBlock extends BushBlock implements BonemealableBlock {
    public static final IntegerProperty AGE;
    private static final VoxelShape[] SHAPE_BY_AGE;
    
    protected CropBlock(final Properties c) {
        super(c);
        this.registerDefaultState(((StateHolder<O, BlockState>)this.stateDefinition.any()).<Comparable, Integer>setValue((Property<Comparable>)this.getAgeProperty(), 0));
    }
    
    @Override
    public VoxelShape getShape(final BlockState cfj, final BlockGetter bpg, final BlockPos fu, final CollisionContext der) {
        return CropBlock.SHAPE_BY_AGE[cfj.<Integer>getValue((Property<Integer>)this.getAgeProperty())];
    }
    
    @Override
    protected boolean mayPlaceOn(final BlockState cfj, final BlockGetter bpg, final BlockPos fu) {
        return cfj.is(Blocks.FARMLAND);
    }
    
    public IntegerProperty getAgeProperty() {
        return CropBlock.AGE;
    }
    
    public int getMaxAge() {
        return 7;
    }
    
    protected int getAge(final BlockState cfj) {
        return cfj.<Integer>getValue((Property<Integer>)this.getAgeProperty());
    }
    
    public BlockState getStateForAge(final int integer) {
        return ((StateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Integer>setValue((Property<Comparable>)this.getAgeProperty(), integer);
    }
    
    public boolean isMaxAge(final BlockState cfj) {
        return cfj.<Integer>getValue((Property<Integer>)this.getAgeProperty()) >= this.getMaxAge();
    }
    
    @Override
    public boolean isRandomlyTicking(final BlockState cfj) {
        return !this.isMaxAge(cfj);
    }
    
    @Override
    public void randomTick(final BlockState cfj, final ServerLevel zd, final BlockPos fu, final Random random) {
        if (zd.getRawBrightness(fu, 0) >= 9) {
            final int integer6 = this.getAge(cfj);
            if (integer6 < this.getMaxAge()) {
                final float float7 = getGrowthSpeed(this, zd, fu);
                if (random.nextInt((int)(25.0f / float7) + 1) == 0) {
                    zd.setBlock(fu, this.getStateForAge(integer6 + 1), 2);
                }
            }
        }
    }
    
    public void growCrops(final Level bqb, final BlockPos fu, final BlockState cfj) {
        int integer5 = this.getAge(cfj) + this.getBonemealAgeIncrease(bqb);
        final int integer6 = this.getMaxAge();
        if (integer5 > integer6) {
            integer5 = integer6;
        }
        bqb.setBlock(fu, this.getStateForAge(integer5), 2);
    }
    
    protected int getBonemealAgeIncrease(final Level bqb) {
        return Mth.nextInt(bqb.random, 2, 5);
    }
    
    protected static float getGrowthSpeed(final Block bvr, final BlockGetter bpg, final BlockPos fu) {
        float float4 = 1.0f;
        final BlockPos fu2 = fu.below();
        for (int integer6 = -1; integer6 <= 1; ++integer6) {
            for (int integer7 = -1; integer7 <= 1; ++integer7) {
                float float5 = 0.0f;
                final BlockState cfj9 = bpg.getBlockState(fu2.offset(integer6, 0, integer7));
                if (cfj9.is(Blocks.FARMLAND)) {
                    float5 = 1.0f;
                    if (cfj9.<Integer>getValue((Property<Integer>)FarmBlock.MOISTURE) > 0) {
                        float5 = 3.0f;
                    }
                }
                if (integer6 != 0 || integer7 != 0) {
                    float5 /= 4.0f;
                }
                float4 += float5;
            }
        }
        final BlockPos fu3 = fu.north();
        final BlockPos fu4 = fu.south();
        final BlockPos fu5 = fu.west();
        final BlockPos fu6 = fu.east();
        final boolean boolean10 = bvr == bpg.getBlockState(fu5).getBlock() || bvr == bpg.getBlockState(fu6).getBlock();
        final boolean boolean11 = bvr == bpg.getBlockState(fu3).getBlock() || bvr == bpg.getBlockState(fu4).getBlock();
        if (boolean10 && boolean11) {
            float4 /= 2.0f;
        }
        else {
            final boolean boolean12 = bvr == bpg.getBlockState(fu5.north()).getBlock() || bvr == bpg.getBlockState(fu6.north()).getBlock() || bvr == bpg.getBlockState(fu6.south()).getBlock() || bvr == bpg.getBlockState(fu5.south()).getBlock();
            if (boolean12) {
                float4 /= 2.0f;
            }
        }
        return float4;
    }
    
    @Override
    public boolean canSurvive(final BlockState cfj, final LevelReader bqd, final BlockPos fu) {
        return (bqd.getRawBrightness(fu, 0) >= 8 || bqd.canSeeSky(fu)) && super.canSurvive(cfj, bqd, fu);
    }
    
    @Override
    public void entityInside(final BlockState cfj, final Level bqb, final BlockPos fu, final Entity aom) {
        if (aom instanceof Ravager && bqb.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
            bqb.destroyBlock(fu, true, aom);
        }
        super.entityInside(cfj, bqb, fu, aom);
    }
    
    protected ItemLike getBaseSeedId() {
        return Items.WHEAT_SEEDS;
    }
    
    @Override
    public ItemStack getCloneItemStack(final BlockGetter bpg, final BlockPos fu, final BlockState cfj) {
        return new ItemStack(this.getBaseSeedId());
    }
    
    @Override
    public boolean isValidBonemealTarget(final BlockGetter bpg, final BlockPos fu, final BlockState cfj, final boolean boolean4) {
        return !this.isMaxAge(cfj);
    }
    
    @Override
    public boolean isBonemealSuccess(final Level bqb, final Random random, final BlockPos fu, final BlockState cfj) {
        return true;
    }
    
    @Override
    public void performBonemeal(final ServerLevel zd, final Random random, final BlockPos fu, final BlockState cfj) {
        this.growCrops(zd, fu, cfj);
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(CropBlock.AGE);
    }
    
    static {
        AGE = BlockStateProperties.AGE_7;
        SHAPE_BY_AGE = new VoxelShape[] { Block.box(0.0, 0.0, 0.0, 16.0, 2.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 4.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 6.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 8.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 10.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 12.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 14.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 16.0, 16.0) };
    }
}
