package com.infinityraider.infinitylib.block;

import com.infinityraider.infinitylib.block.property.InfProperty;
import com.infinityraider.infinitylib.block.property.InfPropertyConfiguration;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemStack;
import net.minecraft.state.StateContainer;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import javax.annotation.Nonnull;

public abstract class BlockBase extends Block implements IInfinityBlock {
    private final String internalName;

    public BlockBase(String name, Properties properties) {
        super(properties);
        this.internalName = name;
        this.setDefaultState(this.getPropertyConfiguration().defineDefault(this.getStateContainer().getBaseState()));
    }

    @Override
    protected final void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        this.getPropertyConfiguration().fillStateContainer(builder);
    }

    protected abstract InfPropertyConfiguration getPropertyConfiguration();

    @Override
    @Deprecated
    public final BlockState rotate(BlockState state, Rotation rot) {
        return this.getPropertyConfiguration().handleRotation(state, rot);
    }

    @Override
    @Deprecated
    public final BlockState mirror(BlockState state, Mirror mirror) {
        return this.getPropertyConfiguration().handleMirror(state, mirror);
    }

    @Override
    public final FluidState getFluidState(BlockState state) {
        return this.getPropertyConfiguration().isWaterLoggable() && InfProperty.Defaults.waterlogged().fetch(state)
                ? Fluids.WATER.getStillFluidState(false)
                : super.getFluidState(state);
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    @Nonnull
    public String getInternalName() {
        return this.internalName;
    }

    public final BlockState waterlog(BlockState state, World world, BlockPos pos) {
        if(this.getPropertyConfiguration().isWaterLoggable()) {
            FluidState fluid = world.getFluidState(pos);
            state = InfProperty.Defaults.waterlogged().apply(state, fluid.getFluid() == Fluids.WATER);
        }
        return state;
    }
}

@@ -181,24 +181,66 @@
 figuration;%0A
+import mcp.MethodsReturnNonnullByDefault;%0A
 import net.m
@@ -341,24 +341,73 @@
 ItemEntity;%0A
+import net.minecraft.entity.player.PlayerEntity;%0A
 import net.m
@@ -727,16 +727,167 @@
 onnull;%0A
+import javax.annotation.Nullable;%0Aimport javax.annotation.ParametersAreNonnullByDefault;%0A%0A@ParametersAreNonnullByDefault%0A@MethodsReturnNonnullByDefault
 %0Apublic 
@@ -1524,32 +1524,69 @@
     @Deprecated%0A
+    @SuppressWarnings(%22deprecation%22)%0A
     public final
@@ -1746,24 +1746,61 @@
 @Deprecated%0A
+    @SuppressWarnings(%22deprecation%22)%0A
     public f
@@ -1946,32 +1946,85 @@
 %0A%0A    @Override%0A
+    @Deprecated%0A    @SuppressWarnings(%22deprecation%22)%0A
     public final
@@ -2821,11 +2821,428 @@
 e;%0A    %7D
+%0A%0A    public boolean addToInventoryOrDrop(ItemStack stack, World world, BlockPos pos, @Nullable PlayerEntity player) %7B%0A        if(player != null) %7B%0A            if(player.addItemStackToInventory(stack)) %7B%0A                return true;%0A            %7D%0A        %7D%0A        ItemEntity entity = new ItemEntity(world, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, stack);%0A        return world.addEntity(entity);%0A    %7D
 %0A%7D%0A

Add drop utility method