// File: Lut99[P]RayTracer/src/lib/Renderer.cpp
// Function: RayTracer::Renderer::render_animation(RayTracer::RenderWorld*, RayTracer::Camera*, RayTracer::Frames&)
void Renderer::render_animation(RenderWorld* world, Camera* cam, Frames& out) {
    #ifdef THREADED
    ThreadPool pool(this->n_threads, this->batch_size);
    #endif

    for (std::size_t i = 0; i < out.n_frames; i++) {
        // Render this frame
        ProgressBar prgrs(0, cam->width * cam->height - 1, "(" + to_string(i + 1) + "/" + to_string(out.n_frames) + ")", "");

        #ifndef THREADED

        for (int y = cam->height-1; y >= 0; y--) {
            for (int x = 0; x < cam->width; x++) {
                // Render the pixel
                out[y][x] = world->render_pixel(x, y, *cam);

                if (this->show_progressbar) {
                    prgrs.update();
                }
            }
        }

        #else

        // Use the thread pool to render it
        unsigned long batch_index = 0;
        unsigned long to_do = cam->width * cam->height;
        while (batch_index < to_do) {
            // Update the progressbar in any case for smoothness
            if (this->show_progressbar) {
                prgrs.set(batch_index);
            }

            // If a the queue is full, continue
            if (pool.batch_queue_full()) {
                pool.wait();
            }

            // Create a new batch and append it
            PixelBatch batch = pool.get_batch(cam->width, cam->height, batch_index);
            batch.camera = cam;
            batch.world = world;
            batch.out = &out.get_current_frame();
            pool.add_batch(batch);
        }

        // Make sure the threads are complete
        pool.complete();

        #endif

        // Update the frames
        out.next();

        // Update the world & camera
        chrono::milliseconds time_passed(1000 / out.fps);
        world->update(time_passed);
        cam->update(time_passed);
    }

    #ifdef THREADED
    pool.stop();
    #endif
}

// Assembly:
subq $0x248, %rsp            # imm = 0x248
movq %rdi, 0x240(%rsp)
movq %rsi, 0x238(%rsp)
movq %rdx, 0x230(%rsp)
movq %rcx, 0x228(%rsp)
movq 0x240(%rsp), %rax
movq %rax, 0x30(%rsp)
movq $0x0, 0x220(%rsp)
movq 0x220(%rsp), %rax
movq 0x228(%rsp), %rcx
movl 0x44(%rcx), %ecx
cmpq %rcx, %rax
jae 0x139a24
movq 0x230(%rsp), %rcx
movl 0x8(%rcx), %eax
movl 0xc(%rcx), %ecx
imull %ecx, %eax
decl %eax
cltq
movq %rax, 0x20(%rsp)
movq 0x220(%rsp), %rsi
incq %rsi
leaq 0x100(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x12e250
movq 0x28(%rsp), %rdx
leaq 0x3cb4a(%rip), %rsi     # 0x176119
leaq 0x120(%rsp), %rdi
callq 0x12d820
jmp 0x1395de
leaq 0x3c959(%rip), %rdx     # 0x175f3e
leaq 0x140(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0xe6bb0
jmp 0x1395fc
movq 0x228(%rsp), %rax
movl 0x44(%rax), %esi
leaq 0xd0(%rsp), %rdi
callq 0x139a70
jmp 0x139616
leaq 0x160(%rsp), %rdi
leaq 0x140(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0x122650
jmp 0x139635
leaq 0x3a48f(%rip), %rdx     # 0x173acb
leaq 0x180(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0xe6bb0
jmp 0x139653
leaq 0xaf(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0xd0a20
movq 0x18(%rsp), %rdx
leaq 0x3817a(%rip), %rsi     # 0x1717eb
leaq 0xb0(%rsp), %rdi
callq 0xd8b80
jmp 0x139680
movq 0x20(%rsp), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x1a0(%rsp), %rdi
leaq 0x180(%rsp), %rcx
leaq 0xb0(%rsp), %r8
callq 0x160380
jmp 0x1396a8
leaq 0xb0(%rsp), %rdi
callq 0xd0b38
leaq 0xaf(%rsp), %rdi
callq 0xd0630
leaq 0x180(%rsp), %rdi
callq 0xd0b38
leaq 0x160(%rsp), %rdi
callq 0xd0b38
leaq 0xd0(%rsp), %rdi
callq 0xd0b38
leaq 0x140(%rsp), %rdi
callq 0xd0b38
leaq 0x120(%rsp), %rdi
callq 0xd0b38
leaq 0x100(%rsp), %rdi
callq 0xd0b38
movq 0x230(%rsp), %rax
movl 0xc(%rax), %eax
subl $0x1, %eax
movl %eax, 0xa8(%rsp)
cmpl $0x0, 0xa8(%rsp)
jl 0x139986
movl $0x0, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
movq 0x230(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x13996e
movq 0x238(%rsp), %rsi
movl 0xa4(%rsp), %edx
movl 0xa8(%rsp), %ecx
movq 0x230(%rsp), %r8
leaq 0x80(%rsp), %rdi
callq 0x162e30
jmp 0x139783
movq 0x228(%rsp), %rdi
movl 0xa8(%rsp), %esi
callq 0x13a630
movl %edx, 0xc(%rsp)
movq %rax, 0x10(%rsp)
jmp 0x1397a2
movl 0xc(%rsp), %eax
movq 0x10(%rsp), %rcx
movq %rcx, 0x58(%rsp)
movl %eax, 0x60(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0x70(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x68(%rsp)
movl 0xa4(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x13b160
movq %rax, (%rsp)
jmp 0x1397dd
movq (%rsp), %rax
movq %rax, 0x78(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x13b0e0
jmp 0x1397fa
movq 0x30(%rsp), %rax
testb $0x1, 0x8(%rax)
je 0x139956
leaq 0x1a0(%rsp), %rdi
movl $0x1, %esi
callq 0x160a50
jmp 0x13981d
jmp 0x139956
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x13991e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x139911
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x139904
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x1398f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x1398ea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x1398d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0xd0b38
leaq 0xaf(%rsp), %rdi
callq 0xd0630
leaq 0x180(%rsp), %rdi
callq 0xd0b38
leaq 0x160(%rsp), %rdi
callq 0xd0b38
leaq 0xd0(%rsp), %rdi
callq 0xd0b38
leaq 0x140(%rsp), %rdi
callq 0xd0b38
leaq 0x120(%rsp), %rdi
callq 0xd0b38
leaq 0x100(%rsp), %rdi
callq 0xd0b38
jmp 0x139a2c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x139a40
jmp 0x139a2c
jmp 0x139958
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0x13973e
jmp 0x139970
movl 0xa8(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xa8(%rsp)
jmp 0x139725
movq 0x228(%rsp), %rdi
callq 0x13a420
jmp 0x139995
movq 0x228(%rsp), %rax
movl 0x48(%rax), %ecx
xorl %edx, %edx
movl $0x3e8, %eax            # imm = 0x3E8
divl %ecx
movl %eax, 0x4c(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x4c(%rsp), %rsi
callq 0x139b70
jmp 0x1399be
movq 0x238(%rsp), %rdi
movq 0x50(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rsi
callq 0x162f90
jmp 0x1399dc
movq 0x230(%rsp), %rdi
movq 0x50(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rsi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x1399fe
leaq 0x1a0(%rsp), %rdi
callq 0x139a40
movq 0x220(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x220(%rsp)
jmp 0x139570
addq $0x248, %rsp            # imm = 0x248
retq
movq 0xf8(%rsp), %rdi
callq 0xd0a10
nopl (%rax)