int
get_menu_selection(char** headers, char** items, int menu_only,
                   int initial_selection) {
    // throw away keys pressed previously, so user doesn't
    // accidentally trigger menu items.
    ui_clear_key_queue();
    
    int item_count = ui_start_menu(headers, items, initial_selection);
    int selected = initial_selection;
    int chosen_item = -1; // NO_ACTION
    int wrap_count = 0;

    while (chosen_item < 0 && chosen_item != GO_BACK) {
        int key = ui_wait_key();
        int visible = ui_text_visible();

        if (key == -1) {   // ui_wait_key() timed out
            if (ui_text_ever_visible()) {
                continue;
            } else {
                LOGI("timed out waiting for key input; rebooting.\n");
                ui_end_menu();
                return ITEM_REBOOT;
            }
        }
        else if (key == -2) {   // we are returning from ui_cancel_wait_key(): trigger a GO_BACK
            return GO_BACK;
        }

        int action = ui_handle_key(key, visible);

        int old_selected = selected;
        selected = ui_get_selected_item();

        if (action < 0) {
            switch (action) {
                case HIGHLIGHT_UP:
                    --selected;
                    selected = ui_menu_select(selected);
                    break;
                case HIGHLIGHT_DOWN:
                    ++selected;
                    selected = ui_menu_select(selected);
                    break;
                case SELECT_ITEM:
                    chosen_item = selected;
                    if (ui_is_showing_back_button()) {
                        if (chosen_item == item_count) {
                            chosen_item = GO_BACK;
                        }
                    }
                    break;
                case NO_ACTION:
                    break;
                case GO_BACK:
                    chosen_item = GO_BACK;
                    break;
            }
        } else if (!menu_only) {
            chosen_item = action;
        }

        if (abs(selected - old_selected) > 1) {
            wrap_count++;
            if (wrap_count == 5) {
                wrap_count = 0;
                if (ui_get_rainbow_mode()) {
                    ui_set_rainbow_mode(0);
                    ui_print("Rainbow mode disabled\n");
                }
                else {
                    ui_set_rainbow_mode(1);
                    ui_print("Rainbow mode enabled!\n");
                }
            }
        }
    }

    ui_end_menu();
    ui_clear_key_queue();
    return chosen_item;
}
int
get_menu_selection(const char** headers, char** items, int menu_only,
                   int initial_selection) {
    // throw away keys pressed previously, so user doesn't
    // accidentally trigger menu items.
    ui_clear_key_queue();

    int item_count = ui_start_menu(headers, items, initial_selection);
    int selected = initial_selection;
    int chosen_item = -1; // NO_ACTION
#ifdef NOT_ENOUGH_RAINBOWS
    int wrap_count = 0;
#endif

    while (chosen_item < 0 && chosen_item != GO_BACK) {
        int key = ui_wait_key();
        int visible = ui_IsTextVisible();

        if (key == -1) {   // ui_wait_key() timed out, always reboot to main system
            LOGI("timed out waiting for key input; rebooting.\n");
            ui_end_menu();
            reboot_main_system(ANDROID_RB_RESTART, 0, 0);
            sleep(5);
            LOGE("Failed to reboot system on timed out key input!!\n");
            return GO_BACK;
        }
        else if (key == -2) {   // we are returning from ui_cancel_wait_key(): trigger a GO_BACK
            return GO_BACK;
        }
        else if (key == -3) {   // an USB device was plugged in (returning from ui_wait_key())
            return REFRESH;
        }

        int action = ui_handle_key(key, visible);

        int old_selected = selected;
        selected = ui_get_selected_item();

        if (action < 0) {
            switch (action) {
                case HIGHLIGHT_UP:
                    --selected;
                    selected = ui_menu_select(selected);
                    break;
                case HIGHLIGHT_DOWN:
                    ++selected;
                    selected = ui_menu_select(selected);
                    break;
#ifdef PHILZ_TOUCH_RECOVERY
                case HIGHLIGHT_ON_TOUCH:
                    selected = ui_menu_touch_select();
                    break;
#endif
                case SELECT_ITEM:
                    chosen_item = selected;
                    if (ui_is_showing_back_button()) {
                        if (chosen_item == item_count) {
                            chosen_item = GO_BACK;
                        }
                    }
                    break;
                case NO_ACTION:
                    break;
                case GO_BACK:
                    chosen_item = GO_BACK;
                    break;
#ifdef PHILZ_TOUCH_RECOVERY
                case GESTURE_ACTIONS:
                    handle_gesture_actions(headers, items, initial_selection);
                    break;
#endif
            }
        } else if (!menu_only) {
            chosen_item = action;
        }
#ifdef NOT_ENOUGH_RAINBOWS
        if (abs(selected - old_selected) > 1) {
            wrap_count++;
            if (wrap_count == 5) {
                wrap_count = 0;
                if (ui_get_rainbow_mode()) {
                    ui_set_rainbow_mode(0);
                    ui_print("Rainbow mode disabled\n");
                }
                else {
                    ui_set_rainbow_mode(1);
                    ui_print("Rainbow mode enabled!\n");
                }
            }
        }
#endif
    }

    ui_end_menu();
    ui_clear_key_queue();
    return chosen_item;
}