// File: /workspace/github_cpp_makefile_star2_O1/miklhh[P]tetris/src/game.cpp
// Function: test_movable(block_t*, int)
collision_t test_movable(block_t* block, direction_t direction)
{
	/* Make a copy of the block and move it. */
	block_t block_copy = *block;
	block_move(&block_copy, direction);

	/* Test if the block interfears with any other placed box, or wall. */
	collision_t collision = NO_COLLISION;

	/* Test collision with other boxes. */
	for (int y = 0; y < MAX_BLOCK_WIDTH; y++)
	{
		for (int x = 0; x < MAX_BLOCK_HEIGHT; x++)
		{
			if (block_copy.structure.tile[y][x] == FILLED   &&
				field[y + block_copy.position.y][x + block_copy.position.x].tile == TAKEN)
			{
				collision = COLLISION_BLOCK;
			}
		}
	}

	/* Test collision with wall. */
	switch (direction)
	{
	case DIRECTION_LEFT:
		/* Test for collision with left side wall. */
		for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
		{
			for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
			{
				if (block_copy.structure.tile[y][x] == FILLED   &&
					x + block_copy.position.x < 0)
				{
					collision = COLLISION_WALL_R;
				}
			}
		}
		break;

	case DIRECTION_RIGHT:
		/* Test for collision with the right side wall. */
		for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
		{
			for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
			{
				if (block_copy.structure.tile[y][x] == FILLED   &&
					x + block_copy.position.x > GRID_WIDTH - 1)
				{
					collision = COLLISION_WALL_R;
				}
			}
		}
		break;
		
	case DIRECTION_UP:
		/* Test for collision with the upper side wall. */
		for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
		{
			for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
			{
				if (block_copy.structure.tile[y][x] == FILLED   &&
					y + block_copy.position.y < 0)
				{
					collision = COLLISION_WALL_U;
				}
			}
		}
		break;

	case DIRECTION_DOWN:
		/* Test for collision the the lower side wall. */
		for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
		{
			for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
			{
				if (block_copy.structure.tile[y][x] == FILLED   &&
					y + block_copy.position.y > GRID_HEIGHT - 1)
				{
					collision = COLLISION_WALL_D;
				}
			}
		}
		break;

	default:
		break;
	}
	return collision;
}

// Assembly:
pushq %rbx
subq $0x50, %rsp
movl %esi, %ebx
movq %rdi, %rsi
movq %rsp, %rax
movl $0x14, %ecx
movq %rax, %rdi
rep  movsl (%rsi), %es:(%rdi)
movq %rax, %rdi
movl %ebx, %esi
callq 0x29d6
leaq 0x10(%rsp), %rcx
movslq -0x4(%rcx), %rax
movslq -0x8(%rcx), %rdx
imulq $0x78, %rax, %rax
leaq (%rdx,%rdx,2), %rdx
leaq (%rax,%rdx,4), %rax
leaq 0x34fd(%rip), %rdx      # 0x6170
addq %rax, %rdx
addq $0x8, %rdx
xorl %esi, %esi
movl $0x5, %edi
xorl %eax, %eax
movq %rdx, %r8
xorl %r9d, %r9d
cmpl $0x1, (%rcx,%r9,4)
jne 0x2c97
cmpl $0x1, (%r8)
cmovel %edi, %eax
incq %r9
addq $0xc, %r8
cmpq $0x4, %r9
jne 0x2c89
incq %rsi
addq $0x78, %rdx
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2c83
cmpl $0x3, %ebx
ja 0x2dde
movl %ebx, %ecx
leaq 0x13b1(%rip), %rdx      # 0x4078
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
leaq 0x10(%rsp), %rcx
movslq -0x8(%rcx), %rdx
negq %rdx
xorl %esi, %esi
movl $0x2, %edi
xorl %r8d, %r8d
movl %eax, %r9d
cmpq %rdx, %r8
cmovll %edi, %eax
cmpl $0x1, (%rcx,%r8,4)
cmovnel %r9d, %eax
incq %r8
cmpq $0x4, %r8
jne 0x2ce6
incq %rsi
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2ce3
jmp 0x2dde
leaq 0x10(%rsp), %rcx
movslq -0x4(%rcx), %rdx
negq %rdx
xorl %esi, %esi
movl $0x3, %edi
xorl %r8d, %r8d
movl %eax, %r9d
cmpq %rdx, %rsi
cmovll %edi, %eax
cmpl $0x1, (%rcx,%r8,4)
cmovnel %r9d, %eax
incq %r8
cmpq $0x4, %r8
jne 0x2d29
incq %rsi
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2d26
jmp 0x2dde
leaq 0x10(%rsp), %rcx
movslq -0x4(%rcx), %rsi
movl $0x13, %edx
subq %rsi, %rdx
xorl %esi, %esi
movl $0x4, %edi
xorl %r8d, %r8d
movl %eax, %r9d
cmpq %rdx, %rsi
cmovgl %edi, %eax
cmpl $0x1, (%rcx,%r8,4)
cmovnel %r9d, %eax
incq %r8
cmpq $0x4, %r8
jne 0x2d71
incq %rsi
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2d6e
jmp 0x2dde
leaq 0x10(%rsp), %rcx
movslq -0x8(%rcx), %rsi
movl $0x9, %edx
subq %rsi, %rdx
xorl %esi, %esi
movl $0x2, %edi
xorl %r8d, %r8d
movl %eax, %r9d
cmpq %rdx, %r8
cmovgl %edi, %eax
cmpl $0x1, (%rcx,%r8,4)
cmovnel %r9d, %eax
incq %r8
cmpq $0x4, %r8
jne 0x2db6
incq %rsi
addq $0x10, %rcx
cmpq $0x4, %rsi
jne 0x2db3
addq $0x50, %rsp
popq %rbx
retq