// File: miklhh[P]tetris/src/main.cpp
// Function: main
int main(int argc, char* argv[])
{
    /* Intialize SDL. */
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        std::cout << "Failed to initialize SDL... Exiting." << std::endl;
        exit_game(NULL, NULL);
    }

	/* Aquire the monitor size and set the window size variables. */
	#define MONITOR_0 0
	SDL_GetCurrentDisplayMode(MONITOR_0, &display_mode);
	window_height   = get_window_height(display_mode);
	window_width    = get_window_width(display_mode);
	block_width     = window_width / 20;
	block_height    = window_height / 20;

	/* Initialize the window. */
	window = SDL_CreateWindow(
		"Tetris", 
		SDL_WINDOWPOS_UNDEFINED, 
		SDL_WINDOWPOS_UNDEFINED, 
		window_width, 
		window_height,
		NULL
	);
	if (window == NULL)
	{
		std::cout << "Failed to create a window... Exiting." << std::endl;
		exit_game(NULL, NULL);
	}

	/* Intialize the renderer. */
	#define FIRST_RENDERING_DEVICE -1
	renderer = SDL_CreateRenderer(
		window,
		FIRST_RENDERING_DEVICE,
		SDL_RENDERER_ACCELERATED
	);
	if (renderer == NULL)
	{
		std::cout << "Failed to create a renderer... Exiting." << std::endl;
		exit_game(window, NULL);
	}



	/* Initialize random seed, and setup the game. */
	srand((unsigned int)time(NULL));
	setup_game();

	/* Print screen and window information. */
	std::cout << "Screen-width: "   << display_mode.w   << ", Screen-height: "  << display_mode.h   << std::endl;
	std::cout << "Window-width: "   << window_width     << ", Window-height: "  << window_height    << std::endl;
	std::cout << "Block-width: "    << block_width      << ", Block-height: "   << block_height     << std::endl;

	/* DEBUGING TIMINGS, REMOVE LATER ON. */
	using namespace std::chrono;
	time_point<high_resolution_clock> t1;
	time_point<high_resolution_clock> t2;
	/* DEBUGING TIMINGS, REMOVE LATER ON. */

	bool is_running = true;
	while (is_running)
	{
		/* DEBUGING TIMINGS, REMOVE LATER ON. */
		t1 = high_resolution_clock::now();
		/* DEBUGING TIMINGS, REMOVE LATER ON. */

		/* Clear the screen. */
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
		SDL_RenderClear(renderer);

		/* Replace with real timer instead. */
		if (iteration_timer())
		{ 
            iterate_game();
		}


        game_draw_field();
        game_draw_current_block();
		SDL_RenderPresent(renderer);

		while (SDL_PollEvent(&events))
		{
            if (events.type == SDL_QUIT)
                is_running = false;
            else
                handle_event(&events);
		}

        static keyboard_state_t* keyboard_state = SDL_GetKeyboardState(NULL);
        handle_keyboard_input(keyboard_state);

		/* DEBUGING TIMINGS, REMOVE LATER ON. */
		t2 = high_resolution_clock::now();
		std::cout << "Iteration time: " << duration_cast<microseconds>(t2 - t1).count() << " microseconds." << std::endl;
		/* DEBUGING TIMINGS, REMOVE LATER ON. */

		/* Later we want a total time of 10 milliseconds per iteration. Game updates 100 times a seconds.*/
		SDL_Delay(10);
	}
	

	exit_game(window, renderer);
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xf231, %edi           # imm = 0xF231
callq 0x2160
cmpl $0x0, %eax
jge 0x4186
movq 0x3e79(%rip), %rdi      # 0x7fd8
leaq 0x11b3(%rip), %rsi      # 0x5319
callq 0x21a0
movq %rax, %rdi
movq 0x3e53(%rip), %rsi      # 0x7fc8
callq 0x21d0
xorl %eax, %eax
movl %eax, %esi
movq %rsi, %rdi
callq 0x2800
xorl %edi, %edi
leaq 0x4991(%rip), %rsi      # 0x8b20
callq 0x20d0
movq 0x4985(%rip), %rax      # 0x8b20
movq %rax, -0x28(%rbp)
movq 0x4982(%rip), %rax      # 0x8b28
movq %rax, -0x20(%rbp)
movq 0x497f(%rip), %rax      # 0x8b30
movq %rax, -0x18(%rbp)
leaq -0x28(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x3dd0
movl %eax, 0x49a7(%rip)      # 0x8b84
movq 0x493c(%rip), %rax      # 0x8b20
movq %rax, -0x40(%rbp)
movq 0x4939(%rip), %rax      # 0x8b28
movq %rax, -0x38(%rbp)
movq 0x4936(%rip), %rax      # 0x8b30
movq %rax, -0x30(%rbp)
leaq -0x40(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x3e30
movl %eax, 0x495a(%rip)      # 0x8b80
movl 0x4954(%rip), %eax      # 0x8b80
movl $0x14, %ecx
cltd
idivl %ecx
movl %eax, 0x494e(%rip)      # 0x8b88
movl 0x4944(%rip), %eax      # 0x8b84
movl $0x14, %ecx
cltd
idivl %ecx
movl %eax, 0x493e(%rip)      # 0x8b8c
movl 0x492c(%rip), %ecx      # 0x8b80
movl 0x4929(%rip), %r8d      # 0x8b84
leaq 0x10dc(%rip), %rdi      # 0x533e
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
xorl %r9d, %r9d
movl %edx, %esi
callq 0x2050
movq %rax, 0x48f8(%rip)      # 0x8b70
cmpq $0x0, 0x48f0(%rip)      # 0x8b70
jne 0x42b0
movq 0x3d4f(%rip), %rdi      # 0x7fd8
leaq 0x10b5(%rip), %rsi      # 0x5345
callq 0x21a0
movq %rax, %rdi
movq 0x3d29(%rip), %rsi      # 0x7fc8
callq 0x21d0
xorl %eax, %eax
movl %eax, %esi
movq %rsi, %rdi
callq 0x2800
movq 0x48b9(%rip), %rdi      # 0x8b70
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0x2, %edx
callq 0x2040
movq %rax, 0x48ab(%rip)      # 0x8b78
cmpq $0x0, 0x48a3(%rip)      # 0x8b78
jne 0x4309
movq 0x3cfa(%rip), %rdi      # 0x7fd8
leaq 0x1086(%rip), %rsi      # 0x536b
callq 0x21a0
movq %rax, %rdi
movq 0x3cd4(%rip), %rsi      # 0x7fc8
callq 0x21d0
movq 0x4870(%rip), %rdi      # 0x8b70
xorl %eax, %eax
movl %eax, %esi
callq 0x2800
xorl %eax, %eax
movl %eax, %edi
callq 0x2170
movl %eax, %edi
callq 0x2190
callq 0x28b0
movq 0x3cb3(%rip), %rdi      # 0x7fd8
leaq 0x1067(%rip), %rsi      # 0x5393
callq 0x21a0
movq %rax, %rdi
movl 0x47ea(%rip), %esi      # 0x8b24
callq 0x2210
movq %rax, %rdi
leaq 0x1059(%rip), %rsi      # 0x53a2
callq 0x21a0
movq %rax, %rdi
movl 0x47d1(%rip), %esi      # 0x8b28
callq 0x2210
movq %rax, %rdi
movq 0x3c62(%rip), %rsi      # 0x7fc8
callq 0x21d0
movq 0x3c66(%rip), %rdi      # 0x7fd8
leaq 0x103b(%rip), %rsi      # 0x53b4
callq 0x21a0
movq %rax, %rdi
movl 0x47f9(%rip), %esi      # 0x8b80
callq 0x2210
movq %rax, %rdi
leaq 0x102d(%rip), %rsi      # 0x53c3
callq 0x21a0
movq %rax, %rdi
movl 0x47e0(%rip), %esi      # 0x8b84
callq 0x2210
movq %rax, %rdi
movq 0x3c15(%rip), %rsi      # 0x7fc8
callq 0x21d0
movq 0x3c19(%rip), %rdi      # 0x7fd8
leaq 0x100f(%rip), %rsi      # 0x53d5
callq 0x21a0
movq %rax, %rdi
movl 0x47b4(%rip), %esi      # 0x8b88
callq 0x2210
movq %rax, %rdi
leaq 0x1000(%rip), %rsi      # 0x53e3
callq 0x21a0
movq %rax, %rdi
movl 0x479b(%rip), %esi      # 0x8b8c
callq 0x2210
movq %rax, %rdi
movq 0x3bc8(%rip), %rsi      # 0x7fc8
callq 0x21d0
leaq -0x48(%rbp), %rdi
callq 0x45e0
leaq -0x50(%rbp), %rdi
callq 0x45e0
movb $0x1, -0x51(%rbp)
testb $0x1, -0x51(%rbp)
je 0x45b1
callq 0x2060
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
movq 0x473b(%rip), %rdi      # 0x8b78
xorl %r8d, %r8d
movl %r8d, %esi
movl %r8d, %edx
movl %r8d, %ecx
callq 0x21f0
movq 0x4723(%rip), %rdi      # 0x8b78
callq 0x2180
callq 0x38e0
testb $0x1, %al
jne 0x4465
jmp 0x446a
callq 0x35f0
callq 0x3510
callq 0x34e0
movq 0x46fd(%rip), %rdi      # 0x8b78
callq 0x2080
leaq 0x46b1(%rip), %rdi      # 0x8b38
callq 0x20f0
cmpl $0x0, %eax
je 0x44b1
cmpl $0x100, 0x469d(%rip)    # imm = 0x100
jne 0x44a3
movb $0x0, -0x51(%rbp)
jmp 0x44af
leaq 0x468e(%rip), %rdi      # 0x8b38
callq 0x3e90
jmp 0x4480
cmpb $0x0, 0x46e0(%rip)      # 0x8b98
jne 0x44f7
leaq 0x46d7(%rip), %rdi      # 0x8b98
callq 0x2230
cmpl $0x0, %eax
je 0x44f7
xorl %eax, %eax
movl %eax, %edi
callq 0x2250
movq %rax, -0x90(%rbp)
jmp 0x44dd
movq -0x90(%rbp), %rax
movq %rax, 0x46a5(%rip)      # 0x8b90
leaq 0x46a6(%rip), %rdi      # 0x8b98
callq 0x2110
movq 0x4692(%rip), %rdi      # 0x8b90
callq 0x3f80
callq 0x2060
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x50(%rbp)
movq 0x3abd(%rip), %rdi      # 0x7fd8
leaq 0xed2(%rip), %rsi       # 0x53f4
callq 0x21a0
movq %rax, -0x98(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3c30
movq %rax, -0x88(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x4610
movq %rax, -0x80(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x4640
movq -0x98(%rbp), %rdi
movq %rax, %rsi
callq 0x2240
movq %rax, %rdi
leaq 0xe91(%rip), %rsi       # 0x5405
callq 0x21a0
movq %rax, %rdi
movq 0x3a45(%rip), %rsi      # 0x7fc8
callq 0x21d0
movl $0xa, %edi
callq 0x2120
jmp 0x441b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq 0x45ee(%rip), %rdi      # 0x8b98
callq 0x2100
jmp 0x45cf
movq 0x45b8(%rip), %rdi      # 0x8b70
movq 0x45b9(%rip), %rsi      # 0x8b78
callq 0x2800
xorl %eax, %eax
addq $0xb0, %rsp
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x2220
nopl (%rax,%rax)