// File: IsseW[P]bytepusher/src/main.cpp
// Function: main
int main(){
    Renderer renderer{"some title", GRID_WIDTH, GRID_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT};

    Grid grid = Grid(GRID_WIDTH, GRID_HEIGHT);
    grid.set_tile(4, 4, Tile::Alive);
    grid.set_tile(4, 5, Tile::Alive);
    grid.set_tile(4, 6, Tile::Alive);
    grid.set_tile(4, 7, Tile::Alive);
    grid.set_tile(4, 8, Tile::Alive);
    grid.set_tile(4, 9, Tile::Alive);
    grid.set_tile(4, 10, Tile::Alive);

    uint64_t now, last;
    double delta_time = 0;

    double next_tick = TICK_TIME;

    auto callback = [&](const SDL_Event& e) {
        switch (e.type) {
            case SDL_MOUSEBUTTONDOWN: {
                uint32_t x = e.button.x * GRID_WIDTH / WINDOW_WIDTH;
                uint32_t y = e.button.y * GRID_HEIGHT / WINDOW_HEIGHT;
                switch (e.button.button) {
                    case SDL_BUTTON_LEFT:
                        grid.set_tile(x, y, Tile::Alive);
                        break;
                    
                }
                break;
            }
        }
    };
    renderer.set_manual_event_handler(callback);

    while(renderer.poll_events()) {
        last = now;
        now = SDL_GetPerformanceCounter();
        delta_time = (now - last) / (double)SDL_GetPerformanceFrequency();

        next_tick -= delta_time;
        if (next_tick < 0.0) {
            next_tick = TICK_TIME;
            grid.update_with_rule(game_of_life_rule);
        }

        renderer.bulk_send_data(grid.get_texture());
        renderer.finalize();
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movl $0x0, -0x4(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0x100(%rbp)
callq 0x22c0
movq -0x100(%rbp), %rdx
leaq 0x2bd9(%rip), %rsi      # 0x504c
leaq -0x80(%rbp), %rdi
callq 0x2c80
jmp 0x247e
leaq -0x60(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movl $0x20, %ecx
movl $0x140, %r9d            # imm = 0x140
movl %ecx, %edx
movl %r9d, %r8d
callq 0x3f40
jmp 0x249d
leaq -0x80(%rbp), %rdi
callq 0x20f0
leaq -0x81(%rbp), %rdi
callq 0x21d0
leaq -0xb0(%rbp), %rdi
movl $0x20, %edx
movl %edx, %esi
callq 0x32b0
jmp 0x24c7
leaq -0xb0(%rbp), %rdi
movl $0x4, %edx
movl $0xff, %ecx
movq %rdx, %rsi
callq 0x3440
jmp 0x24e2
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0x5, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x24ff
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0x6, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x251c
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0x7, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x2539
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0x8, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x2556
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0x9, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x2573
leaq -0xb0(%rbp), %rdi
movl $0x4, %esi
movl $0xa, %edx
movl $0xff, %ecx
callq 0x3440
jmp 0x2590
movq $0x0, -0xc8(%rbp)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0xd0(%rbp)
leaq -0xb0(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xf8(%rbp), %rdi
movq %rdi, -0x108(%rbp)
leaq -0xd8(%rbp), %rsi
callq 0x2830
movq -0x108(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x3f10
jmp 0x25e6
leaq -0xf8(%rbp), %rdi
callq 0x2d30
leaq -0x60(%rbp), %rdi
callq 0x4190
movb %al, -0x109(%rbp)
jmp 0x2603
movb -0x109(%rbp), %al
testb $0x1, %al
jne 0x2612
jmp 0x27e6
movq -0xb8(%rbp), %rax
movq %rax, -0xc0(%rbp)
callq 0x2250
movq %rax, -0x118(%rbp)
jmp 0x262e
movq -0x118(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq -0xc0(%rbp), %rcx
subq %rcx, %rax
movq %rax, %xmm0
movaps 0x29b7(%rip), %xmm1     # 0x5010
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x29bb(%rip), %xmm1     # 0x5020
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, -0x128(%rbp)
callq 0x2180
movq %rax, -0x120(%rbp)
jmp 0x268a
movsd -0x128(%rbp), %xmm0
movq -0x120(%rbp), %rax
movq %rax, %xmm1
movaps 0x296b(%rip), %xmm2     # 0x5010
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x296f(%rip), %xmm2     # 0x5020
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd -0xc8(%rbp), %xmm1
movsd -0xd0(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0xd0(%rbp)
xorps %xmm0, %xmm0
ucomisd -0xd0(%rbp), %xmm0
jbe 0x27af
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0xd0(%rbp)
leaq 0x162f(%rip), %rsi      # 0x3d40
leaq -0xb0(%rbp), %rdi
callq 0x3390
jmp 0x271f
jmp 0x27af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x2753
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x20f0
leaq -0x81(%rbp), %rdi
callq 0x21d0
jmp 0x281c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x2813
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x2807
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x2d30
jmp 0x2807
leaq -0xb0(%rbp), %rdi
callq 0x3720
movq %rax, -0x130(%rbp)
jmp 0x27c4
movq -0x130(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x4090
jmp 0x27d6
leaq -0x60(%rbp), %rdi
callq 0x4120
jmp 0x27e1
jmp 0x25f2
leaq -0xb0(%rbp), %rdi
callq 0x2d50
leaq -0x60(%rbp), %rdi
callq 0x4010
movl -0x4(%rbp), %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
leaq -0xb0(%rbp), %rdi
callq 0x2d50
leaq -0x60(%rbp), %rdi
callq 0x4010
movq -0x90(%rbp), %rdi
callq 0x22b0
nopl (%rax,%rax)