// File: miklhh[P]tetris/src/game.cpp
// Function: iterate_game()
bool iterate_game()
{
    /* Test if the game already set to game-over. */
    if (game_over)
    {
        delete current_block;
        delete next_block;
        return false;
    }

    /* Test if the game just ended. */
    //TODO: Implement later. Don't forget to remove (delete) all blocks.

    /* If the block hits the ground. */
    if (test_movable(current_block, DIRECTION_DOWN) != NO_COLLISION)
    {
        std::cout << "CRACH" << std::endl;
        for (int y = 0; y < MAX_BLOCK_HEIGHT; y++)
        {
            for (int x = 0; x < MAX_BLOCK_WIDTH; x++)
            {
                if (current_block->structure.tile[y][x] == FILLED)
                {
                    field[y + current_block->position.y][x + current_block->position.x].tile = FILLED;
                    field[y + current_block->position.y][x + current_block->position.x].color_b = COLOR_BLOCK_BACKGROUND;
                    field[y + current_block->position.y][x + current_block->position.x].color_f = current_block->color;
                }
            }
        }

        /* Test and remove posible full rows */
        for (int y1 = 0; y1 < GRID_HEIGHT; y1++)
        {
            /* Test if the row 'y1' is full. If it is, test how many row under 'y1'
            * which also is full. */
            if (test_row_full(y1))
            {
                int   row = y1;
                int   n = 1;
                bool  one_found = false;
                for (int y2 = y1; y2 < GRID_HEIGHT; y2++)
                {
                    bool row_full = test_row_full(y2);
                    if (row_full)
                    {
                        n = y2 - y1 + 1;
                        one_found = true;
                    }
                    if (one_found && !row_full)
                        break;
                }

                /* The appropriate rows to remove and the amount of rows under it
                * has been found. Remove accordingly and move field down. */
                for (int y = y1; y < y1 + n; y++)
                {
                    remove_row(y);
                }

                /* Move down the pieces above it and break out of loop. */
                move_field_down(y1, n);
                break;
            }
        }

        /* Remove the old block and prepare a new one. */
        delete current_block;
        current_block   = next_block;
        next_block      = block_spawn();
        return false;
    }

    /* The block hasn't landed. Move it downward a step and continue the game. */
    block_move(current_block, DIRECTION_DOWN);
    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
testb $0x1, 0x54d1(%rip)      # 0x8ad0
je 0x3648
movq 0x54d0(%rip), %rax      # 0x8ad8
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
je 0x3620
movq -0x30(%rbp), %rdi
movl $0x50, %esi
callq 0x21c0
movq 0x54b9(%rip), %rax      # 0x8ae0
movq %rax, -0x38(%rbp)
cmpq $0x0, %rax
je 0x363f
movq -0x38(%rbp), %rdi
movl $0x50, %esi
callq 0x21c0
movb $0x0, -0x1(%rbp)
jmp 0x38c7
movq 0x5489(%rip), %rdi      # 0x8ad8
movl $0x3, %esi
callq 0x3010
cmpl $0x0, %eax
je 0x38b2
movq 0x496f(%rip), %rdi      # 0x7fd8
leaq 0x1ca3(%rip), %rsi      # 0x5313
callq 0x21a0
movq %rax, %rdi
movq 0x4949(%rip), %rsi      # 0x7fc8
callq 0x21d0
movl $0x0, -0x8(%rbp)
cmpl $0x4, -0x8(%rbp)
jge 0x37a2
movl $0x0, -0xc(%rbp)
cmpl $0x4, -0xc(%rbp)
jge 0x3792
movq 0x542b(%rip), %rax      # 0x8ad8
addq $0x10, %rax
movslq -0x8(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movslq -0xc(%rbp), %rcx
cmpl $0x1, (%rax,%rcx,4)
jne 0x3782
movl -0x8(%rbp), %eax
movq 0x5404(%rip), %rcx      # 0x8ad8
addl 0xc(%rcx), %eax
movslq %eax, %rcx
leaq 0x4a8f(%rip), %rax      # 0x8170
imulq $0x78, %rcx, %rcx
addq %rcx, %rax
movl -0xc(%rbp), %ecx
movq 0x53e6(%rip), %rdx      # 0x8ad8
addl 0x8(%rdx), %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl $0x1, 0x8(%rax)
movl -0x8(%rbp), %eax
movq 0x53c8(%rip), %rcx      # 0x8ad8
addl 0xc(%rcx), %eax
movslq %eax, %rcx
leaq 0x4a53(%rip), %rax      # 0x8170
imulq $0x78, %rcx, %rcx
addq %rcx, %rax
movl -0xc(%rbp), %ecx
movq 0x53aa(%rip), %rdx      # 0x8ad8
addl 0x8(%rdx), %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl $0x8, 0x4(%rax)
movq 0x538f(%rip), %rax      # 0x8ad8
movl (%rax), %ecx
movl -0x8(%rbp), %eax
movq 0x5383(%rip), %rdx      # 0x8ad8
addl 0xc(%rdx), %eax
movslq %eax, %rdx
leaq 0x4a0e(%rip), %rax      # 0x8170
imulq $0x78, %rdx, %rdx
addq %rdx, %rax
movl -0xc(%rbp), %edx
movq 0x5365(%rip), %rsi      # 0x8ad8
addl 0x8(%rsi), %edx
movslq %edx, %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
jmp 0x3784
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x369c
jmp 0x3794
movl -0x8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8(%rbp)
jmp 0x368b
movl $0x0, -0x10(%rbp)
cmpl $0x14, -0x10(%rbp)
jge 0x3862
movl -0x10(%rbp), %edi
callq 0x3480
testb $0x1, %al
jne 0x37c4
jmp 0x3852
movl -0x10(%rbp), %eax
movl %eax, -0x14(%rbp)
movl $0x1, -0x18(%rbp)
movb $0x0, -0x19(%rbp)
movl -0x10(%rbp), %eax
movl %eax, -0x20(%rbp)
cmpl $0x14, -0x20(%rbp)
jge 0x381f
movl -0x20(%rbp), %edi
callq 0x3480
andb $0x1, %al
movb %al, -0x21(%rbp)
testb $0x1, -0x21(%rbp)
je 0x3804
movl -0x20(%rbp), %eax
subl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movb $0x1, -0x19(%rbp)
testb $0x1, -0x19(%rbp)
je 0x3812
testb $0x1, -0x21(%rbp)
jne 0x3812
jmp 0x381f
jmp 0x3814
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x37db
movl -0x10(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl -0x10(%rbp), %ecx
addl -0x18(%rbp), %ecx
cmpl %ecx, %eax
jge 0x3845
movl -0x28(%rbp), %edi
callq 0x32d0
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3825
movl -0x10(%rbp), %edi
movl -0x18(%rbp), %esi
callq 0x3360
jmp 0x3862
jmp 0x3854
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x37a9
movq 0x526f(%rip), %rax      # 0x8ad8
movq %rax, -0x40(%rbp)
cmpq $0x0, %rax
je 0x3881
movq -0x40(%rbp), %rdi
movl $0x50, %esi
callq 0x21c0
movq 0x5258(%rip), %rax      # 0x8ae0
movq %rax, 0x5249(%rip)      # 0x8ad8
movl $0x7, %edi
movl $0x4, %esi
xorl %edx, %edx
movl $0x3, %ecx
callq 0x29c0
movq %rax, 0x5234(%rip)      # 0x8ae0
movb $0x0, -0x1(%rbp)
jmp 0x38c7
movq 0x521f(%rip), %rdi      # 0x8ad8
movl $0x3, %esi
callq 0x2b80
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)