/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2022  Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include "alsa.h"
#include "bfu.h"
#include "cwdaemon.h"
#include "dsp.h"
#include "menu.h"
#include "net.h"
#include "oss.h"
#include "pa.h"
#include "rc.h"
#include "scope.h"
#include "ssbd.h"
#include "subwin.h"
#include "terminal.h"
#include "tsdl.h"

char *keys[MAX_CQ]={"F5", "F6", "F7", "F8", "F11", "F12"};

struct menu_item no_cq_defined_menu[] = {
    {CTEXT(T_NO_CQ), "", M_BAR, NULL, NULL, 0, 0},
    {NULL, NULL, 0, NULL, NULL, 0, 0},
};


/************************** CW *******************************/
 
char cw_str[MAX_STR_LEN], cw_speed_str[EQSO_LEN];
int cw_repeat, cw_breakable;
char cw_ts_str[EQSO_LEN];
int cw_allowifundef;    


void refresh_cq_cw(void *xxx){
    struct cq *cq;

    cq = (struct cq *)xxx;
    
    STORE_STR(cq, cw_str);
    cq->cw_speed = atoi(cw_speed_str);
	cq->cw_repeat = cw_repeat;
	cq->cw_breakable = cw_breakable;
    cq->cw_ts  = atoi(cw_ts_str);
    cq->cw_allowifundef = cw_allowifundef;

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

char *cq_cw_msg[] = {
   CTEXT(T_TEXT), 
   CTEXT(T_SPEED), 
   CTEXT(T_REPEAT),
   TRANSLATE("Breakable"),
   CTEXT(T_DELAY), 
   CTEXT(T_ALLOW_UNDEF),
   "", /* OK */
   "", /* Cancel */
};


void cq_cw_fn(struct dialog_data *dlg)
{
    struct terminal *term = dlg->win->term;
    int max = 0, min = 0;
    int w, rw;
    int y = -1;

    max_group_width(term, cq_cw_msg + 0, dlg->items + 0, 1, &max);
    min_group_width(term, cq_cw_msg + 0, dlg->items + 0, 1, &min);
    max_group_width(term, cq_cw_msg + 1, dlg->items + 1, 1, &max);
    min_group_width(term, cq_cw_msg + 1, dlg->items + 1, 1, &min);
    max_group_width(term, cq_cw_msg + 2, dlg->items + 2, 1, &max);
    min_group_width(term, cq_cw_msg + 2, dlg->items + 2, 1, &min);
    max_group_width(term, cq_cw_msg + 3, dlg->items + 2, 1, &max);
    min_group_width(term, cq_cw_msg + 3, dlg->items + 2, 1, &min);
    max_group_width(term, cq_cw_msg + 4, dlg->items + 2, 1, &max);
    min_group_width(term, cq_cw_msg + 4, dlg->items + 2, 1, &min);
	max_group_width(term, cq_cw_msg + 5, dlg->items + 2, 1, &max);
	min_group_width(term, cq_cw_msg + 5, dlg->items + 2, 1, &min);

    max_buttons_width(term, dlg->items + 6, 2, &max);
    min_buttons_width(term, dlg->items + 6, 2, &min);
    
    w = dlg->win->term->x * 9 / 10 - 2 * DIALOG_LB;
    if (w > max) w = max;
    if (w < min) w = min;
    if (w > dlg->win->term->x - 2 * DIALOG_LB - 8 ) w = dlg->win->term->x - 2 * DIALOG_LB - 8;
    if (w < 1) w = 1;
    
    rw = 0;
    y ++;
    dlg_format_group(NULL, term, cq_cw_msg + 0, dlg->items + 0, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, cq_cw_msg + 1, dlg->items + 1, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, cq_cw_msg + 2, dlg->items + 2, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, cq_cw_msg + 3, dlg->items + 3, 1, 0, &y, w, &rw);
	dlg_format_group(NULL, term, cq_cw_msg + 4, dlg->items + 4, 1, 0, &y, w, &rw);
	dlg_format_group(NULL, term, cq_cw_msg + 5, dlg->items + 5, 1, 0, &y, w, &rw);
    y++;
    dlg_format_buttons(NULL, term, dlg->items + 6, 2, 0, &y, w, &rw, AL_LEFT);
    
    
    w = rw;
    dlg->xw = w + 2 * DIALOG_LB;
    dlg->yw = y + 2 * DIALOG_TB;

    
    center_dlg(dlg);
    draw_dlg(dlg);
    y = dlg->y + DIALOG_TB;
    y++;
    dlg_format_group(term, term, cq_cw_msg + 0, dlg->items + 0, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, cq_cw_msg + 1, dlg->items + 1, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, cq_cw_msg + 2, dlg->items + 2, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, cq_cw_msg + 3, dlg->items + 3, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
	dlg_format_group(term, term, cq_cw_msg + 4, dlg->items + 4, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
	dlg_format_group(term, term, cq_cw_msg + 5, dlg->items + 5, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    y++;
    dlg_format_buttons(term, term, dlg->items + 6, 2, dlg->x + DIALOG_LB, &y, w, NULL, AL_LEFT);
    
}

void cq_cw(void *arg){

    struct dialog *d;
    int i;
    int no;
    struct cq *cq;


    no = GPOINTER_TO_INT(arg);
    cq = g_ptr_array_index(cfg->cqs, no);
    
    safe_strncpy0(cw_str, cq->cw_str, MAX_STR_LEN);
    g_snprintf(cw_speed_str, EQSO_LEN, "%d", cq->cw_speed);
	cw_repeat = cq->cw_repeat;
	cw_breakable = cq->cw_breakable;
    g_snprintf(cw_ts_str, EQSO_LEN, "%d", cq->cw_ts);
    cw_allowifundef = cq->cw_allowifundef;

    
    if (!(d = g_malloc(sizeof(struct dialog) + 55 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 55 * sizeof(struct dialog_item));
    d->title = VTEXT(T_CW_CQ);
    d->fn = cq_cw_fn;
    d->refresh = (void (*)(void *))refresh_cq_cw;
    d->refresh_data = (void *)cq;
    
    d->items[i=0].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = cw_str;
    d->items[i].maxl = 60;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = cw_speed_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = cfg->cwda_maxwpm;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (void *)&cw_repeat;
    
	d->items[++i].type = D_CHECKBOX;
	d->items[i].gid = 0;
	d->items[i].gnum = 1;
	d->items[i].dlen = sizeof(int);
	d->items[i].data = (void *)&cw_breakable;

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = cw_ts_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 300;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (void *)&cw_allowifundef;
    

    d->items[++i].type = D_BUTTON; 
    d->items[i].gid = B_ENTER;
    d->items[i].fn = ok_dialog;
    d->items[i].text = VTEXT(T_OK);
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ESC;
    d->items[i].fn = cancel_dialog;
    d->items[i].text = VTEXT(T_CANCEL);
    
    
    d->items[++i].type = D_END;
    do_dialog(d, getml(d, NULL));
                               
}

void menu_cq_cw(void *arg){
    int i;
    char *c;
    struct menu_item *mi = NULL;
    struct cq *cq;
    char example[40];
    

    for (i=0; i<cfg->cqs->len; i++){
        cq = (struct cq *) g_ptr_array_index(cfg->cqs, i);
        
        safe_strncpy0(example, cq->cw_str, 40);
        c = g_strdup_printf(VTEXT(T_CW_DSCS), i, keys[i], cq->cw_repeat?'R':' ', example);
        if (!mi) if (!(mi = new_menu(3))) return;
        add_to_menu(&mi, 
                g_strdup(c), 
                "", "", 
                MENU_FUNC cq_cw, GINT_TO_POINTER(i), 0);    
        g_free(c);
    }
    if (i) 
        do_menu(mi, NULL);
    else
        do_menu(no_cq_defined_menu, NULL);
}


/*********************** SSB ****************************/

char ssb_file[MAX_STR_LEN];
int ssb_repeat, ssb_breakable;
char ssb_ts_str[EQSO_LEN];

void refresh_cq_ssb(void *xxx){
    struct cq *cq;

    cq = (struct cq *)xxx;
    
    STORE_STR(cq, ssb_file);
	cq->ssb_repeat = ssb_repeat;
	cq->ssb_breakable = ssb_breakable;
    cq->ssb_ts  = atoi(ssb_ts_str);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

char *cq_ssb_msg[] = {
   CTEXT(T_FILENAME), 
   CTEXT(T_REPEAT),
   TRANSLATE("Breakable"),
   CTEXT(T_DELAY), 
   "", /* OK */
   "", /* Cancel */
};


void cq_ssb_fn(struct dialog_data *dlg)
{
    struct terminal *term = dlg->win->term;
    int max = 0, min = 0;
    int w, rw;
    int y = -1;

    max_group_width(term, cq_ssb_msg + 0, dlg->items + 0, 1, &max);
    min_group_width(term, cq_ssb_msg + 0, dlg->items + 0, 1, &min);
    max_group_width(term, cq_ssb_msg + 1, dlg->items + 1, 1, &max);
    min_group_width(term, cq_ssb_msg + 1, dlg->items + 1, 1, &min);
    max_group_width(term, cq_ssb_msg + 2, dlg->items + 2, 1, &max);
    min_group_width(term, cq_ssb_msg + 2, dlg->items + 2, 1, &min);
	max_group_width(term, cq_ssb_msg + 3, dlg->items + 3, 1, &max);
	min_group_width(term, cq_ssb_msg + 3, dlg->items + 3, 1, &min);

    max_buttons_width(term, dlg->items + 4, 2, &max);
    min_buttons_width(term, dlg->items + 4, 2, &min);
    
    w = dlg->win->term->x * 9 / 10 - 2 * DIALOG_LB;
    if (w > max) w = max;
    if (w < min) w = min;
    if (w > dlg->win->term->x - 2 * DIALOG_LB - 8 ) w = dlg->win->term->x - 2 * DIALOG_LB - 8;
    if (w < 1) w = 1;
    
    rw = 0;
    y ++;
    dlg_format_group(NULL, term, cq_ssb_msg + 0, dlg->items + 0, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, cq_ssb_msg + 1, dlg->items + 1, 1, 0, &y, w, &rw);
	dlg_format_group(NULL, term, cq_ssb_msg + 2, dlg->items + 2, 1, 0, &y, w, &rw);
	dlg_format_group(NULL, term, cq_ssb_msg + 3, dlg->items + 3, 1, 0, &y, w, &rw);
    y++;
    dlg_format_buttons(NULL, term, dlg->items + 4, 2, 0, &y, w, &rw, AL_LEFT);
    
    
    w = rw;
    dlg->xw = w + 2 * DIALOG_LB;
    dlg->yw = y + 2 * DIALOG_TB;

    
    center_dlg(dlg);
    draw_dlg(dlg);
    y = dlg->y + DIALOG_TB;
    y++;
    dlg_format_group(term, term, cq_ssb_msg + 0, dlg->items + 0, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, cq_ssb_msg + 1, dlg->items + 1, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
	dlg_format_group(term, term, cq_ssb_msg + 2, dlg->items + 2, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
	dlg_format_group(term, term, cq_ssb_msg + 3, dlg->items + 3, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    y++;
    dlg_format_buttons(term, term, dlg->items + 4, 2, dlg->x + DIALOG_LB, &y, w, NULL, AL_LEFT);
    
}

void cq_ssb(void *arg){

    struct dialog *d;
    int i;
    int no;
    struct cq *cq;


    no = GPOINTER_TO_INT(arg);            
    cq = g_ptr_array_index(cfg->cqs, no);
    
    safe_strncpy0(ssb_file, cq->ssb_file, MAX_STR_LEN);
	ssb_repeat = cq->ssb_repeat;
	ssb_breakable = cq->ssb_breakable;
    g_snprintf(ssb_ts_str, EQSO_LEN, "%d", cq->ssb_ts);

    
    if (!(d = g_malloc(sizeof(struct dialog) + 55 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 55 * sizeof(struct dialog_item));
    d->title = VTEXT(T_SSB_CQ);
    d->fn = cq_ssb_fn;
    d->refresh = (void (*)(void *))refresh_cq_ssb;
    d->refresh_data = (void *)cq;
    
    d->items[i=0].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = ssb_file;
    d->items[i].maxl = 60;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (void *)&ssb_repeat;
    
	d->items[++i].type = D_CHECKBOX;
	d->items[i].gid = 0;
	d->items[i].gnum = 1;
	d->items[i].dlen = sizeof(int);
	d->items[i].data = (void *)&ssb_breakable;

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssb_ts_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 300;
    
    d->items[++i].type = D_BUTTON; 
    d->items[i].gid = B_ENTER;
    d->items[i].fn = ok_dialog;
    d->items[i].text = VTEXT(T_OK);
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ESC;
    d->items[i].fn = cancel_dialog;
    d->items[i].text = VTEXT(T_CANCEL);
    
    
    d->items[++i].type = D_END;
    do_dialog(d, getml(d, NULL));
                               
}


void menu_cq_ssb(void *arg){
    int i;
    char *c;
    struct menu_item *mi = NULL;
    struct cq *cq;
    char example[20];
    

    for (i=0; i<cfg->cqs->len; i++){
        cq = (struct cq *) g_ptr_array_index(cfg->cqs, i);

        safe_strncpy0(example, cq->ssb_file, 20);
        c = g_strdup_printf(VTEXT(T_SSB_DSCS), i, keys[i], cq->ssb_repeat?'R':' ', example);
        if (!mi) if (!(mi = new_menu(3))) return;
        add_to_menu(&mi, 
                g_strdup(c), 
                "", "", 
                MENU_FUNC cq_ssb, GINT_TO_POINTER(i), 0);    
        g_free(c);
    }
    if (i) 
        do_menu(mi, NULL);
    else
        do_menu(no_cq_defined_menu, NULL);
}



/******************* CWDAEMON **********************************/

int cwda_enabled, cwda_type;
char cwda_device[MAX_STR_LEN];
char cwda_hostname[MAX_STR_LEN];
char udp_port_str[EQSO_LEN];
char speed_str[EQSO_LEN];
char weight_str[EQSO_LEN];
char minwpm_str[EQSO_LEN], maxwpm_str[EQSO_LEN];
int cwda_spk;
char leadin_str[EQSO_LEN];
char tail_str[EQSO_LEN];
char autgive_str[EQSO_LEN];
    
void refresh_cwda(void *xxx){
    
	cfg->cwda_type=cwda_type;
    if (!cwda_enabled) cfg->cwda_type = CWD_NONE;
    STORE_STR(cfg, cwda_device);
    STORE_STR(cfg, cwda_hostname);
    cfg->cwda_udp_port = atoi(udp_port_str);
    cfg->cwda_speed = atoi(speed_str);
    cfg->cwda_weight = atoi(weight_str);
    if (cfg->cwda_weight < 30) cfg->cwda_weight = 30;
    if (cfg->cwda_weight > 70) cfg->cwda_weight = 70;
    cfg->cwda_minwpm = atoi(minwpm_str);
    cfg->cwda_maxwpm = atoi(maxwpm_str);
    cfg->cwda_spk = cwda_spk;
    cfg->cwda_leadin = atoi(leadin_str);
    cfg->cwda_tail = atoi(tail_str);
    cfg->cwda_autgive = atoi(autgive_str);
	
	free_cwdaemon(cwda);
	cwda=init_cwdaemon();
	progress(NULL);
#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}


void menu_cwda(void *arg){

    struct dialog *d;
    int i;
    
    cwda_enabled = cfg->cwda_type > 0;
	cwda_type=cfg->cwda_type;
    safe_strncpy0(cwda_device, cfg->cwda_device, MAX_STR_LEN);
    safe_strncpy0(cwda_hostname, cfg->cwda_hostname, MAX_STR_LEN);
    g_snprintf(udp_port_str, EQSO_LEN, "%d", cfg->cwda_udp_port);
    g_snprintf(speed_str, EQSO_LEN, "%d", cfg->cwda_speed);
    if (cfg->cwda_weight < 30 || cfg->cwda_weight > 70) cfg->cwda_weight = 50;
    g_snprintf(weight_str, EQSO_LEN, "%d", cfg->cwda_weight);
    g_snprintf(minwpm_str, EQSO_LEN, "%d", cfg->cwda_minwpm);
    g_snprintf(maxwpm_str, EQSO_LEN, "%d", cfg->cwda_maxwpm);
    cwda_spk=cfg->cwda_spk;
    g_snprintf(leadin_str, EQSO_LEN, "%d", cfg->cwda_leadin);
    g_snprintf(tail_str, EQSO_LEN, "%d", cfg->cwda_tail);
    g_snprintf(autgive_str, EQSO_LEN, "%d", cfg->cwda_autgive);

    
    if (!(d = g_malloc(sizeof(struct dialog) + 55 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 55 * sizeof(struct dialog_item));
    d->title = VTEXT(T_CW_DAEMON);
//  d->fn = cwda_fn;
    d->fn = dlg_pf_fn;
    d->refresh = (void (*)(void *))refresh_cwda;
    d->refresh_data = NULL;
    d->y0 = 1;
  
    d->items[i=0].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char*)&cwda_enabled;
    d->items[i].msg = CTEXT(T_ENABLED);//CTEXT(T_RIG_QRG_R2T);
    d->items[i].wrap = 1;

/*    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_NONE;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = CTEXT(T_ROT_NONE);*/
	
    d->items[++i].type = D_CHECKBOX; 
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_PARPORT;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = CTEXT(T_PARPORT);
	
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_TTYS;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = CTEXT(T_TTYS);
	
	d->items[++i].type = D_CHECKBOX;
	d->items[i].gid = 1;
	d->items[i].gnum = CWD_TTYS_SINGLE;
	d->items[i].dlen = sizeof(int);
	d->items[i].data = (char *)&cwda_type;
	d->items[i].msg = CTEXT(T_TTYSSINGLE);
	d->items[i].wrap = 1;

#ifdef Z_HAVE_LIBFTDI
	d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_DAVAC4;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = "Davac4";
#endif

#ifdef HAVE_HIDAPI
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_DAVAC5;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char*)&cwda_type;
    d->items[i].msg = "Davac5";
#endif

    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_CWD;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = "cwdaemon";
	
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_WINKEY;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
    d->items[i].msg = "winkey";

    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = CWD_WINKEYTCP;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_type;
	d->items[i].msg = "winkey TCP";
	d->items[i].wrap = 1;

#ifdef HAVE_HAMLIB
	d->items[++i].type = D_CHECKBOX;
	d->items[i].gid = 1;
	d->items[i].gnum = CWD_HAMLIB;
	d->items[i].dlen = sizeof(int);
	d->items[i].data = (char *)&cwda_type;
	d->items[i].msg = CTEXT(T_ROT_HAMLIB);
	d->items[i].wrap = 1;
#endif

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = cwda_device;
    d->items[i].maxl = 20;
    d->items[i].msg = CTEXT(T_DEVICE);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = cwda_hostname;
    d->items[i].maxl = 20;
    d->items[i].msg = CTEXT(T_HOSTNAME);
    
    d->items[++i].type = D_FIELD;    
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = udp_port_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 65535;
    d->items[i].msg = CTEXT(T_UDPPORT);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;      
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = speed_str;
    d->items[i].maxl = 3;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = cfg->cwda_maxwpm;
    d->items[i].msg = CTEXT(T_INIT_SPEED);
    
    d->items[++i].type = D_FIELD;     /* 10 */ 
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = weight_str;
    d->items[i].maxl = 3;
    d->items[i].msg = CTEXT(T_INIT_WEIGHT);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;  
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = minwpm_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 99;
    d->items[i].msg = CTEXT(T_WPMFROM);
    
    d->items[++i].type = D_FIELD;  
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = maxwpm_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 99;
    d->items[i].msg = CTEXT(T_WPMTO);
    d->items[i].wrap = 1;
    
#ifdef Z_UNIX
    d->items[++i].type = D_CHECKBOX;  
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&cwda_spk;
    d->items[i].msg = CTEXT(T_USE_SPK);
    d->items[i].wrap = 1;
#endif
    
    d->items[++i].type = D_FIELD;  
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = leadin_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 10000;
    d->items[i].msg = CTEXT(T_LEADIN);

	d->items[++i].type = D_FIELD;  
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = tail_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 10000;
    d->items[i].msg = TRANSLATE("PTT tail [ms]");//CTEXT(T_LEADIN);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;     /* 15 */
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = autgive_str;
    d->items[i].maxl = 3;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 9;
    d->items[i].msg = CTEXT(T_AUTGIVE);
    d->items[i].wrap = 2;

    d->items[++i].type = D_BUTTON;    
    d->items[i].gid = 0;
    d->items[i].fn = dlg_winkey_opts;
    d->items[i].text = VTEXT(T_WINKEYOPTS);
    d->items[i].wrap = 1;
    
#ifdef HAVE_HIDAPI

    d->items[++i].type = D_BUTTON;    
    d->items[i].gid = 0;
    d->items[i].fn = dlg_davac5_opts;
    d->items[i].text = TRANSLATE("Davac5 options");//VTEXT(T_WINKEYOPTS);
    d->items[i].wrap = 2;
#endif
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ENTER;
    d->items[i].fn = ok_dialog;
    d->items[i].text = VTEXT(T_OK);
    
    d->items[++i].type = D_BUTTON;    
    d->items[i].gid = B_ESC;
    d->items[i].fn = cancel_dialog;
    d->items[i].text = VTEXT(T_CANCEL);
    d->items[i].align = AL_BUTTONS;
    d->items[i].wrap = 1;
    
    
    d->items[++i].type = D_END;
    do_dialog(d, getml(d, NULL));
                               
}


/*********************** SSBD ****************************/

#ifdef HAVE_SNDFILE

#define MAX_RECORD_FORMAT 7
int record_format; /* index 0..MAX_RECORD_FORMAT-1 */
extern char ssbd_format_str[MAX_STR_LEN];
extern char ssbd_oss_src[MAX_STR_LEN];
extern char ssbd_alsa_src[MAX_STR_LEN];
#ifdef HAVE_PORTAUDIO
int ssbd_pa_play_hi, ssbd_pa_rec_hi;
char ssbd_pa_play_s[MAX_STR_LEN];
char ssbd_pa_rec_s[MAX_STR_LEN];
#endif

char *record_format_msg[]={
    CTEXT(T_PCM8),
    CTEXT(T_PCM16),
    CTEXT(T_ULAW),
    CTEXT(T_ALAW),
    CTEXT(T_IMAADPCM),
    CTEXT(T_MSADPCM),
    CTEXT(T_GSM610)
};

int record_formats[]={
    SF_FORMAT_WAV | SF_FORMAT_PCM_U8,
    SF_FORMAT_WAV | SF_FORMAT_PCM_16,
    SF_FORMAT_WAV | SF_FORMAT_ULAW,
    SF_FORMAT_WAV | SF_FORMAT_ALAW,
    SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM,
    SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM,
    SF_FORMAT_WAV | SF_FORMAT_GSM610
};

void record_format_func (void *arg){
    int active;
    
    active=GPOINTER_TO_INT(arg);
    if (active<0 || active>=MAX_RECORD_FORMAT) return;
    record_format = active;
    safe_strncpy0(ssbd_format_str,_(CTEXT(T_PCM8+record_format)),MAX_STR_LEN);
    redraw_later();
    
}

int dlg_record_format(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, sel;
    struct menu_item *mi;
    
    if (!(mi = new_menu(1))) return 0;
    for (i = 0; i < MAX_RECORD_FORMAT; i++) {
        add_to_menu(&mi, record_format_msg[i], "", "", MENU_FUNC record_format_func, GINT_TO_POINTER(i), 0);
    }
    sel = record_format;
    if (sel < 0) sel = 0;
    if (sel>=MAX_RECORD_FORMAT) sel=0;
    do_menu_selected(mi, GINT_TO_POINTER(record_format), sel);
    return 0;
}

/* ------------------------ */    

void alsa_src_func (void *arg){
    int i, active;
    GString *labels;
    gchar **items;
    
    active=GPOINTER_TO_INT(arg);

    labels=g_string_sized_new(100);
#ifdef HAVE_ALSA
    alsa_get_sources(gssbd->dsp, labels);
#endif    
    items=g_strsplit(labels->str, ";", 0);
    for (i=0;items[i]!=NULL;i++);/* dbg("items[%d]=%s\n", i, items[i]);*/
/*    dbg("alsa_src_func: active=%d max=%d\n", active, i);*/
    dbg("alsa_src_func(%d) labels='%s'\n", active, labels->str);
    
    if (active<0 || active>i) goto x;
    if (active==0)
        safe_strncpy0(ssbd_alsa_src,VTEXT(T_RECSRC_NONE),MAX_STR_LEN);
    else
        safe_strncpy0(ssbd_alsa_src,items[active-1],MAX_STR_LEN);
    dbg("  ssbd_alsa_src='%s'\n", ssbd_alsa_src);
    redraw_later();
x:;    
    g_string_free(labels, 1);
    g_strfreev(items);
}

int dlg_alsa_src(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, sel;
    struct menu_item *mi;
    GString *labels;
    gchar **items;
    
    labels=g_string_sized_new(100);


#ifdef HAVE_ALSA
    alsa_get_sources(gssbd->dsp, labels);
#endif    
    items=g_strsplit(labels->str, ";", 0);
    dbg("dlg_alsa_src() labels='%s'\n", labels->str);
    if (!(mi = new_menu(1))) goto x;
    add_to_menu(&mi, g_strdup(VTEXT(T_RECSRC_NONE)), "", "", MENU_FUNC alsa_src_func, GINT_TO_POINTER(0), 0);
    sel=0;
    for (i = 0; items[i]!=NULL; i++) {
        add_to_menu(&mi, g_strdup(items[i]), "", "", MENU_FUNC alsa_src_func, GINT_TO_POINTER(i+1), 0);
        if (strcmp(items[i], ssbd_alsa_src)==0) sel=i+1;
    }
    dbg("  sel=%d\n", sel);
    do_menu_selected(mi, NULL, sel);
x:;    
    g_string_free(labels, 1);
    g_strfreev(items);
    return 0;
}
    
/* ------------------------ */    

void oss_src_func (void *arg){
    int i, active;
    GString *labels;
    gchar **items;
    
    active=GPOINTER_TO_INT(arg);

    labels=g_string_sized_new(100);
#ifdef HAVE_OSS
    oss_get_sources(gssbd->dsp, labels);
#endif
    items=g_strsplit(labels->str, ";", 0);
    for (i=0;items[i]!=NULL;i++);/* dbg("items[%d]=%s\n", i, items[i]);*/
    dbg("oss_src_func: active=%d max=%d\n", active, i);

    if (active<0 || active>i) goto x;
    if (active==0)
        safe_strncpy0(ssbd_oss_src,VTEXT(T_RECSRC_NONE),MAX_STR_LEN);
    else
        safe_strncpy0(ssbd_oss_src,items[active-1],MAX_STR_LEN);
    redraw_later();
x:;    
    g_string_free(labels, 1);
    g_strfreev(items);
}

int dlg_oss_src(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, sel;
    struct menu_item *mi;
    GString *labels;
    gchar **items;
    
    labels=g_string_sized_new(100);

#ifdef HAVE_OSS
    oss_get_sources(gssbd->dsp, labels);
#endif
    items=g_strsplit(labels->str, ";", 0);
    dbg("labels='%s'\n", labels->str);
    if (!(mi = new_menu(1))) goto x;
    add_to_menu(&mi, g_strdup(VTEXT(T_RECSRC_NONE)), "", "", MENU_FUNC oss_src_func, GINT_TO_POINTER(0), 0);
    sel=0;
    for (i = 0; items[i]!=NULL; i++) {
        add_to_menu(&mi, g_strdup(items[i]), "", "", MENU_FUNC oss_src_func, GINT_TO_POINTER(i+1), 0);
        if (strcmp(items[i], ssbd_oss_src)==0) sel=i+1;
    }
    dbg("sel=%d\n", sel);
    do_menu_selected(mi, NULL, sel);
x:;    
    g_string_free(labels, 1);
    g_strfreev(items);
    return 0;
}

/* ------------------------ */    

#ifdef HAVE_PORTAUDIO
static void pa_play_src_func (void *arg){
    int active = GPOINTER_TO_INT(arg);

    const PaDeviceInfo *di = Pa_GetDeviceInfo(active);
    ssbd_pa_play_hi = di->hostApi;
    safe_strncpy0(ssbd_pa_play_s, di->name, MAX_STR_LEN);
    redraw_later();
}

static int dlg_pa_play_src(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, max, sel = 0, n;
    struct menu_item *mi;

    max = Pa_GetDeviceCount();
    mi = new_menu(1);
    n = 0;

	for (i = 0; i < max; i++){
    	const PaDeviceInfo *di = Pa_GetDeviceInfo(i);
		if (di->maxOutputChannels <= 0) continue;
        add_to_menu(&mi, g_strdup_printf("%d: %s", i, di->name), "", "", MENU_FUNC pa_play_src_func, GINT_TO_POINTER(i), 0);
		if (ssbd_pa_play_hi == di->hostApi && strcmp(di->name, ssbd_pa_play_s) == 0) sel = n;
        n++;
    }
    do_menu_selected(mi, NULL, sel);
	return 0;
}
    
/* ------------------------ */    

static void pa_rec_src_func(void *arg){
    int active = GPOINTER_TO_INT(arg);

    const PaDeviceInfo *di = Pa_GetDeviceInfo(active);
    ssbd_pa_rec_hi = di->hostApi;
    safe_strncpy0(ssbd_pa_rec_s, di->name, MAX_STR_LEN);
    redraw_later();
}

static int dlg_pa_rec_src(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, max, sel = 0, n;
    struct menu_item *mi;

    max = Pa_GetDeviceCount();
    mi = new_menu(1);
    n = 0;

	for (i = 0; i < max; i++){
    	const PaDeviceInfo *di = Pa_GetDeviceInfo(i);
		if (di->maxInputChannels <= 0) continue;
        add_to_menu(&mi, g_strdup_printf("%d: %s", i, di->name), "", "", MENU_FUNC pa_rec_src_func, GINT_TO_POINTER(i), 0);
        if (ssbd_pa_rec_hi == di->hostApi && strcmp(di->name, ssbd_pa_rec_s) == 0) sel = n;
        n++;
    }
    do_menu_selected(mi, NULL, sel);
	return 0;
}
#endif
    
/* ------------------------ */    
int ssbd_type;
int ssbd_record;
char ssbd_maxmin_str[EQSO_LEN], ssbd_diskfree_str[EQSO_LEN];
int ssbd_format; /* 0x100xx */
char ssbd_format_str[MAX_STR_LEN];
char ssbd_channels_str[EQSO_LEN], ssbd_samplerate_str[EQSO_LEN];
char ssbd_plev_str[EQSO_LEN], ssbd_rlev_str[EQSO_LEN];
char ssbd_template[MAX_STR_LEN];

char ssbd_pcm_play[EQSO_LEN], ssbd_pcm_rec[EQSO_LEN];
char ssbd_period_time_str[EQSO_LEN]/*, ssbd_buffer_time_str[EQSO_LEN]*/;
char ssbd_alsa_mixer[EQSO_LEN];
char ssbd_alsa_src[MAX_STR_LEN];
    
char ssbd_dsp[MAX_STR_LEN];
char ssbd_maxfrag_str[EQSO_LEN];
char ssbd_mixer[MAX_STR_LEN];
char ssbd_oss_src[MAX_STR_LEN];

char ssbd_hostname[MAX_STR_LEN],ssbd_udp_port_str[EQSO_LEN];

void refresh_ssbd(void *xxx){
    
    STORE_INT(cfg, ssbd_type);
    STORE_INT(cfg, ssbd_record);
    STORE_SINT(cfg, ssbd_maxmin);
    STORE_SINT(cfg, ssbd_diskfree);
    if (record_format<0 || record_format>=MAX_RECORD_FORMAT){
        cfg->ssbd_format = SF_FORMAT_WAV | SF_FORMAT_GSM610;
    }else{
        cfg->ssbd_format = record_formats[record_format];
    }
    dbg("refresh_ssbd: record_formats[%d]=0x%x (%s)\n", record_format, cfg->ssbd_format, _(CTEXT(T_PCM8+record_format)));
    STORE_SINT(cfg, ssbd_channels);
    STORE_SINT(cfg, ssbd_samplerate);
    STORE_SINT(cfg, ssbd_plev);
    STORE_SINT(cfg, ssbd_rlev);
    STORE_STR(cfg, ssbd_template);

    STORE_STR(cfg, ssbd_pcm_play);
    STORE_STR(cfg, ssbd_pcm_rec);
    STORE_SINT(cfg, ssbd_period_time);
    //STORE_SINT(cfg, ssbd_buffer_time);
    STORE_STR(cfg, ssbd_alsa_mixer);
    if (strcmp(ssbd_alsa_src, VTEXT(T_RECSRC_NONE))==0){
        strcpy(ssbd_alsa_src, "");
    }
    STORE_STR(cfg, ssbd_alsa_src);

    
    dbg("refresh_ssbd: ssbd_alsa_src='%s'\n", cfg->ssbd_alsa_src);

    STORE_STR(cfg, ssbd_dsp);
    STORE_SINT(cfg, ssbd_maxfrag);
    STORE_STR(cfg, ssbd_mixer);
    if (strcmp(ssbd_oss_src, VTEXT(T_RECSRC_NONE))==0){
        strcpy(ssbd_oss_src, "");
    }
    STORE_STR(cfg, ssbd_oss_src);
    dbg("refresh_ssbd: ssbd_oss_src='%s'\n", cfg->ssbd_oss_src);

#ifdef HAVE_PORTAUDIO
    STORE_INT(cfg, ssbd_pa_play_hi);
    STORE_INT(cfg, ssbd_pa_rec_hi);
    STORE_STR(cfg, ssbd_pa_play_s);
    STORE_STR(cfg, ssbd_pa_rec_s);

#endif

    STORE_STR(cfg, ssbd_hostname);
    STORE_SINT(cfg, ssbd_udp_port);

    free_ssbd(gssbd, 0);
    sw_scope_clear_scopes();
    gssbd=init_ssbd();
	progress(NULL);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

void do_ssbd(void){
    struct dialog *d;
    int i;
    GString *labels;
    gchar *c;

#ifdef HAVE_PORTAUDIO
    const PaDeviceInfo *di;

	if (!pa_initialised) {
		Pa_Initialize();
		pa_initialised = 1;
	}
#endif

    labels=g_string_sized_new(100);

    ssbd_type = cfg->ssbd_type;
    ssbd_record = cfg->ssbd_record;
    g_snprintf(ssbd_maxmin_str, EQSO_LEN, "%d", cfg->ssbd_maxmin);
    g_snprintf(ssbd_diskfree_str, EQSO_LEN, "%d", cfg->ssbd_diskfree);
    ssbd_format=cfg->ssbd_format;
    record_format=0;
    for (i=0;i<MAX_RECORD_FORMAT;i++) if (record_formats[i]==ssbd_format) record_format=i;
    safe_strncpy0(ssbd_format_str,_(CTEXT(T_PCM8+record_format)),MAX_STR_LEN);
    dbg("do_ssbd: ssbd_format=0x%x (%s)  record_format=%d\n", ssbd_format, ssbd_format_str, record_format);
    g_snprintf(ssbd_channels_str, EQSO_LEN, "%d", cfg->ssbd_channels);
    g_snprintf(ssbd_samplerate_str, EQSO_LEN, "%d", cfg->ssbd_samplerate);
    g_snprintf(ssbd_plev_str, EQSO_LEN, "%d", cfg->ssbd_plev);
    g_snprintf(ssbd_rlev_str, EQSO_LEN, "%d", cfg->ssbd_rlev);
    safe_strncpy0(ssbd_template, cfg->ssbd_template, MAX_STR_LEN);

    safe_strncpy0(ssbd_pcm_play, cfg->ssbd_pcm_play, EQSO_LEN);
    safe_strncpy0(ssbd_pcm_rec,  cfg->ssbd_pcm_rec,  EQSO_LEN);
    g_snprintf(ssbd_period_time_str, EQSO_LEN, "%d", cfg->ssbd_period_time);
    //g_snprintf(ssbd_buffer_time_str, EQSO_LEN, "%d", cfg->ssbd_buffer_time);
    safe_strncpy0(ssbd_alsa_mixer, cfg->ssbd_alsa_mixer, EQSO_LEN);
/*    safe_strncpy0(ssbd_alsa_src,   cfg->ssbd_alsa_src, MAX_STR_LEN);*/
    
    dbg("do_ssbd: cfg->ssbd_alsa_src='%s'\n", cfg->ssbd_alsa_src);
    if (cfg->ssbd_alsa_src && strlen(cfg->ssbd_alsa_src)>0){
        safe_strncpy0(ssbd_alsa_src,cfg->ssbd_alsa_src,MAX_STR_LEN);
    }else{
        safe_strncpy0(ssbd_alsa_src, VTEXT(T_RECSRC_NONE), MAX_STR_LEN);
    }
    dbg("do_ssbd: ssbd_alsa_src='%s'\n", ssbd_alsa_src);

    safe_strncpy0(ssbd_dsp, cfg->ssbd_dsp, MAX_STR_LEN);
    g_snprintf(ssbd_maxfrag_str, EQSO_LEN, "%d", cfg->ssbd_maxfrag);
    safe_strncpy0(ssbd_mixer, cfg->ssbd_mixer, MAX_STR_LEN);
    
    dbg("do_ssbd: cfg->ssbd_oss_src='%s'\n", cfg->ssbd_oss_src);
    if (cfg->ssbd_oss_src){
        if (!*cfg->ssbd_oss_src) c=NULL;
        else c=cfg->ssbd_oss_src;
    }else{
        c=NULL;
#ifdef HAVE_OSS
        c=oss_recsrc2source(cfg->ssbd_recsrc);
#endif
    }
    dbg("do_ssbd: cfg->ssbd_recsrc=%d label='%s'\n", cfg->ssbd_recsrc, c);
    if (c){
        safe_strncpy0(ssbd_oss_src,c,MAX_STR_LEN);
    }else{
        safe_strncpy0(ssbd_oss_src, VTEXT(T_RECSRC_NONE), MAX_STR_LEN);
    }

#ifdef HAVE_PORTAUDIO
    if (cfg->ssbd_pa_play_s != NULL && strlen(cfg->ssbd_pa_play_s) >= 0) {
        cfg->ssbd_pa_play = pa_find_device(cfg->ssbd_pa_play_s, cfg->ssbd_pa_play_hi, 1, 0);
    }
	if (cfg->ssbd_pa_play < 0) cfg->ssbd_pa_play = Pa_GetDefaultOutputDevice();
    di = Pa_GetDeviceInfo(cfg->ssbd_pa_play);
	if (di){
        ssbd_pa_play_hi = di->hostApi;
        safe_strncpy(ssbd_pa_play_s, di->name, MAX_STR_LEN);
	}else{
        ssbd_pa_play_hi = -1;
        safe_strncpy0(ssbd_pa_play_s, VTEXT(T_RECSRC_NONE), MAX_STR_LEN);
	}
    
    if (cfg->ssbd_pa_rec_s != NULL && strlen(cfg->ssbd_pa_rec_s) >= 0) {
        cfg->ssbd_pa_rec = pa_find_device(cfg->ssbd_pa_rec_s, cfg->ssbd_pa_rec_hi, 0, 1);
    }
    if (cfg->ssbd_pa_rec < 0) cfg->ssbd_pa_rec = Pa_GetDefaultInputDevice();
    di = Pa_GetDeviceInfo(cfg->ssbd_pa_rec);
	if (di){
        ssbd_pa_rec_hi = di->hostApi;
        safe_strncpy(ssbd_pa_rec_s, di->name, MAX_STR_LEN);
	}else{
        ssbd_pa_rec_hi = -1;
        safe_strncpy0(ssbd_pa_rec_s, VTEXT(T_RECSRC_NONE), MAX_STR_LEN);
    }
#endif
    

    safe_strncpy0(ssbd_hostname, cfg->ssbd_hostname, MAX_STR_LEN);
    g_snprintf(ssbd_udp_port_str, EQSO_LEN, "%d", cfg->ssbd_udp_port);
    
    g_string_free(labels, 0);

    if (!(d = (struct dialog *)g_malloc(sizeof(struct dialog) + 55 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 55 * sizeof(struct dialog_item));
    d->title = VTEXT(T_AUDIO);
    d->fn = dlg_pf_fn;
    d->refresh = (void (*)(void *))refresh_ssbd;
    d->y0 = 1;
    
	d->items[i = 0].type = D_TEXT; 
	d->items[i].msg = CTEXT(T_AUDIO_SUBSYSTEM);
#ifdef HAVE_ALSA
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = DSPT_ALSA;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&ssbd_type;
    d->items[i].msg = CTEXT(T_ALSA);
#endif
    
#ifdef HAVE_OSS
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = DSPT_OSS;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&ssbd_type;
    d->items[i].msg = CTEXT(T_OSS);
#endif

#ifdef HAVE_PORTAUDIO
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
    d->items[i].gnum = DSPT_PORTAUDIO;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&ssbd_type;
    d->items[i].msg = CTEXT(T_PORTAUDIO);
#endif
	
#ifdef USE_SDR
	d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 1;
	d->items[i].gnum = DSPT_SNDPIPE;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&ssbd_type;
    d->items[i].msg = CTEXT(T_SDR);
#endif

#ifdef HAVE_HAMLIB
	d->items[++i].type = D_CHECKBOX;
	d->items[i].gid = 1;
	d->items[i].gnum = DSPT_HAMLIB;
	d->items[i].dlen = sizeof(int);
	d->items[i].data = (char *)&ssbd_type;
	d->items[i].msg = CTEXT(T_ROT_HAMLIB);
#endif

	d->items[i].wrap = 1;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&ssbd_record;
    d->items[i].msg = CTEXT(T_RECORD);
    
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_maxmin_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 10000;
    d->items[i].msg = CTEXT(T_MAXMIN);

    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_diskfree_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 10000;
    d->items[i].msg = CTEXT(T_DISKFREE);
 
    d->items[++i].type = D_BUTTON;     
    d->items[i].gid  = 0;
    d->items[i].fn   = dlg_record_format;
    d->items[i].text = ssbd_format_str;
    d->items[i].msg = CTEXT(T_FORMAT); 
	d->items[i].wrap = 1;
 
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_channels_str;
    d->items[i].maxl = 3;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 8;
    d->items[i].msg = CTEXT(T_CHANNELS); 
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_samplerate_str;
    d->items[i].maxl = 7;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 4000;
    d->items[i].gnum = 192000;
    d->items[i].msg = CTEXT(T_SAMPLERATE); 

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_period_time_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 1000;
    d->items[i].msg = CTEXT(T_PERIOD); 
    
#if defined(HAVE_SYS_SOUNDCARD_H) || defined(HAVE_ALSA)
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_plev_str;
    d->items[i].maxl = 4;
    d->items[i].fn   = check_number;
    d->items[i].gid  = -1;
    d->items[i].gnum = 100;
    d->items[i].msg = CTEXT(T_PLAYBACK_VOLUME);
    
    d->items[++i].type = D_FIELD;    
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_rlev_str;
    d->items[i].maxl = 4;
    d->items[i].fn   = check_number;
    d->items[i].gid  = -1;
    d->items[i].gnum = 100;
    d->items[i].msg = CTEXT(T_CAPTURE_VOLUME);
#endif
	d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;  
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = ssbd_template;
    d->items[i].maxl = 30;
    d->items[i].msg = CTEXT(T_TEMPLATE);
	d->items[i].wrap = 2;
    
#ifdef HAVE_ALSA
    d->items[++i].type = D_FIELD;    
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_pcm_play;
    d->items[i].maxl = 15;
    d->items[i].msg = CTEXT(T_PCM_PLAY);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_pcm_rec;
    d->items[i].maxl = 15;
    d->items[i].msg = CTEXT(T_PCM_REC);
	d->items[i].wrap = 1;
    

    
    /*d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_buffer_time_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 1000;
    d->items[i].msg = CTEXT(T_BUFFER);
	d->items[i].wrap = 1;*/
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_alsa_mixer;
    d->items[i].maxl = 15;
    d->items[i].msg = CTEXT(T_ALSA_MIXER);
    
    d->items[++i].type = D_BUTTON;  
    d->items[i].gid  = 0;
    d->items[i].fn   = dlg_alsa_src;
    d->items[i].text = ssbd_alsa_src;
    d->items[i].msg = CTEXT(T_CAPTURE);
	d->items[i].wrap = 2;
#endif

#ifdef HAVE_SYS_SOUNDCARD_H
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = ssbd_dsp;
    d->items[i].maxl = 20;
    d->items[i].msg = CTEXT(T_DSP);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = ssbd_maxfrag_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 20;
    d->items[i].msg = CTEXT(T_MAXFRAG);
	d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;        
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = ssbd_mixer;
    d->items[i].maxl = 20;
    d->items[i].msg = CTEXT(T_MIXER);
    
    d->items[++i].type = D_BUTTON; 
    d->items[i].gid  = 0;
    d->items[i].fn   = dlg_oss_src;
    d->items[i].text = ssbd_oss_src;
    d->items[i].msg = CTEXT(T_RECSRC);
    d->items[i].wrap = 2;
#endif


#ifdef HAVE_PORTAUDIO
    d->items[++i].type = D_BUTTON;  
    d->items[i].gid  = 0;
    d->items[i].fn   = dlg_pa_play_src;
    d->items[i].text = ssbd_pa_play_s;
    d->items[i].msg = CTEXT(T_PA_PLAY);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_BUTTON;  
    d->items[i].gid  = 0;
    d->items[i].fn   = dlg_pa_rec_src;
    d->items[i].text = ssbd_pa_rec_s;
    d->items[i].msg = CTEXT(T_PA_REC);
    d->items[i].wrap = 2;
#endif
    
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ENTER;
    d->items[i].fn = ok_dialog;
    d->items[i].text = VTEXT(T_OK);
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ESC;
    d->items[i].fn = cancel_dialog;
    d->items[i].text = VTEXT(T_CANCEL);
    d->items[i].align = AL_BUTTONS;
    d->items[i].wrap = 2;
    
    
    d->items[++i].type = D_END;
    do_dialog(d, getml(d, NULL));
}


void menu_ssbd(void *arg){
    
    do_ssbd();
}
#endif //HAVE_SNDFILE


/*********************** NETWORK ****************************/

char net_if_ignore[MAX_STR_LEN],net_ip_ignore[MAX_STR_LEN],net_ip_announce[MAX_STR_LEN];
int trace_bcast, trace_sock, trace_recv, trace_send, trace_qsos, trace_rig, trace_sdev, trace_keys;
int net_remote_enable;
char net_remote_host[MAX_STR_LEN], net_remote_port_str[EQSO_LEN], net_remote_pass[MAX_STR_LEN];

void refresh_net(void *xxx){
	int raise = 0;
	if (trace_bcast && !cfg->trace_bcast) raise++;
	if (trace_sock && !cfg->trace_sock) raise++;
	if (trace_recv && !cfg->trace_recv) raise++;
	if (trace_send && !cfg->trace_send) raise++;
	if (trace_rig  && !cfg->trace_rig)  raise++;
	if (trace_qsos && !cfg->trace_qsos) raise++;
	if (trace_sdev && !cfg->trace_sdev) raise++;
	if (trace_keys && !cfg->trace_keys) raise++;
    
    STORE_STR(cfg, net_if_ignore);
    STORE_STR(cfg, net_ip_ignore);
    STORE_STR(cfg, net_ip_announce);

	STORE_INT(cfg, net_remote_enable);
    STORE_STR(cfg, net_remote_host);
    STORE_SINT(cfg, net_remote_port);
    STORE_STR(cfg, net_remote_pass);

    STORE_INT(cfg, trace_bcast);
    STORE_INT(cfg, trace_sock);
    STORE_INT(cfg, trace_recv);
    STORE_INT(cfg, trace_send);
    STORE_INT(cfg, trace_qsos);
    STORE_INT(cfg, trace_rig);
    STORE_INT(cfg, trace_sdev);
    STORE_INT(cfg, trace_keys);
    
    free_net_ifaces(gnet);
    init_net_ifaces(gnet, 1);
	net_connect_remote(gnet);
	if (raise){
		sw_raise_or_new(SWT_LOG);
	}

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}


void do_net(void){

    struct dialog *d;
    int i;
    
    safe_strncpy0(net_if_ignore, cfg->net_if_ignore, MAX_STR_LEN);
    safe_strncpy0(net_ip_ignore, cfg->net_ip_ignore, MAX_STR_LEN);
    safe_strncpy0(net_ip_announce, cfg->net_ip_announce, MAX_STR_LEN);
	net_remote_enable = cfg->net_remote_enable;
    safe_strncpy0(net_remote_host, cfg->net_remote_host, MAX_STR_LEN);
    g_snprintf(net_remote_port_str, EQSO_LEN, "%d", cfg->net_remote_port);
    safe_strncpy0(net_remote_pass, cfg->net_remote_pass, MAX_STR_LEN);
    trace_bcast=cfg->trace_bcast;
    trace_sock=cfg->trace_sock;
    trace_recv=cfg->trace_recv;
    trace_send=cfg->trace_send;
    trace_qsos=cfg->trace_qsos;
	trace_rig=cfg->trace_rig;
	trace_sdev=cfg->trace_sdev;
    trace_keys=cfg->trace_keys;

    
    if (!(d = (struct dialog *) g_malloc(sizeof(struct dialog) + 55 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 55 * sizeof(struct dialog_item));
    d->title = VTEXT(T_NETWORK);
    d->fn = dlg_pf_fn;
    d->refresh = (void (*)(void *))refresh_net;
    d->y0 = 1;
	i = -1;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&net_remote_enable;
    d->items[i].msg = CTEXT(T_ENABLE_REMOTE_CONNECT);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = net_remote_host;
    d->items[i].maxl = 24;
    d->items[i].msg = CTEXT(T_REMOTE_HOST);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = net_remote_port_str;
    d->items[i].maxl = 24;
	d->items[i].gid  = 0;
	d->items[i].gnum = 65535;
    d->items[i].msg = CTEXT(T_REMOTE_PORT);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = net_remote_pass;
    d->items[i].maxl = 24;
    d->items[i].msg = CTEXT(T_REMOTE_PASS);
    d->items[i].wrap = 2;

   
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = net_if_ignore;
    d->items[i].maxl = 24;
    d->items[i].msg = CTEXT(T_IF_IGNORE);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = net_ip_ignore;
    d->items[i].maxl = 24;
    d->items[i].msg = CTEXT(T_IP_IGNORE);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;     
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = net_ip_announce;
    d->items[i].maxl = 24;
    d->items[i].msg = CTEXT(T_IP_ANNOUNCE);
    d->items[i].wrap = 2;


    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_bcast;
    d->items[i].msg = CTEXT(T_TRACE_BCAST);
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_sock;
    d->items[i].msg = CTEXT(T_TRACE_SOCK);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_CHECKBOX;  
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_recv;
    d->items[i].msg = CTEXT(T_TRACE_RECV);
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_send;
    d->items[i].msg = CTEXT(T_TRACE_SEND);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_qsos;
    d->items[i].msg = CTEXT(T_TRACE_QSOS);
    
	d->items[++i].type = D_CHECKBOX3;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_rig;
    d->items[i].msg = CTEXT(T_TRACE_RIG);//CTEXT(T_TRACE_SDEV);
    d->items[i].wrap = 1;

	d->items[++i].type = D_CHECKBOX3;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_sdev;
    d->items[i].msg = CTEXT(T_TRACE_SDEV);
    d->items[i].wrap = 0;

    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&trace_keys;
    d->items[i].msg = CTEXT(T_TRACE_KEYS);//CTEXT(T_TRACE_SDEV);
    d->items[i].wrap = 2;
    
	d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ENTER;
    d->items[i].fn = ok_dialog;
    d->items[i].text = VTEXT(T_OK);
    
    d->items[++i].type = D_BUTTON;
    d->items[i].gid = B_ESC;
    d->items[i].fn = cancel_dialog;
    d->items[i].text = VTEXT(T_CANCEL);
    d->items[i].align = AL_BUTTONS;
    d->items[i].wrap = 1;
    
    
    d->items[++i].type = D_END;
    do_dialog(d, getml(d, NULL));
                               
}


void menu_network(void *arg){
    
    do_net();
}



