package net.glowstone.block.blocktype;

import net.glowstone.block.GlowBlock;
import net.glowstone.block.GlowBlockState;
import net.glowstone.entity.GlowPlayer;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;

/**
 * Represents a block that falls down, when there's no block below it.
 */
public class BlockFalling extends BlockType {

    private final Material drop;

    public BlockFalling(Material drop) {
        this.drop = drop;
    }

    @Override
    public void afterPlace(GlowPlayer player, GlowBlock block, ItemStack holding,
        GlowBlockState oldState) {
        updatePhysics(block);
    }

    @Override
    public void onNearBlockChanged(GlowBlock me, BlockFace face, GlowBlock other, Material oldType,
        byte oldData, Material newType, byte newData) {
        if (face == BlockFace.DOWN) {
            updatePhysics(me);
        }
    }

    @Override
    public void updatePhysicsAfterEvent(GlowBlock me) {
        super.updatePhysicsAfterEvent(me);
        Block below = me.getRelative(BlockFace.DOWN);
        if (!supportingBlock(below.getType())) {
            //Simulates real Minecraft delay on block fall
            //If possible should be changed to 2.5 ticks
            me.getWorld().getServer().getScheduler()
                .runTaskLater(null, () -> transformToFallingEntity(me), 2);
        }
    }

    protected void transformToFallingEntity(GlowBlock me) {
        //Force block to update otherwise it can sometimes duplicate
        me = me.getWorld().getBlockAt(me.getX(), me.getY(), me.getZ());

        if (!me.isEmpty()) {
            byte data = me.getData();
            me.setType(Material.AIR);
            me.getWorld().spawnFallingBlock(me.getLocation().add(0.50, 0.00, 0.50), drop, data);
        }
    }

    private boolean supportingBlock(Material material) {
        switch (material) {
            case AIR:
            case FIRE:
            case WATER:
            case STATIONARY_WATER:
            case LAVA:
            case STATIONARY_LAVA:
                return false;
            default:
                return true;
        }
    }
}

@@ -1853,49 +1853,35 @@
     
-private boolean supportingBlock(M
+/**%0A     * @param m
 aterial 
 mate
@@ -1880,270 +1880,188 @@
 ial 
-m
+A M
 aterial
-) %7B
 %0A     
-   switch (material) %7B%0A            case AIR:%0A            case FIRE:%0A            case WATER:%0A            case STATIONARY_WATER:%0A            case LAVA:
+* @return true if material will support this block and prevent it from falling or breaking
 %0A     
-   
+*/%0A
     
-case STATIONARY_LAVA:%0A                return false;%0A            default:%0A  
+private boolean supportingBlock(Material material) %7B%0A
         
     
@@ -2060,36 +2060,34 @@
     
-      
 return 
-true;%0A        %7D
+material.isSolid();
 %0A   

Allow blocks to fall when placed directly on a non solid block (#1106)