/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2003 Linus Nielsen Feltzing
 *
 * All files in this archive are subject to the GNU General Public License.
 * See the file COPYING in the source tree root for full license agreement.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include "config.h"
#include <stdio.h>
#include <stdbool.h>
#include "sprintf.h"
#include "lcd.h"
#include "mas.h"
#include "settings.h"
#include "button.h"
#include "fmradio.h"
#include "status.h"
#include "kernel.h"
#include "mpeg.h"
#include "audio.h"
#include "mp3_playback.h"
#include "ctype.h"
#include "file.h"
#include "errno.h"
#include "atoi.h"
#include "string.h"
#include "system.h"
#include "radio.h"
#include "menu.h"
#include "misc.h"
#include "keyboard.h"
#include "screens.h"
#include "peakmeter.h"
#include "lang.h"
#include "font.h"
#include "sound_menu.h"
#include "recording.h"
#include "talk.h"
#include "tuner.h"
#include "hwcompat.h"
#include "power.h"
#include "sound.h"

#ifdef CONFIG_TUNER

#if CONFIG_KEYPAD == RECORDER_PAD
#define FM_MENU BUTTON_F1
#define FM_PRESET BUTTON_F2
#define FM_RECORD BUTTON_F3
#define FM_FREEZE BUTTON_PLAY
#define FM_STOP BUTTON_OFF
#define FM_EXIT (BUTTON_ON | BUTTON_REL)
#define FM_PRESET_ADD BUTTON_F1
#define FM_PRESET_ACTION BUTTON_F3
#elif CONFIG_KEYPAD == ONDIO_PAD /* restricted keypad */
#define FM_MENU (BUTTON_MENU | BUTTON_REPEAT)
#define FM_RECORD (BUTTON_MENU | BUTTON_REL)
#define FM_STOP (BUTTON_OFF | BUTTON_REL)
#define FM_EXIT (BUTTON_OFF | BUTTON_REPEAT)
#endif

#define MAX_FREQ (108000000)
#define MIN_FREQ (87500000)
#define FREQ_STEP 100000

static int curr_preset = -1;
static int curr_freq;

#define MAX_PRESETS 32
static bool presets_loaded = false;
static struct fmstation presets[MAX_PRESETS];

static const char default_filename[] = "/.rockbox/fm-presets-default.fmr";

static int preset_menu; /* The menu index of the preset list */
static struct menu_item preset_menu_items[MAX_PRESETS];
static int num_presets; /* The number of presets in the preset list */

void radio_load_presets(void);
bool handle_radio_presets(void);
bool radio_menu(void);

#if CONFIG_TUNER == S1A0903X01 /* FM recorder */
#define radio_set samsung_set
#define radio_get samsung_get
#elif CONFIG_TUNER == TEA5767 /* Iriver */
#define radio_set philips_set
#define radio_get philips_get
#elif CONFIG_TUNER == (S1A0903X01 | TEA5767) /* OndioFM */
void (*radio_set)(int setting, int value);
int (*radio_get)(int setting);
#endif

void radio_init(void)
{
#if CONFIG_TUNER == (S1A0903X01 | TEA5767)
    if (read_hw_mask() & TUNER_MODEL)
    {
        radio_set = philips_set;
        radio_get = philips_get;
    }
    else
    {
        radio_set = samsung_set;
        radio_get = samsung_get;
    }
#endif
    radio_stop();
}

void radio_stop(void)
{
    radio_set(RADIO_MUTE, 1);
    radio_set(RADIO_SLEEP, 1); /* low power mode, if available */
    radio_set_status(FMRADIO_OFF); /* status update, power off if avail. */
}

bool radio_hardware_present(void)
{
#ifdef HAVE_TUNER_PWR_CTRL
    bool ret;
    int fmstatus = radio_get_status(); /* get current state */
    radio_set_status(FMRADIO_POWERED); /* power it up */
    ret = radio_get(RADIO_PRESENT);
    radio_set_status(fmstatus); /* restore previous state */
    return ret;
#else
    return radio_get(RADIO_PRESENT);
#endif
}

static int find_preset(int freq)
{
    int i;
    for(i = 0;i < MAX_PRESETS;i++)
    {
        if(freq == presets[i].frequency)
            return i;
    }

    return -1;
}

static void remember_frequency(void)
{
    global_settings.last_frequency = (curr_freq - MIN_FREQ) / FREQ_STEP;
    settings_save();
}

bool radio_screen(void)
{
    char buf[MAX_PATH];
    bool done = false;
    int button;
    int freq;
    bool tuned;
    bool stereo = false;
    int search_dir = 0;
    int fw, fh;
    bool last_stereo_status = false;
    int top_of_screen = 0;
    bool update_screen = true;
    int timeout = current_tick + HZ/10;
    bool screen_freeze = false;
    bool have_recorded = false;
    unsigned int seconds;
    unsigned int last_seconds = 0;
    int hours, minutes;
    bool keep_playing = false;

    lcd_clear_display();
    lcd_setmargins(0, 8);
    status_draw(true);
    radio_set_status(FMRADIO_PLAYING);

    font_get(FONT_UI);
    lcd_getstringsize("M", &fw, &fh);

    /* Adjust for font size, trying to center the information vertically */
    if(fh < 10)
        top_of_screen = 1;
    
    radio_load_presets();

#ifndef SIMULATOR
    if(rec_create_directory() > 0)
        have_recorded = true;
    
    audio_stop();
    
    mpeg_init_recording();

    sound_settings_apply();

    /* Yes, we use the D/A for monitoring */
    peak_meter_playback(true);
    
    peak_meter_enabled = true;

    if (global_settings.rec_prerecord_time)
        talk_buffer_steal(); /* will use the mp3 buffer */

    mpeg_set_recording_options(global_settings.rec_frequency,
                               global_settings.rec_quality,
                               1, /* Line In */
                               global_settings.rec_channels,
                               global_settings.rec_editable,
                               global_settings.rec_prerecord_time);

    
    mpeg_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
                            sound_default(SOUND_RIGHT_GAIN), false);
#endif

    curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
    
    radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
    radio_set(RADIO_FREQUENCY, curr_freq);
    radio_set(RADIO_IF_MEASUREMENT, 0);
    radio_set(RADIO_SENSITIVITY, 0);
    radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
    radio_set(RADIO_MUTE, 0);
    
    curr_preset = find_preset(curr_freq);

#if CONFIG_KEYPAD == RECORDER_PAD
    buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS),
                  str(LANG_FM_BUTTONBAR_RECORD));
#endif

    while(!done)
    {
        if(search_dir)
        {
            curr_freq += search_dir * FREQ_STEP;
            if(curr_freq < MIN_FREQ)
                curr_freq = MAX_FREQ;
            if(curr_freq > MAX_FREQ)
                curr_freq = MIN_FREQ;

            /* Tune in and delay */
            radio_set(RADIO_FREQUENCY, curr_freq);
            sleep(1);
            
            /* Start IF measurement */
            radio_set(RADIO_IF_MEASUREMENT, 1);
            sleep(1);

            /* Now check how close to the IF frequency we are */
            tuned = radio_get(RADIO_TUNED);

            /* Stop searching if the tuning is close */
            if(tuned)
            {
                search_dir = 0;
                curr_preset = find_preset(curr_freq);
                remember_frequency();
            }
            
            update_screen = true;
        }

        if(search_dir)
            button = button_get(false);
        else
            button = button_get_w_tmo(HZ / peak_meter_fps);
        switch(button)
        {
            case FM_STOP:
#ifndef SIMULATOR
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    audio_stop();
                }
                else
#endif
                {
                    done = true;
                }
                update_screen = true;
                break;

#ifdef FM_RECORD
            case FM_RECORD:
#ifndef SIMULATOR
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    mpeg_new_file(rec_create_filename(buf));
                    update_screen = true;
                }
                else
                {
                    have_recorded = true;
                    talk_buffer_steal(); /* we use the mp3 buffer */
                    mpeg_record(rec_create_filename(buf));
                    update_screen = true;
                }
#endif
                last_seconds = 0;
                break;
#endif /* #ifdef FM_RECORD */

            case FM_EXIT:
#ifndef SIMULATOR
                if(audio_status() == AUDIO_STATUS_RECORD)
                    audio_stop();
#endif
                done = true;
                keep_playing = true;
                break;
                
            case BUTTON_LEFT:
                curr_freq -= FREQ_STEP;
                if(curr_freq < MIN_FREQ)
                    curr_freq = MAX_FREQ;

                radio_set(RADIO_FREQUENCY, curr_freq);
                curr_preset = find_preset(curr_freq);
                remember_frequency();
                search_dir = 0;
                update_screen = true;
                break;

            case BUTTON_RIGHT:
                curr_freq += FREQ_STEP;
                if(curr_freq > MAX_FREQ)
                    curr_freq = MIN_FREQ;
                
                radio_set(RADIO_FREQUENCY, curr_freq);
                curr_preset = find_preset(curr_freq);
                remember_frequency();
                search_dir = 0;
                update_screen = true;
                break;

            case BUTTON_LEFT | BUTTON_REPEAT:
                search_dir = -1;
                break;
                
            case BUTTON_RIGHT | BUTTON_REPEAT:
                search_dir = 1;
                break;

            case BUTTON_UP:
            case BUTTON_UP | BUTTON_REPEAT:
                global_settings.volume++;
                if(global_settings.volume > sound_max(SOUND_VOLUME))
                    global_settings.volume = sound_max(SOUND_VOLUME);
                sound_set(SOUND_VOLUME, global_settings.volume);
                update_screen = true;
                settings_save();
                break;

            case BUTTON_DOWN:
            case BUTTON_DOWN | BUTTON_REPEAT:
                global_settings.volume--;
                if(global_settings.volume < sound_min(SOUND_VOLUME))
                    global_settings.volume = sound_min(SOUND_VOLUME);
                sound_set(SOUND_VOLUME, global_settings.volume);
                update_screen = true;
                settings_save();
                break;

#ifdef FM_MENU
            case FM_MENU:
                radio_menu();
                curr_preset = find_preset(curr_freq);
                lcd_clear_display();
                lcd_setmargins(0, 8);
#if CONFIG_KEYPAD == RECORDER_PAD
                buttonbar_set(str(LANG_BUTTONBAR_MENU),
                              str(LANG_FM_BUTTONBAR_PRESETS),
                              str(LANG_FM_BUTTONBAR_RECORD));
#endif
                update_screen = true;
                break;
#endif
                
#ifdef FM_PRESET
            case FM_PRESET:
                handle_radio_presets();
                curr_preset = find_preset(curr_freq);
                lcd_clear_display();
                lcd_setmargins(0, 8);
#if CONFIG_KEYPAD == RECORDER_PAD
                buttonbar_set(str(LANG_BUTTONBAR_MENU),
                              str(LANG_FM_BUTTONBAR_PRESETS),
                              str(LANG_FM_BUTTONBAR_RECORD));
#endif
                update_screen = true;
                break;
#endif
                
#ifdef FM_FREEZE
            case FM_FREEZE:
                if(!screen_freeze)
                {
                    splash(0, true, "Screen frozen");
                    lcd_update();
                    screen_freeze = true;
                }
                else
                {
                    update_screen = true;
                    screen_freeze = false;
                }
                break;
#endif                
            case SYS_USB_CONNECTED:
                /* Only accept USB connection when not recording */
                if(audio_status() != AUDIO_STATUS_RECORD)
                {
                    default_event_handler(SYS_USB_CONNECTED);
                    screen_freeze = true; /* Cosmetic: makes sure the
                                             radio screen doesn't redraw */
                    done = true;
                }
                break;
                
            default:
                default_event_handler(button);
                break;
        }

        peak_meter_peek();

        if(!screen_freeze)
        {
            lcd_setmargins(0, 8);
            
            /* Only display the peak meter when not recording */
            if(!audio_status())
            {
                lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
                lcd_fillrect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
                lcd_set_drawmode(DRMODE_SOLID);
                peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
                lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
            }
            
            if(TIME_AFTER(current_tick, timeout))
            {
                timeout = current_tick + HZ;
                
                stereo = radio_get(RADIO_STEREO) &&
                    !global_settings.fm_force_mono;
                if(stereo != last_stereo_status)
                {
                    update_screen = true;
                    last_stereo_status = stereo;
                }
            }
            
#ifndef SIMULATOR
            seconds = mpeg_recorded_time() / HZ;
#endif
            if(update_screen || seconds > last_seconds)
            {
                last_seconds = seconds;
                
                lcd_setfont(FONT_UI);
                
                if(curr_preset >= 0)
                {
                    lcd_puts_scroll(0, top_of_screen,
                                    presets[curr_preset].name);
                }
                else
                {
                    lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
                    lcd_fillrect(0, 8 + top_of_screen*fh, LCD_WIDTH, fh);
                    lcd_set_drawmode(DRMODE_SOLID);
                }
                
                freq = curr_freq / 100000;
                snprintf(buf, 128, str(LANG_FM_STATION), freq / 10, freq % 10);
                lcd_puts(0, top_of_screen + 1, buf);
                
                snprintf(buf, 128,
                         stereo?str(LANG_CHANNEL_STEREO):
                         str(LANG_CHANNEL_MONO));
                lcd_puts(0, top_of_screen + 2, buf);

                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    hours = seconds / 3600;
                    minutes = (seconds - (hours * 3600)) / 60;
                    snprintf(buf, 32, "%s %02d:%02d:%02d",
                             str(LANG_RECORDING_TIME),
                             hours, minutes, seconds%60);
                    lcd_puts(0, top_of_screen + 3, buf);
                }
                else
                {
                    if(global_settings.rec_prerecord_time)
                    {
                        snprintf(buf, 32, "%s %02d",
                                 str(LANG_RECORD_PRERECORD), seconds%60);
                        lcd_puts(0, top_of_screen + 3, buf);
                    }
                }
                
#if CONFIG_KEYPAD == RECORDER_PAD
                buttonbar_draw();
#endif                
                lcd_update();
                
                update_screen = false;
            }
            /* Only force the redraw if update_screen is true */
            status_draw(update_screen);
        }

        if(audio_status() & AUDIO_STATUS_ERROR)
        {
            done = true;
        }
    }

#ifndef SIMULATOR
    if(audio_status() & AUDIO_STATUS_ERROR)
    {
        splash(0, true, str(LANG_DISK_FULL));
        status_draw(true);
        lcd_update();
        audio_error_clear();

        while(1)
        {
            button = button_get(true);
            if(button == (BUTTON_OFF | BUTTON_REL))
                break;
        }
    }
    
    audio_init_playback();

    sound_settings_apply();

    if(keep_playing)
    {
        /* Enable the Left and right A/D Converter */
        mpeg_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
                                sound_default(SOUND_RIGHT_GAIN), false);
        mas_codec_writereg(6, 0x4000);
        radio_set_status(FMRADIO_POWERED); /* leave it powered */
    }
    else
    {
        radio_stop();
    }

#endif
    return have_recorded;
}

void radio_save_presets(void)
{
    int fd;
    int i;
    
    fd = creat(default_filename, O_WRONLY);
    if(fd >= 0)
    {
        for(i = 0;i < num_presets;i++)
        {
            fdprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name);
        }
        close(fd);
    }
    else
    {
        splash(HZ*2, true, str(LANG_FM_PRESET_SAVE_FAILED));
    }
}

void radio_load_presets(void)
{
    int fd;
    int rc;
    char buf[128];
    char *freq;
    char *name;
    bool done = false;
    int i;
    int f;

    if(!presets_loaded)
    {
        memset(presets, 0, sizeof(presets));
        num_presets = 0;
    
        fd = open(default_filename, O_RDONLY);
        if(fd >= 0)
        {
            i = 0;
            while(!done && i < MAX_PRESETS)
            {
                rc = read_line(fd, buf, 128);
                if(rc > 0)
                {
                    if(settings_parseline(buf, &freq, &name))
                    {
                        f = atoi(freq);
                        if(f) /* For backwards compatibility */
                        {
                            presets[num_presets].frequency = f;
                            strncpy(presets[num_presets].name, name, 27);
                            presets[num_presets].name[27] = 0;
                            num_presets++;
                        }
                    }
                }
                else
                    done = true;
            }
            close(fd);
        }
    }
    presets_loaded = true;
}

static void rebuild_preset_menu(void)
{
    int i;
    for(i = 0;i < num_presets;i++)
    {
        preset_menu_items[i].desc = presets[i].name;
    }
}

static bool radio_add_preset(void)
{
    char buf[27];

    if(num_presets < MAX_PRESETS)
    {
        memset(buf, 0, 27);
        
        if (!kbd_input(buf, 27))
        {
            buf[27] = 0;
            strcpy(presets[num_presets].name, buf);
            presets[num_presets].frequency = curr_freq;
            menu_insert(preset_menu, -1,
                        presets[num_presets].name, 0);
            /* We must still rebuild the menu table, since the
               item name pointers must be updated */
            rebuild_preset_menu();
            num_presets++;
            radio_save_presets();
        }
    }
    else
    {
        splash(HZ*2, true, str(LANG_FM_NO_FREE_PRESETS));
    }
    return true;
}

/* button preprocessor for preset option submenu */
static int handle_radio_presets_menu_cb(int key, int m)
{
    (void)m;
#ifdef FM_PRESET_ACTION
    switch(key)
    {
        case FM_PRESET_ACTION:
            key = MENU_EXIT; /* Fake an exit */
            break;
            
        case FM_PRESET_ACTION | BUTTON_REL:
            /* Ignore the release events */
            key = BUTTON_NONE;
            break;
    }
#endif
    return key;
}

static bool radio_edit_preset(void)
{
    int pos = menu_cursor(preset_menu);
    char buf[27];

    strncpy(buf, menu_description(preset_menu, pos), 27);
        
    if (!kbd_input(buf, 27))
    {
        buf[27] = 0;
        strcpy(presets[pos].name, buf);
        radio_save_presets();
    }
    return true;
}

bool radio_delete_preset(void)
{
    int pos = menu_cursor(preset_menu);
    int i;

    for(i = pos;i < num_presets;i++)
        presets[i] = presets[i+1];
    num_presets--;
    
    menu_delete(preset_menu, pos);
    /* We must still rebuild the menu table, since the
       item name pointers must be updated */
    rebuild_preset_menu();
    radio_save_presets();

    return true; /* Make the menu return immediately */
}

/* little menu on what to do with a preset entry */
bool handle_radio_presets_menu(void)
{
    static const struct menu_item preset_menu_items[] = {
        { ID2P(LANG_FM_EDIT_PRESET), radio_edit_preset },
        { ID2P(LANG_FM_DELETE_PRESET), radio_delete_preset },
    };
    int m;

    m = menu_init( preset_menu_items,
                   sizeof preset_menu_items / sizeof(struct menu_item),
                   handle_radio_presets_menu_cb,
                   NULL, NULL, str(LANG_FM_BUTTONBAR_EXIT));
    menu_run(m);
    menu_exit(m);
    return false;
}

/* button preprocessor for list of preset stations menu */
int handle_radio_presets_cb(int key, int m)
{
    (void)m;
    switch(key)
    {
#ifdef FM_PRESET_ADD
        case FM_PRESET_ADD:
            radio_add_preset();
            menu_draw(m);
            key = BUTTON_NONE;
            break;
#endif            
#ifdef FM_PRESET
        case FM_PRESET:
            menu_draw(m);
            key = MENU_EXIT; /* Fake an exit */
            break;
#endif
#ifdef FM_PRESET_ACTION
        case FM_PRESET_ACTION:
#endif
#ifdef MENU_ENTER2
        case MENU_ENTER2 | BUTTON_REPEAT:
#endif
        case MENU_ENTER | BUTTON_REPEAT: /* long gives options */
        {
            bool ret;
            ret = handle_radio_presets_menu();
            menu_draw(m);
            if(ret)
                key = MENU_ATTACHED_USB;
            else
                key = BUTTON_NONE;
            break;
        }
#ifdef MENU_ENTER2
        case MENU_ENTER2 | BUTTON_REL:
#endif
        case MENU_ENTER | BUTTON_REL:
            key = MENU_ENTER; /* fake enter for short press */
            break;

#ifdef MENU_ENTER2
        case MENU_ENTER2:
#endif
        case MENU_ENTER: /* ignore down event */
            /* Ignore the release events */
#ifdef FM_PRESET_ADD
        case FM_PRESET_ADD | BUTTON_REL:
#endif
#ifdef FM_PRESET_ACTION
        case FM_PRESET_ACTION | BUTTON_REL:
#endif
            key = BUTTON_NONE;
            break;
    }
    return key;
}

/* present a list of preset stations */
bool handle_radio_presets(void)
{
    int result;
    bool reload_dir = false;

    if(presets_loaded)
    {
        rebuild_preset_menu();

        /* DIY menu handling, since we want to exit after selection */
        preset_menu = menu_init( preset_menu_items, num_presets,
                                 handle_radio_presets_cb,
                                 str(LANG_FM_BUTTONBAR_ADD),
                                 str(LANG_FM_BUTTONBAR_EXIT),
                                 str(LANG_FM_BUTTONBAR_ACTION));
        if (curr_preset >= 0)
            menu_set_cursor(preset_menu, curr_preset);
        result = menu_show(preset_menu);
        menu_exit(preset_menu);
        if (result == MENU_SELECTED_EXIT)
            return false;
        else if (result == MENU_ATTACHED_USB)
            reload_dir = true;
        
        if (result >= 0) /* A preset was selected */
        {
            curr_preset = menu_cursor(preset_menu);
            curr_freq = presets[curr_preset].frequency;
            radio_set(RADIO_FREQUENCY, curr_freq);
            remember_frequency();
        }
    }
    
    return reload_dir;
}

#ifndef SIMULATOR
static bool fm_recording_settings(void)
{
    bool ret;
    
    ret = recording_menu(true);
    if(!ret)
    {
        if (global_settings.rec_prerecord_time)
            talk_buffer_steal(); /* will use the mp3 buffer */

        mpeg_set_recording_options(global_settings.rec_frequency,
                                   global_settings.rec_quality,
                                   1, /* Line In */
                                   global_settings.rec_channels,
                                   global_settings.rec_editable,
                                   global_settings.rec_prerecord_time);
    }
    return ret;
}
#endif

char monomode_menu_string[32];

static void create_monomode_menu(void)
{
    snprintf(monomode_menu_string, 32, "%s: %s", str(LANG_FM_MONO_MODE),
             global_settings.fm_force_mono?
             str(LANG_SET_BOOL_YES):str(LANG_SET_BOOL_NO));
}

static bool toggle_mono_mode(void)
{
    global_settings.fm_force_mono = !global_settings.fm_force_mono;
    radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
    settings_save();
    create_monomode_menu();
    return false;
}


/* button preprocessor for the main menu */
int radio_menu_cb(int key, int m)
{
    (void)m;
    switch(key)
    {
#ifdef MENU_ENTER2
    case MENU_ENTER2:
#endif
    case MENU_ENTER:
        key = BUTTON_NONE; /* eat the downpress, next menu reacts on release */
        break;

#ifdef MENU_ENTER2
    case MENU_ENTER2 | BUTTON_REL:
#endif
    case MENU_ENTER | BUTTON_REL:
        key = MENU_ENTER; /* fake downpress, next menu doesn't like release */
        break;
    }

    return key;
}

/* main menu of the radio screen */
bool radio_menu(void)
{
    struct menu_item items[5];
    int m;
    bool result;

    m = menu_init(items, 0, radio_menu_cb, NULL, NULL, NULL);

#if CONFIG_KEYPAD == ONDIO_PAD /* Ondio has no key for presets, put it in menu */
    /* fixme: make real string table entries */
    menu_insert(m, -1, ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets);
    menu_insert(m, -1, ID2P(LANG_FM_BUTTONBAR_ADD), radio_add_preset);
#endif
    create_monomode_menu();
    menu_insert(m, -1, monomode_menu_string, toggle_mono_mode);
    menu_insert(m, -1, ID2P(LANG_SOUND_SETTINGS), sound_menu);
#ifndef SIMULATOR
    menu_insert(m, -1, ID2P(LANG_RECORDING_SETTINGS), fm_recording_settings);
#endif

    result = menu_run(m);
    menu_exit(m);
    return result;
}

#endif
