// File: /workspace/github_cpp_makefile_star2_O2/fulhax[P]ncpamixer/src/ui/tab.cpp
// Function: Tab::dropDown(int, int, std::map<unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, unsigned int, unsigned int, unsigned int)
uint32_t Tab::dropDown(
    int x,
    int y,
    std::map<uint32_t, std::string> objects,
    uint32_t current,
    uint32_t width,
    uint32_t height
)
{
    if (objects.empty()) {
        return -1;
    }

    bool autowidth = false;
    bool autoheight = false;

    if (width == 0) {
        autowidth = true;
    }

    if (height == 0) {
        autoheight = true;
    }

    uint32_t selected = 0;

    std::vector<ITEM *> items;
    MENU *menu = 0;
    WINDOW *menu_win = 0;

    for (auto &i : objects) {
        ITEM *item = new_item(i.second.c_str(), nullptr);
        set_item_opts(item, O_SELECTABLE);
        set_item_userptr(item, static_cast<void*>(&i));

        items.push_back(item);

        if (i.first == current) {
            selected = items.size() - 1;
        }

        if (autowidth) {
            width = (width < strlen(i.second.c_str()) + 3) ?
                    strlen(i.second.c_str()) :
                    width;
        }

        if (autoheight) {
            height = (height < 5) ? height + 1 : 5;
        }
    }

    items.push_back(new_item(nullptr, nullptr));
    menu = new_menu(&items[0]);

    if (x < 0) {
        x = ui.width - (width + 2);
    }

    menu_win = newwin(height + 2, width + 2, y, x);
    keypad(menu_win, true);

    set_menu_win(menu, menu_win);
    set_menu_sub(menu, derwin(menu_win, height + 1, width, 1, 1));
    set_menu_format(menu, height, 1);

    wbkgd(menu_win, COLOR_PAIR(COLOR_BORDER));
    //set_menu_back(menu, COLOR_PAIR(7));
    set_menu_fore(menu, COLOR_PAIR(COLOR_DROPDOWN_SELECTED));
    set_menu_grey(menu, COLOR_PAIR(COLOR_DROPDOWN_UNSELECTED));

    //set_menu_mark(menu, "* ");
    set_menu_mark(menu, "");
    menu_opts_on(menu, O_ONEVALUE);
    menu_opts_off(menu, O_SHOWDESC);
    menu_opts_off(menu, O_NONCYCLIC);

    box(menu_win, 0, 0);

    post_menu(menu);
    set_current_item(menu, items[selected]);

    wrefresh(menu_win);

    bool selecting = true;

    while (selecting) {
        int input = wgetch(menu_win);

        if (input == ERR) {
            continue;
        }

#ifdef KEY_MOUSE
        if (input == KEY_MOUSE) {
            MEVENT mevent;
            int ok;

            ok = getmouse(&mevent);
            if (ok != OK) {
                continue;
            }

            if (mevent.bstate & BUTTON1_PRESSED) {
                if (mevent.y < y || mevent.y > y + (int)height + 1 ||
                    mevent.x < x || mevent.x > x + (int)width + 1) {
                    clrtoeol();

                    ITEM *item = current_item(menu);
                    selected = static_cast<std::pair<uint32_t, std::string>*>(
                                   item_userptr(item)
                               )->first;

                    selecting = false;
                    continue;
                }
            }

            if (mevent.y == y || mevent.y == y + (int)height + 1 ||
                mevent.x == x || mevent.x == x + (int)width + 1) {
                continue;
            }

            if (mevent.bstate & BUTTON1_PRESSED) {
                int top = top_row(menu);
                int idx = mevent.y - y - 1 + top;
                ITEM** its = menu_items(menu);
                int itc = item_count(menu);
                if (idx < itc) {
                    ITEM* item = its[idx];
                    set_current_item(menu, item);
                    selected = static_cast<std::pair<uint32_t, std::string>*>(
                                   item_userptr(item)
                               )->first;
                }

                selecting = false;
                continue;
            }
#if NCURSES_MOUSE_VERSION > 1
            else if (mevent.bstate & BUTTON4_PRESSED) {
                menu_driver(menu, REQ_UP_ITEM);
            } else if (mevent.bstate & BUTTON5_PRESSED) {
                menu_driver(menu, REQ_DOWN_ITEM);
            }
#endif
        }
#endif

        if (input == KEY_RESIZE) {
            selecting = false;
            continue;
        }

        std::string key = std::to_string(input);
        
        std::string event = config.getString(("keycode." +  key).c_str(), "unbound");

        if (!strcmp("unbound", event.c_str())) {
            continue;
        }

        if (!strcmp("select", event.c_str())) {
            clrtoeol();

            ITEM *item = current_item(menu);
            selected = static_cast<std::pair<uint32_t, std::string>*>(
                            item_userptr(item)
                       )->first;

            selecting = false;
        } else if (!strcmp("move_down", event.c_str())) {
            menu_driver(menu, REQ_DOWN_ITEM);
        } else if (!strcmp("move_up", event.c_str())) {
            menu_driver(menu, REQ_UP_ITEM);
        } else if (!strcmp("page_up", event.c_str())) {
            menu_driver(menu, REQ_SCR_UPAGE);
        } else if (!strcmp("page_down", event.c_str())) {
            menu_driver(menu, REQ_SCR_DPAGE);
        } else if (!strcmp("quit", event.c_str())) {
            selecting = false;
        }

        wrefresh(menu_win);
    }

    unpost_menu(menu);
    free_menu(menu);

    for (auto i : items) {
        if (i != nullptr)
            free_item(i);
    }

    items.clear();
    refresh();

    return selected;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movl %r9d, 0x4(%rsp)
cmpq $0x0, 0x28(%rdx)
je 0xe295
movl %r8d, %ebp
movl %ecx, %r12d
movq %rdx, %rbx
movl %edi, 0x4c(%rsp)
movq %rsi, 0x40(%rsp)
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq 0x18(%rdx), %r14
addq $0x8, %rbx
movq $0x0, 0x18(%rsp)
movl 0x4(%rsp), %eax
movl %eax, %r15d
movl %r8d, %eax
movq %rax, 0x8(%rsp)
cmpq %rbx, %r14
je 0xde1c
movq 0x28(%r14), %rdi
xorl %esi, %esi
callq 0x65e0
movq %rax, 0x50(%rsp)
movq %rax, %rdi
pushq $0x1
popq %rsi
callq 0x6be0
leaq 0x20(%r14), %r13
movq 0x50(%rsp), %rdi
movq %r13, %rsi
callq 0x6260
leaq 0x20(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xe600
cmpl %r12d, (%r13)
jne 0xddc2
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
shrq $0x3, %rax
decl %eax
movq %rax, 0x18(%rsp)
testl %ebp, %ebp
jne 0xddf1
movq %r15, 0x70(%rsp)
movq 0x8(%rsp), %r15
movl %r15d, %r13d
movq 0x28(%r14), %rdi
callq 0x62a0
leaq 0x3(%rax), %rcx
cmpq %r13, %rcx
cmovbel %r15d, %eax
movq 0x70(%rsp), %r15
movq %rax, 0x8(%rsp)
leal 0x1(%r15), %r13d
cmpl $0x5, %r15d
pushq $0x5
popq %rax
cmovael %eax, %r13d
cmpl $0x0, 0x4(%rsp)
cmovnel %r15d, %r13d
movq %r14, %rdi
callq 0x6450
movq %rax, %r14
movl %r13d, %r15d
jmp 0xdd63
xorl %edi, %edi
xorl %esi, %esi
callq 0x65e0
leaq 0x50(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0xee84
movq 0x20(%rsp), %rdi
callq 0x6390
movq 0x40(%rsp), %r14
movq 0x18(%rsp), %rbp
movq %rax, %rbx
leaq 0xa9d3(%rip), %rax      # 0x18828
movl 0x8(%rax), %r12d
movq 0x8(%rsp), %rax
leal 0x2(%rax), %esi
subl %esi, %r12d
movl 0x4c(%rsp), %eax
testl %eax, %eax
cmovnsl %eax, %r12d
leal 0x2(%r15), %edi
movl %r14d, %edx
movl %r12d, %ecx
callq 0x6600
movq %rax, %r13
pushq $0x1
popq %rsi
movq %rax, %rdi
callq 0x6240
movq %rbx, %rdi
movq %r13, %rsi
callq 0x63f0
leal 0x1(%r15), %esi
pushq $0x1
popq %rcx
movq %r13, %rdi
movq 0x8(%rsp), %rdx
movl %ecx, %r8d
callq 0x6490
movq %rbx, %rdi
movq %rax, %rsi
callq 0x6090
pushq $0x1
popq %rdx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x6730
movq %r13, %rdi
movl $0xd00, %esi            # imm = 0xD00
callq 0x6a20
movq %rbx, %rdi
movl $0xb00, %esi            # imm = 0xB00
callq 0x61d0
movq %rbx, %rdi
movl $0xc00, %esi            # imm = 0xC00
callq 0x60f0
leaq 0x25fb(%rip), %rsi      # 0x104ef
movq %rbx, %rdi
callq 0x6250
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x6b60
pushq $0x2
popq %rsi
movq %rbx, %rdi
callq 0x6ad0
pushq $0x20
popq %rsi
movq %rbx, %rdi
callq 0x6ad0
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x6b50
movq %rbx, %rdi
callq 0x6870
movl %ebp, %eax
movq 0x20(%rsp), %rcx
movq (%rcx,%rax,8), %rsi
movq %rbx, %rdi
callq 0x6100
movq %r13, %rdi
callq 0x6680
leal (%r14,%r15), %eax
incl %eax
movl %eax, 0x4(%rsp)
movq 0x8(%rsp), %rax
leal 0x1(%rax,%r12), %eax
movl %eax, 0x8(%rsp)
notl %r14d
movb $0x1, %bpl
movq %rbx, %r15
testb $0x1, %bpl
je 0xe23c
movq %r13, %rdi
callq 0x6230
movl %eax, %ebx
movb $0x1, %bpl
cmpl $-0x1, %eax
je 0xdf6d
cmpl $0x19a, %ebx            # imm = 0x19A
jne 0xdf95
xorl %ebp, %ebp
jmp 0xdf6d
cmpl $0x199, %ebx            # imm = 0x199
leaq 0x50(%rsp), %rbp
jne 0xe00d
movq %rbp, %rdi
callq 0x69f0
movb $0x1, %bpl
testl %eax, %eax
jne 0xdf6d
movl 0x58(%rsp), %ecx
movl 0x60(%rsp), %eax
testb $0x2, %al
jne 0xe152
cmpl 0x40(%rsp), %ecx
je 0xdf6d
cmpl 0x4(%rsp), %ecx
je 0xdf6d
movl 0x54(%rsp), %ecx
cmpl %r12d, %ecx
sete %dl
cmpl 0x8(%rsp), %ecx
sete %cl
orb %dl, %cl
jne 0xdf6d
testb $0x2, %al
jne 0xe1f0
movl $0x202, %esi            # imm = 0x202
btl $0x10, %eax
leaq 0x50(%rsp), %rbp
jb 0xe005
movl $0x203, %esi            # imm = 0x203
btl $0x15, %eax
jae 0xe00d
movq %r15, %rdi
callq 0x64e0
movq %rbp, %rdi
movl %ebx, %esi
callq 0xa255
leaq 0x78(%rsp), %rdi
leaq 0x38b0(%rip), %rsi      # 0x118d3
movq %rbp, %rdx
callq 0xc533
movq 0x78(%rsp), %rbx
leaq 0xb8(%rsp), %rbp
movq %rbp, %rdi
leaq 0x387e(%rip), %rsi      # 0x118c0
leaq 0x17(%rsp), %rdx
callq 0xa1f6
leaq 0x98(%rsp), %rdi
leaq 0xa775(%rip), %rsi      # 0x187d0
movq %rbx, %rdx
movq %rbp, %rcx
callq 0x9eb6
movq %rbp, %rdi
callq 0x62b0
leaq 0x78(%rsp), %rdi
callq 0x62b0
movq 0x98(%rsp), %rbx
leaq 0x3839(%rip), %rdi      # 0x118c0
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe120
leaq 0x3a13(%rip), %rdi      # 0x11ab1
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe128
leaq 0x391c(%rip), %rdi      # 0x119cd
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe1a7
leaq 0x38fd(%rip), %rdi      # 0x119c5
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe1ae
leaq 0x39d9(%rip), %rdi      # 0x11ab8
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe1b5
leaq 0x39ca(%rip), %rdi      # 0x11ac0
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
je 0xe1bc
leaq 0x37cf(%rip), %rdi      # 0x118dc
movq %rbx, %rsi
callq 0x6830
testl %eax, %eax
setne %bpl
jmp 0xe1cc
movb $0x1, %bpl
jmp 0xe1d4
movq 0x9e61(%rip), %rax      # 0x17f90
movq (%rax), %rdi
callq 0x6630
movq %r15, %rdi
callq 0x6910
movq %rax, %rdi
callq 0x6980
movl (%rax), %eax
movq %rax, 0x18(%rsp)
xorl %ebp, %ebp
jmp 0xe1cc
cmpl 0x40(%rsp), %ecx
jl 0xe17c
cmpl 0x4(%rsp), %ecx
jg 0xe17c
movl 0x54(%rsp), %edx
cmpl %r12d, %edx
setl %sil
cmpl 0x8(%rsp), %edx
setg %dl
orb %sil, %dl
cmpb $0x1, %dl
jne 0xdfc1
movq 0x9e0d(%rip), %rax      # 0x17f90
movq (%rax), %rdi
callq 0x6630
movq %r15, %rdi
callq 0x6910
movq %rax, %rdi
callq 0x6980
movl (%rax), %eax
movq %rax, 0x18(%rsp)
jmp 0xdf91
movl $0x203, %esi            # imm = 0x203
jmp 0xe1c1
movl $0x202, %esi            # imm = 0x202
jmp 0xe1c1
movl $0x207, %esi            # imm = 0x207
jmp 0xe1c1
movl $0x206, %esi            # imm = 0x206
movb $0x1, %bpl
movq %r15, %rdi
callq 0x64e0
movq %r13, %rdi
callq 0x6680
leaq 0x98(%rsp), %rdi
callq 0x62b0
leaq 0x50(%rsp), %rdi
callq 0x62b0
jmp 0xdf6d
movq %r15, %rdi
callq 0x67c0
movl %eax, %ebx
addl %r14d, %ebx
addl 0x58(%rsp), %ebx
movq %r15, %rdi
callq 0x6170
movq %rax, %rbp
movq %r15, %rdi
callq 0x62d0
cmpl %eax, %ebx
jge 0xdf91
movslq %ebx, %rax
movq (%rbp,%rax,8), %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x6100
movq %rbx, %rdi
callq 0x6980
jmp 0xe19b
movq %r15, %rdi
callq 0x6470
movq 0x18(%rsp), %r12
movq %r15, %rdi
callq 0x6200
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %r14
cmpq %r14, %rbx
je 0xe273
movq (%rbx), %rdi
testq %rdi, %rdi
je 0xe26d
callq 0x66f0
addq $0x8, %rbx
jmp 0xe25b
movq 0x20(%rsp), %rax
cmpq %rax, 0x28(%rsp)
je 0xe284
movq %rax, 0x28(%rsp)
callq 0x6a40
leaq 0x20(%rsp), %rdi
callq 0xed0c
jmp 0xe299
pushq $-0x1
popq %r12
movl %r12d, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xe305
jmp 0xe305
jmp 0xe305
jmp 0xe305
jmp 0xe305
jmp 0xe2df
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x62b0
jmp 0xe2cf
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
jmp 0xe2ea
movq %rax, %rbx
jmp 0xe2ef
jmp 0xe305
jmp 0xe305
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x62b0
leaq 0x50(%rsp), %rdi
callq 0x62b0
jmp 0xe308
jmp 0xe305
jmp 0xe305
jmp 0xe305
jmp 0xe305
jmp 0xe305
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0xed0c
movq %rbx, %rdi
callq 0x6ac0