package net.darkmorford.jas.block;

import net.darkmorford.jas.JustAnotherSnad;
import net.darkmorford.jas.configuration.ConfigurationData;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import org.apache.logging.log4j.Level;

import java.util.Random;

import static net.darkmorford.jas.JustAnotherSnad.MODID;

public class BlockSnad extends BlockSand {

    public BlockSnad() {
        super();
        setCreativeTab(CreativeTabs.MISC);
        setHardness(0.5f);
        setSoundType(SoundType.SAND);
        setTickRandomly(true);
        setUnlocalizedName("snad");
        setRegistryName(MODID, "snad");
    }

    @Override
    public void randomTick(World world, BlockPos position, IBlockState state, Random random) {
        super.randomTick(world, position, state, random);

        Block blockAbove = world.getBlockState(position.up()).getBlock();
        if (blockAbove instanceof BlockReed || blockAbove instanceof BlockCactus) {
            checkColumnOfPlant(world, position, random, blockAbove);
        } else if (blockAbove instanceof IPlantable) {
            blockAbove.randomTick(world, position.up(), world.getBlockState(position.up()), random);
        }
    }

    private void checkColumnOfPlant(World world, BlockPos position, Random random, Block blockAbove) {
        JustAnotherSnad.logger.log(Level.INFO, "checkColumnOfPlant");
        int height = 1;
        Block nextPlantBlock;
        while ((nextPlantBlock = world.getBlockState(position.up(height)).getBlock()).getClass().equals(blockAbove.getClass())) {
            JustAnotherSnad.logger.log(Level.INFO, "do growthLoop");
            growthLoop(world, position, random, (IPlantable) blockAbove, height, nextPlantBlock);
            height++;
        }
    }

    private void growthLoop(World world, BlockPos position, Random random, IPlantable blockAbove,int height, Block nextPlantBlock) {
        for (int growthAttempts = 0; growthAttempts < ConfigurationData.SNAD_SPEED_INCREASE_VALUE * 10; growthAttempts++) {
            if (growthAttempts == 0 || canSustainPlant(world.getBlockState(position), world, position, null, blockAbove)) {
                nextPlantBlock.randomTick(world, position.up(height), world.getBlockState(position.up(height)), random);
            }
        }
    }

    @Override
    public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos position, EnumFacing facing, IPlantable plantable) {
        BlockPos plantPosition = new BlockPos(position.getX(), position.getY() + 1, position.getZ());
        EnumPlantType plantType = plantable.getPlantType(world, plantPosition);
        switch (plantType) {
            case Desert:
                return true;
            case Beach:
                return ((world.getBlockState(new BlockPos(position.getX() - 1, position.getY(), position.getZ())).getMaterial() == Material.WATER) ||
                    (world.getBlockState(new BlockPos(position.getX() + 1, position.getY(), position.getZ())).getMaterial() == Material.WATER) ||
                    (world.getBlockState(new BlockPos(position.getX(), position.getY(), position.getZ() + 1)).getMaterial() == Material.WATER) ||
                    (world.getBlockState(new BlockPos(position.getX(), position.getY(), position.getZ() - 1)).getMaterial() == Material.WATER));

            case Water:
                return (world.getBlockState(position).getMaterial() == Material.WATER) && (world.getBlockState(position) == getDefaultState());
            default: {
                return false;
            }
        }
    }
}

@@ -1599,33 +1599,41 @@
 world, BlockPos 
-p
+originalP
 osition, Random 
@@ -1672,92 +1672,28 @@
     
-JustAnotherSnad.logger.log(Level.INFO, %22checkColumnOfPlant%22);%0A        int height = 1
+Block nextPlantBlock
 ;%0A  
@@ -1699,39 +1699,64 @@
        Block
+Pos
  nextP
-lantBlock
+osition = originalPosition.up()
 ;%0A        wh
@@ -1798,35 +1798,28 @@
 ckState(
-p
+nextP
 osition
-.up(height)
 ).getBlo
@@ -1872,77 +1872,8 @@
 ) %7B%0A
-            JustAnotherSnad.logger.log(Level.INFO, %22do growthLoop%22);%0A
     
@@ -1890,33 +1890,41 @@
 owthLoop(world, 
-p
+originalP
 osition, random,
@@ -1949,22 +1949,28 @@
 kAbove, 
-height
+nextPosition
 , nextPl
@@ -1996,16 +1996,40 @@
     
-height++
+nextPosition = nextPosition.up()
 ;%0A  
@@ -2085,33 +2085,40 @@
 world, BlockPos 
-p
+orignalP
 osition, Random 
@@ -2151,18 +2151,30 @@
 ove,
-int height
+ BlockPos nextPosition
 , Bl
@@ -2296,13 +2296,8 @@
 ALUE
- * 10
 ; gr
@@ -2381,33 +2381,40 @@
 d.getBlockState(
-p
+orignalP
 osition), world,
@@ -2410,25 +2410,32 @@
 on), world, 
-p
+orignalP
 osition, nul
@@ -2501,35 +2501,28 @@
 (world, 
-p
+nextP
 osition
-.up(height)
 , world.
@@ -2539,27 +2539,20 @@
 ate(
-p
+nextP
 osition
-.up(height)
 ), r

Refactor away height in favoour of nextPosition