package common.block;

import common.block.natural.BlockFire;
import common.entity.item.EntityFalling;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import common.vars.Vars;
import common.world.State;
import common.world.World;
import common.world.AWorldServer;

public class BlockFalling extends Block {
	public static boolean fallInstantly;

	public static boolean canFallInto(World world, BlockPos pos) {
		Block block = world.getState(pos).getBlock();
		return block instanceof BlockFire || block == Blocks.air || block.getMaterial().isLiquid();
	}

	public BlockFalling(Material material) {
		super(material);
	}

	public void onBlockAdded(AWorldServer world, BlockPos pos, State state) {
		world.scheduleUpdate(pos, this, this.tickRate(world, pos));
	}

	public void onNeighborBlockChange(World world, BlockPos pos, State state, Block neighbor) {
		world.scheduleUpdate(pos, this, this.tickRate(world, pos));
	}

	public void updateTick(AWorldServer world, BlockPos pos, State state, Random rand) {
		if(Vars.blockGravity)
			this.checkFallable(world, pos);
	}

	private void checkFallable(World world, BlockPos pos) {
		if(canFallInto(world, pos.down()) && pos.getY() >= 0) {
			int range = 32;
			if(!fallInstantly && world.isAreaLoaded(pos.add(-range, -range, -range), pos.add(range, range, range))) {
				if(!world.client) {
					EntityFalling entity = new EntityFalling(world, (double)pos.getX() + 0.5D, (double)pos.getY(),
							(double)pos.getZ() + 0.5D, world.getState(pos));
					this.onStartFalling(entity);
					world.spawnEntityInWorld(entity);
				}
			}
			else {
				world.setBlockToAir(pos);
				BlockPos loc;
				int limit = 512;
				for(loc = pos.down(); canFallInto(world, loc) && loc.getY() > -World.MAX_SIZE_Y; loc = loc.down()) {
					if(--limit <= 0)
						return;
				}
				if(loc.getY() > -World.MAX_SIZE_Y)
					world.setState(loc.up(), this.getState());
			}
		}
	}

	public int tickRate(World world, BlockPos pos) {
		return 2;
	}

	protected void onStartFalling(EntityFalling entity) {
	}

	public void onEndFalling(World world, BlockPos pos) {
	}
}
