// File: /workspace/github_cpp_makefile_star2_O2/therealgymmy[P]HelicopterGame/src/events.cpp
// Function: events(void*)
void pollForEvents (EventsArg *eventsArg) {
    Resources       *resources = eventsArg->resources_;
    XHandler        *xhandler  = eventsArg->xhandler_;
    pthread_mutex_t *mutex     = eventsArg->mutex_;

    Display *display = xhandler->display();
    Window   window  = xhandler->window();
    XSelectInput(display, window,
                 KeyPressMask |
                 KeyReleaseMask |
                 StructureNotifyMask);

    Helicopter &helicopter = resources->heli_;
    KeySym key;
    XWindowAttributes attr;

    XEvent event;
    while (true) {
        XNextEvent(display, &event);

        if (pthread_mutex_lock(mutex) == -1) {
            error("cannot lock mutex in control thread");
        }

        switch (event.type) {
            case ConfigureNotify:
                if (event.xconfigure.width  != attr.width ||
                        event.xconfigure.height != attr.height) {
                    XGetWindowAttributes(display, window, &attr);

                    attr::DrawableBase::ScaleX = (double)PLANE_W / (double)attr.width;
                    attr::DrawableBase::ScaleY = (double)PLANE_H / (double)attr.height;

                    std::cout << attr::DrawableBase::ScaleX << std::endl;
                    std::cout << attr::DrawableBase::ScaleY << std::endl;
                    std::cout << "w: " << attr.width << std::endl;
                    std::cout << "h: " << attr.height << std::endl;

                    xhandler->updateAttr(&attr);
                }

                break;

            case KeyPress:
                XLookupString(&event.xkey, NULL, 0, &key, NULL);
                switch (key) {
                    case XK_f:
                        if (xhandler->showCredit()) {
                            xhandler->setShowCredit(false);
                        }
                        else {
                            xhandler->setShowCredit(true);
                        }
                        break;

                    case XK_Up:
                        helicopter.up_ = true;
                        break;
                    case XK_Down:
                        helicopter.down_ = true;
                        break;
                    case XK_Left:
                        helicopter.left_ = true;
                        break;
                    case XK_Right:
                        helicopter.right_ = true;
                        break;

                    case XK_a:
                        Tower::incSpeed();
                        Missile::incSpeed();
                        break;
                    case XK_z:
                        Tower::decSpeed();
                        Missile::decSpeed();
                        break;

                    /*
                    case XK_q:  // slow down scroll speed
                        Tower::incDelay(1);
                        Missile::incDelay(1);
                        Bomb::incDelay(2);
                        break;
                    case XK_w:  // speed up scroll speed
                        Tower::decDelay(1);
                        Missile::decDelay(1);
                        Bomb::decDelay(2);
                        break;

                    */
                    case XK_d:
                        if (helicopter.right_) {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::FORWARD);
                        }
                        else if (helicopter.left_) {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::BACKWARD);
                        }
                        else {
                            int x = helicopter.x() + helicopter.w() * 0.8;
                            int y = helicopter.y() + helicopter.h() * 0.8;
                            resources->bombs_.addBomb(x,
                                                      y,
                                                      Bomb::NUL);
                        }

                        /*
                        if (helicopter.movement() == Helicopter::LEFT) {
                            resources->bombs_.push_back(
                                    Bomb(
                                        helicopter.x() + Helicopter::w(),
                                        helicopter.y() + Helicopter::h(),
                                        false));
                        }
                        else {
                            resources->bombs_.push_back(
                                    Bomb(
                                        helicopter.x() + Helicopter::w(),
                                        helicopter.y() + Helicopter::h(),
                                        true));
                        }
                        */
                        break;

                    default:
                        break;
                }
                break;

            case KeyRelease:
                XLookupString(&event.xkey, NULL, 0, &key, NULL);
                switch (key) {
                    case XK_Up:
                        helicopter.up_ = false;
                        helicopter.delayUp_ = 30;
                        break;
                    case XK_Down:
                        helicopter.down_ = false;
                        helicopter.delayDown_ = 30;
                        break;
                    case XK_Left:
                        helicopter.left_ = false;
                        helicopter.delayLeft_ = 30;
                        break;
                    case XK_Right:
                        helicopter.right_ = false;
                        helicopter.delayRight_ = 30;
                        break;
                    default:
                        break;
                }
                break;

            default:
                break;

        }

        if (pthread_mutex_unlock(mutex) == -1) {
            error("cannot unlock mutex in control thread");
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq (%rdi), %rbx
movq 0x8(%rdi), %rax
movq 0x10(%rdi), %r15
movq 0x8(%rax), %r12
movq %rax, 0x18(%rsp)
movq 0x18(%rax), %rsi
movl $0x20003, %edx          # imm = 0x20003
movq %r12, %rdi
movq %rsi, 0x28(%rsp)
callq 0x2100
leaq 0xf8(%rsp), %rbp
leaq 0x50(%rsp), %r13
leaq 0x30(%rsp), %r14
movq %r12, 0x20(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2280
movq %r15, %rdi
callq 0x2290
cmpl $-0x1, %eax
jne 0x3cca
movq %r13, %rdi
leaq 0x2598(%rip), %rsi      # 0x6248
leaq 0xf(%rsp), %rdx
callq 0x3a9c
movq %r13, %rdi
callq 0x3a7c
movq %r13, %rdi
callq 0x20b0
movl 0xf8(%rsp), %eax
cmpl $0x2, %eax
je 0x3e4b
cmpl $0x3, %eax
je 0x3dfe
cmpl $0x16, %eax
jne 0x4033
movl 0x130(%rsp), %eax
cmpl 0x78(%rsp), %eax
jne 0x3d0a
movl 0x134(%rsp), %eax
cmpl 0x7c(%rsp), %eax
je 0x4033
movq %r12, %rdi
movq 0x28(%rsp), %rsi
movq %rbx, %rbp
movq %r14, %rbx
movq %r13, %r14
leaq 0x70(%rsp), %rdx
callq 0x2340
cvtsi2sdl 0x78(%rsp), %xmm1
movsd 0x22ed(%rip), %xmm0     # 0x6020
divsd %xmm1, %xmm0
cvtsi2sdl 0x7c(%rsp), %xmm1
leaq 0x54b4(%rip), %rax      # 0x91f8
movsd %xmm0, (%rax)
movsd 0x22d8(%rip), %xmm2     # 0x6028
divsd %xmm1, %xmm2
leaq 0x54a5(%rip), %r13      # 0x9200
movsd %xmm2, (%r13)
movq 0x5260(%rip), %r12      # 0x8fc8
movq %r12, %rdi
callq 0x2300
movq %rax, %rdi
callq 0x20d0
movsd (%r13), %xmm0
movq %r12, %rdi
callq 0x2300
movq %rax, %rdi
callq 0x20d0
movq %r12, %rdi
leaq 0x24d4(%rip), %rsi      # 0x626c
callq 0x21d0
movl 0x78(%rsp), %esi
movq %rax, %rdi
callq 0x2320
movq %rax, %rdi
callq 0x20d0
movq %r12, %rdi
leaq 0x24b5(%rip), %rsi      # 0x6270
callq 0x21d0
movl 0x7c(%rsp), %esi
movq %rax, %rdi
callq 0x2320
movq %rax, %rdi
callq 0x20d0
movq 0x18(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movq %r14, %r13
movq %rbx, %r14
movq %rbp, %rbx
leaq 0xf8(%rsp), %rbp
movq 0x20(%rsp), %r12
callq 0x38d8
jmp 0x4033
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0x10(%rsp), %rcx
xorl %r8d, %r8d
callq 0x2190
movq 0x10(%rsp), %rax
movq $-0xff51, %rcx          # imm = 0xFFFF00AF
addq %rcx, %rax
cmpq $0x3, %rax
ja 0x4033
leaq 0x23f6(%rip), %rcx      # 0x6228
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, 0x3a(%rbx)
movl $0x1e, 0x44(%rbx)
jmp 0x4033
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0x10(%rsp), %rcx
xorl %r8d, %r8d
callq 0x2190
movq 0x10(%rsp), %rax
leaq -0xff51(%rax), %rcx
cmpq $0x3, %rcx
jbe 0x3eb7
cmpq $0x61, %rax
je 0x3f00
cmpq $0x64, %rax
je 0x3f85
cmpq $0x7a, %rax
je 0x3f38
cmpq $0x66, %rax
jne 0x4033
movq 0x18(%rsp), %rax
cmpb $0x1, 0xf0(%rax)
jne 0x4020
movb $0x0, 0xf0(%rax)
jmp 0x4033
leaq 0x237a(%rip), %rdx      # 0x6238
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
movb $0x1, 0x3a(%rbx)
jmp 0x4033
movb $0x0, 0x3b(%rbx)
movl $0x1e, 0x48(%rbx)
jmp 0x4033
movb $0x0, 0x39(%rbx)
movl $0x1e, 0x40(%rbx)
jmp 0x4033
movb $0x0, 0x38(%rbx)
movl $0x1e, 0x3c(%rbx)
jmp 0x4033
leaq 0x52e9(%rip), %rax      # 0x91f0
movl (%rax), %eax
cmpl $0x9, %eax
jg 0x3f19
incl %eax
leaq 0x52d9(%rip), %rcx      # 0x91f0
movl %eax, (%rcx)
leaq 0x52f8(%rip), %rax      # 0x9218
movl (%rax), %eax
cmpl $0x9, %eax
jg 0x4033
incl %eax
jmp 0x3f65
movb $0x1, 0x3b(%rbx)
jmp 0x4033
leaq 0x52b1(%rip), %rax      # 0x91f0
movl (%rax), %eax
cmpl $0x2, %eax
jl 0x3f51
decl %eax
leaq 0x52a1(%rip), %rcx      # 0x91f0
movl %eax, (%rcx)
leaq 0x52c0(%rip), %rax      # 0x9218
movl (%rax), %eax
cmpl $0x2, %eax
jl 0x4033
decl %eax
leaq 0x52ac(%rip), %rcx      # 0x9218
movl %eax, (%rcx)
jmp 0x4033
movb $0x1, 0x39(%rbx)
jmp 0x4033
movb $0x1, 0x38(%rbx)
jmp 0x4033
cmpb $0x1, 0x3b(%rbx)
jne 0x3fd2
cvtsi2sdl 0x4c(%rbx), %xmm0
leaq 0x529d(%rip), %rax      # 0x9234
cvtsi2sdl (%rax), %xmm1
movsd 0x227d(%rip), %xmm2     # 0x6220
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
cvtsi2sdl 0x50(%rbx), %xmm0
leaq 0x527d(%rip), %rax      # 0x9238
cvtsi2sdl (%rax), %xmm1
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
movq %rbx, %rdi
pushq $0x1
jmp 0x401d
cvtsi2sdl 0x4c(%rbx), %xmm0
leaq 0x5256(%rip), %rax      # 0x9234
cvtsi2sdl (%rax), %xmm1
movsd 0x2236(%rip), %xmm2     # 0x6220
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %esi
cvtsi2sdl 0x50(%rbx), %xmm0
leaq 0x5236(%rip), %rax      # 0x9238
cvtsi2sdl (%rax), %xmm1
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
cmpb $0x1, 0x3a(%rbx)
jne 0x4029
movq %rbx, %rdi
pushq $0x2
popq %rcx
jmp 0x402e
movb $0x1, 0xf0(%rax)
jmp 0x4033
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x4c34
movq %r15, %rdi
callq 0x2140
cmpl $-0x1, %eax
jne 0x3c8e
movq %r14, %rdi
leaq 0x2226(%rip), %rsi      # 0x6274
leaq 0xf(%rsp), %rdx
callq 0x3a9c
movq %r14, %rdi
callq 0x3a7c
movq %r14, %rdi
callq 0x20b0
jmp 0x3c8e
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
jmp 0x407f
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x20b0
jmp 0x408b
jmp 0x4088
movq %rax, %rbx
movq %rbx, %rdi
callq 0x2330
nop