/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2023  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 "bfu.h"
#include "fifo.h"
#include "kbd.h"
#include "main.h"
#include "menu.h"
#include "qsodb.h"
#include "rc.h"
#include "rotar.h"
#include "tsdl.h"
#include "terminal.h"
#include "trig.h"

/******************** MISC OPTIONS *******************************/


char loglines_str[MAX_STR_LEN],skedcount_str[MAX_STR_LEN],startbandchar_str[MAX_STR_LEN];
char gfx_x_ch_str[MAX_STR_LEN],gfx_y_ch_str[MAX_STR_LEN];
char gfx_x_px_str[MAX_STR_LEN],gfx_y_px_str[MAX_STR_LEN];
int fullscreen, usetouch, altsyms, nolocks, portrait, reverse, inverse;
char fontheight_str[EQSO_LEN];
char slashkey[3];
int dssaver;
int adif_export_mode_t2r;
char adif_export_mode_t2r_str[EQSO_LEN];
char *adif_export_modes[] = {
    "Error",
    "Call",
    "Skip"
};
char logdirpath[MAX_STR_LEN];

void refresh_misc_opts(void *xxx)
{
    struct config_band *confb;
    int gfx_x_ch, gfx_y_ch, gfx_x_px, gfx_y_px;
    int new_w = 800, new_h = 600, resize, new_fh;


	resize=0;
    if (cfg->loglines != atoi(loglines_str)) {
        resize++;
#ifdef Z_HAVE_SDL
        if (cfg->loglines != atoi(loglines_str)) {
            new_w = sdl->screen->w;
            new_h = sdl->screen->h;
        }
#endif
    }

    STORE_SINT(cfg,loglines);
    STORE_SINT(cfg,skedcount);

    confb=get_config_band_by_bandchar(startbandchar_str[0]);
    if (confb){
        CONDGFREE(cfg->startband);
        cfg->startband=g_strdup(confb->pband);
    }
    gfx_x_ch=atoi(gfx_x_ch_str);
    gfx_y_ch=atoi(gfx_y_ch_str);
    gfx_x_px=atoi(gfx_x_px_str);
    gfx_y_px=atoi(gfx_y_px_str);
    STORE_STR(cfg, slashkey);
    STORE_INT(cfg, dssaver);
	STORE_INT(cfg, usetouch);
	STORE_INT(cfg, altsyms);
	STORE_INT(cfg, nolocks);
    if (portrait != cfg->portrait || reverse != cfg->reverse){
#ifdef Z_ANDROID
        log_addf(VTEXT(T_SAVE_RESTART));
#endif
	    STORE_INT(cfg, portrait);
	    STORE_INT(cfg, reverse);
    }

	STORE_INT(cfg, inverse);
	STORE_INT(cfg, adif_export_mode_t2r);
	STORE_STR(cfg, logdirpath);
    
    new_fh = atoi(fontheight_str);

#ifdef Z_HAVE_SDL    
    if (sdl){
		if (new_fh !=cfg->fontheight) {
			cfg->fontheight = new_fh;
			new_w = sdl->screen->w;
			new_h = sdl->screen->h;
			resize++;
		}
		if (fullscreen != cfg->fullscreen){
			cfg->fullscreen = fullscreen;
			new_w = sdl->screen->w;
			new_h = sdl->screen->h;
			resize++;
		}
        if (gfx_x_ch>10 && gfx_y_ch>10){
            if (gfx_x_ch * zsdl->font_w != cfg->gfx_x ||
                gfx_y_ch * zsdl->font_h != cfg->gfx_y){
                new_w = gfx_x_ch * zsdl->font_w;
                new_h = gfx_y_ch * zsdl->font_h;
                resize++;
            }
        }
        if (gfx_x_px > 100 && gfx_y_px > 100){
            if (gfx_x_px != cfg->gfx_x ||
                gfx_y_px != cfg->gfx_y){
                new_w = gfx_x_px;
                new_h = gfx_y_px;
                resize++;
            }
        }
		if (inverse != zsdl->inverse){
			resize++;
		}

		if (resize && new_w <= 3840 && new_h <= 3840) {
            cfg->gfx_x = new_w;
            cfg->gfx_y = new_h;
            sdl_setvideomode(new_w, new_h, 0);
            resize_terminal(NULL);
        }
    }
    else
#endif  
    {
        if (resize) resize_terminal(NULL);
    }

	set_logs_dir();


#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

void set_adif_export_mode(void *arg, void *arg2){
    adif_export_mode_t2r = GPOINTER_TO_INT(arg);
    strcpy(adif_export_mode_t2r_str, adif_export_modes[adif_export_mode_t2r]);
    redraw_later();
}

int choose_adif_export_mode(struct dialog_data *dlg, struct dialog_item_data *di){
    struct menu_item *mi;
    int i;

    if (!(mi = new_menu(1))) return 0;

    for (i = 0; i < 3; i++) add_to_menu(&mi, adif_export_modes[i], "", "", set_adif_export_mode, GINT_TO_POINTER(i), 0);
    do_menu_selected(mi, di->cdata, adif_export_mode_t2r);
    return 0;
}

void misc_opts(void *arg)
{
    struct dialog *d;
    int i;
    struct config_band *confb;

    g_snprintf(loglines_str, MAX_STR_LEN, "%d", cfg->loglines);
    g_snprintf(skedcount_str, MAX_STR_LEN, "%d", cfg->skedcount);
    
    confb=get_config_band_by_pband(cfg->startband);
    if (!confb) confb=(struct config_band *)g_ptr_array_index(cfg->bands,0);
    startbandchar_str[0]=confb->bandchar;
    startbandchar_str[1]='\0';

//    dbg("gfx_x=%d gfx_x=%d %%=%d %d\n", cfg->gfx_x, cfg->gfx_y, cfg->gfx_x%sdl->font_w, cfg->gfx_y%font_h);
#ifdef Z_HAVE_SDL        
    if (sdl){
        if (cfg->gfx_x % zsdl->font_w!=0 || cfg->gfx_y % zsdl->font_h!=0){
            strcpy(gfx_x_ch_str, "");
            strcpy(gfx_y_ch_str, "");
        }else{
            g_snprintf(gfx_x_ch_str, MAX_STR_LEN, "%d", cfg->gfx_x/zsdl->font_w);
            g_snprintf(gfx_y_ch_str, MAX_STR_LEN, "%d", cfg->gfx_y/zsdl->font_h);
        }
    }
    else
#endif        
    {
        strcpy(gfx_x_ch_str, "");
        strcpy(gfx_y_ch_str, "");
    }

    g_snprintf(gfx_x_px_str, MAX_STR_LEN, "%d", cfg->gfx_x);
    g_snprintf(gfx_y_px_str, MAX_STR_LEN, "%d", cfg->gfx_y);
    g_snprintf(fontheight_str, EQSO_LEN, "%d", cfg->fontheight);
    safe_strncpy0(slashkey, cfg->slashkey, sizeof(slashkey));
    dssaver = cfg->dssaver;
	fullscreen = cfg->fullscreen;
	usetouch = cfg->usetouch;
	altsyms = cfg->altsyms;
	nolocks = cfg->nolocks;
	portrait = cfg->portrait;
	reverse = cfg->reverse;
	inverse = cfg->inverse;
	adif_export_mode_t2r = cfg->adif_export_mode_t2r;
	LOAD_STR(cfg, logdirpath);

    d = g_new0(struct dialog, 20);
    d->title = VTEXT(T_MISCOPTS);
    d->fn = dlg_pf_fn;
    d->refresh = (void (*)(void *))refresh_misc_opts;
    d->y0 = 1;
	i = -1;
    

#ifdef Z_HAVE_SDL
	if (sdl){
		d->items[++i].type = D_FIELD;
		d->items[i].fn = check_number;
		d->items[i].gid = 13;
		d->items[i].gnum = 40;
		d->items[i].maxl = 5;
		d->items[i].dlen = EQSO_LEN;
		d->items[i].data = fontheight_str;
		d->items[i].msg = CTEXT(T_FONTHEIGHT);
		d->items[i].wrap = 1;
    
		d->items[++i].type = D_FIELD;
		d->items[i].dlen = MAX_STR_LEN;
		d->items[i].data = gfx_x_ch_str;
		d->items[i].maxl = 5;
		d->items[i].msg = CTEXT(T_GFX_X_CH);
    
		d->items[++i].type = D_FIELD;
		d->items[i].dlen = MAX_STR_LEN;
		d->items[i].data = gfx_y_ch_str;
		d->items[i].maxl = 5;
		d->items[i].msg = CTEXT(T_GFX_Y_CH);
		d->items[i].wrap = 1;
    
		d->items[++i].type = D_FIELD;
		d->items[i].dlen = MAX_STR_LEN;
		d->items[i].data = gfx_x_px_str;
		d->items[i].maxl = 5;
		d->items[i].msg = CTEXT(T_GFX_X_PX);
    
		d->items[++i].type = D_FIELD;
		d->items[i].dlen = MAX_STR_LEN;
		d->items[i].data = gfx_y_px_str;
		d->items[i].maxl = 5;
		d->items[i].msg = CTEXT(T_GFX_Y_PX);
		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 *)&fullscreen;
		d->items[i].msg = CTEXT(T_FULLSCREEN);
		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 *)&usetouch;
		d->items[i].msg = CTEXT(T_TOUCH);
		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 *)&altsyms;
		d->items[i].msg = CTEXT(T_ALT_QWER);
		d->items[i].wrap = 1;

	}
#endif

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = startbandchar_str;
    d->items[i].maxl = 3;
    d->items[i].msg = CTEXT(T_STARTBAND);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = loglines_str;
    d->items[i].maxl = 3;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 30;
    d->items[i].msg = CTEXT(T_LOGLINES);
    d->items[i].wrap = 1;
    
  
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = skedcount_str;
    d->items[i].maxl = 3;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 10;
    d->items[i].msg = CTEXT(T_SKEDCOUNT);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = 3;
    d->items[i].data = slashkey;
    d->items[i].maxl = 2;
    d->items[i].msg = CTEXT(T_SLASHKEY);
    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 *)&dssaver;
    d->items[i].msg = CTEXT(T_DSSAVER);
	d->items[i].wrap = 1;

//#ifdef Z_UNIX_ANDROID
	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 *)&nolocks;
	d->items[i].msg = CTEXT(T_NO_LOCKS);
	d->items[i].wrap = 1;
//#endif
    
	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 *)&portrait;
	d->items[i].msg = CTEXT(T_PORTRAIT_ORIENTATION);

#ifdef Z_ANDROID
	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 *)&reverse;
	d->items[i].msg = CTEXT(T_REVERSE);
#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 *)&inverse;
	d->items[i].msg = TRANSLATE("Inverse display");
	d->items[i].wrap = 1;

	strcpy(adif_export_mode_t2r_str, adif_export_modes[adif_export_mode_t2r]);
	d->items[++i].type = D_BUTTON;
	d->items[i].gid = 0;
	d->items[i].fn = choose_adif_export_mode;
	d->items[i].data=(char *)&adif_export_mode_t2r;
	d->items[i].msg = CTEXT(T_ADIF_EXPORT_MODE);
	d->items[i].text = adif_export_mode_t2r_str;
	d->items[i].wrap = 1;

	d->items[++i].type = D_FIELD;
	d->items[i].dlen = MAX_STR_LEN;
	d->items[i].data = logdirpath;
	d->items[i].maxl = 15;
	d->items[i].msg = CTEXT(T_LOGDIR_PATH);
	d->items[i].wrap = 1;

	d->items[i].wrap++;
    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));
}

/*********************** FIXQRG - Fix rig frequency *************************/

#ifdef HAVE_HAMLIB
void fixqrg(void *xxx, char *qrgstr){
    gdouble newqrg;
	int rignr = GPOINTER_TO_INT(xxx);

    if (!qrgstr) return;

	     
    //newqrg = atof(qrgstr);
	newqrg = z_qrg_parse(qrgstr);
    if (newqrg<=0){
        errbox(CTEXT(T_BAD_QRG), 0);
        return;
    }

    set_rig_lo(aband, rignr, get_rig_lo(aband, rignr) + newqrg - gtrigs->qrg);
    
    trigs_resend_freq(gtrigs, rignr);
}


void do_fixqrg(void *itdata, void *menudata){
    static char qrgstr[256];
	//int rignr = GPOINTER_TO_INT(itdata);
    
    //g_snprintf(qrgstr, EQSO_LEN, "%1.0f", gtrigs->qrg);
	z_qrg_format(qrgstr, sizeof(qrgstr), gtrigs->qrg); 

    input_field(NULL, CTEXT(T_FIXQRG), CTEXT(T_ENTER_QRG) ,
               CTEXT(T_OK), CTEXT(T_CANCEL), itdata, 
               NULL, 20, qrgstr, 0, 0, NULL,
               /*(void (*)(void *, char *))*/ fixqrg, NULL, 0);

}

void menu_fixqrg(void *itdata, void *menudata){
	int i, enabled = 0;

	for (i = 0; i < gtrigs->trigs->len; i++){
		struct config_rig *crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, i);
		if (crig->rig_enabled) enabled++;
	}

	if (enabled > 1){
		int i;
		struct menu_item *mi = new_menu(3);
		mi->rtext = VTEXT(T_CHOOSE_RIG);
		for (i = 0; i < gtrigs->trigs->len; i++){
			struct config_rig *crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, i);
			if (!crig->rig_enabled) continue;
			add_to_menu(&mi, 
				g_strdup_printf(VTEXT(T_RIG_D), i), "", "", MENU_FUNC do_fixqrg, GINT_TO_POINTER(i), 0);
		}
		set_window_ptr(gses->win, (term->x - strlen(mi->rtext) - 6) / 2, (term->y - 2 - gtrigs->trigs->len) / 2);
		do_menu(mi, NULL);
		return;
	}
	do_fixqrg(itdata, menudata);
}
#endif


/************************** winkey ******************************/

int wk_wk2, wk_usepot, wk_usebut, wk_keymode, wk_swap, wk_echoback;


void refresh_winkey_opts(void *xxx)
{
    STORE_INT(cfg, wk_wk2);
    STORE_INT(cfg, wk_usepot);
    STORE_INT(cfg, wk_usebut);
    STORE_INT(cfg, wk_keymode);
    STORE_INT(cfg, wk_swap);
    STORE_INT(cfg, wk_echoback);
}

char *winkey_opts_msg[] = {
    CTEXT(T_WK_WK2),
    CTEXT(T_WK_USEPOT),
    CTEXT(T_WK_USEBUT),
    CTEXT(T_WK_KM_B), 
    CTEXT(T_WK_KM_A), 
    CTEXT(T_WK_KM_U), 
    CTEXT(T_WK_KM_G), 
    CTEXT(T_WK_SWAP),
    CTEXT(T_WK_ECHOBACK),
    "",
    ""
};

void winkey_opts_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, winkey_opts_msg + 0, dlg->items + 0, 1, &max);
    min_group_width(term, winkey_opts_msg + 0, dlg->items + 0, 1, &min);
    max_group_width(term, winkey_opts_msg + 1, dlg->items + 1, 2, &max);
    min_group_width(term, winkey_opts_msg + 1, dlg->items + 1, 2, &min);
    max_group_width(term, winkey_opts_msg + 3, dlg->items + 3, 4, &max);
    min_group_width(term, winkey_opts_msg + 3, dlg->items + 3, 4, &min);
    max_group_width(term, winkey_opts_msg + 7, dlg->items + 1, 1, &max);
    min_group_width(term, winkey_opts_msg + 7, dlg->items + 1, 1, &min);
    max_group_width(term, winkey_opts_msg + 8, dlg->items + 1, 1, &max);
    min_group_width(term, winkey_opts_msg + 8, dlg->items + 1, 1, &min);
    
    max_buttons_width(term, dlg->items + 9, 2, &max);
    min_buttons_width(term, dlg->items + 9, 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) w = dlg->win->term->x - 2 * DIALOG_LB;
    if (w < 1) w = 1;
    
    rw = 0;
    y ++;
    dlg_format_group(NULL, term, winkey_opts_msg + 0, dlg->items + 0, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, winkey_opts_msg + 1, dlg->items + 1, 2, 0, &y, w, &rw);
    dlg_format_group(NULL, term, winkey_opts_msg + 3, dlg->items + 3, 4, 0, &y, w, &rw);
    dlg_format_group(NULL, term, winkey_opts_msg + 7, dlg->items + 7, 1, 0, &y, w, &rw);
    dlg_format_group(NULL, term, winkey_opts_msg + 8, dlg->items + 8, 1, 0, &y, w, &rw);
    y++;
    dlg_format_buttons(NULL, term, dlg->items +9, 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, winkey_opts_msg + 0, dlg->items + 0, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, winkey_opts_msg + 1, dlg->items + 1, 2, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, winkey_opts_msg + 3, dlg->items + 3, 4, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, winkey_opts_msg + 7, dlg->items + 7, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    dlg_format_group(term, term, winkey_opts_msg + 8, dlg->items + 8, 1, dlg->x + DIALOG_LB, &y, w, AL_LEFT);
    y++;
    dlg_format_buttons(term, term, dlg->items +9, 2, dlg->x + DIALOG_LB, &y, w, NULL, AL_LEFT);
}

void winkey_opts(void *arg)
{
    struct dialog *d;
    int i;

    wk_wk2 = cfg->wk_wk2;
    wk_usepot = cfg->wk_usepot;
    wk_usebut = cfg->wk_usebut;
    wk_keymode = cfg->wk_keymode;
    wk_swap = cfg->wk_swap;
    wk_echoback = cfg->wk_echoback;


    if (!(d = (struct dialog *)g_malloc(sizeof(struct dialog) + 20 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 20 * sizeof(struct dialog_item));
    d->title = VTEXT(T_WINKEYOPTS); 
    d->fn = winkey_opts_fn;
    d->refresh = (void (*)(void *))refresh_winkey_opts;
    
    d->items[i=0].type = D_CHECKBOX;    /* 0 */
    d->items[i].gid  = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_wk2;
    
    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 *)&wk_usepot;
    
    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 *)&wk_usebut;
    
    d->items[++i].type = D_CHECKBOX;  /* 3 */
    d->items[i].gid  = 1;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_keymode;

    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid  = 1;
    d->items[i].gnum = 2;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_keymode;

    d->items[++i].type = D_CHECKBOX;       /* 5 */
    d->items[i].gid  = 1;
    d->items[i].gnum = 3;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_keymode;

    d->items[++i].type = D_CHECKBOX;
    d->items[i].gid  = 1;
    d->items[i].gnum = 4;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_keymode;

    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 *)&wk_swap;

    d->items[++i].type = D_CHECKBOX;       /* 8 */
    d->items[i].gid  = 0;
    d->items[i].gnum = 1;
    d->items[i].dlen = sizeof(int);
    d->items[i].data = (char *)&wk_echoback;

    d->items[++i].type = D_BUTTON;   /* 9 */
    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));
}

int dlg_winkey_opts(struct dialog_data *dd, struct dialog_item_data *did){
    winkey_opts(NULL);
    return 0;
}


/************************** rig ******************************/
#ifdef HAVE_HAMLIB
int rig_enabled;
char rig_desc[MAX_STR_LEN];
char rig_filename[MAX_STR_LEN];
char rig_model_str[EQSO_LEN];
int rig_model;
char rig_speed_str[EQSO_LEN];
int rig_handshake_none;
/* choose manufacturer */
char rig_civaddr_str[EQSO_LEN];
char rig_ssbcw_shift_str[EQSO_LEN];
char rig_lo_str[MAX_STR_LEN];
//int rig_poll_ms;
char rig_poll_ms_str[MAX_STR_LEN];
int rig_qrg_r2t, rig_qrg_t2r, rig_mode_t2r, rig_clr_rit, rig_ptt_t2r, rig_verbose;
char rig_ptt_t2r_str[EQSO_LEN];
char rig_conf[MAX_STR_LEN];

int new_model = 0;
char new_model_name[EQSO_LEN];

char *rig_ptt_types[] = {
    "Unused", 
    "PTT", 
    "PTT MIC",
    "PTT DATA"
};

void set_rig (void *arg){
    struct rig_caps *mcaps;
    int active;
    
    active = GPOINTER_TO_INT(arg);
    if (active < 0 || active >= riglist->len) return;
    mcaps = (struct rig_caps *)z_ptr_array_index(riglist, active);
    
    dbg("%4d %4d %-20s %s\n", active, mcaps->rig_model, mcaps->mfg_name, mcaps->model_name);
	new_model = mcaps->rig_model;
    g_snprintf(new_model_name, EQSO_LEN, "%s", mcaps->model_name);
    dbg("set_rig: new_model = %d (%s)\n", new_model, new_model_name);
    redraw_later();
}
    
void choose_rig (void *arg){
    struct rig_caps *mcaps;
    int i, sel=0, model;
    struct menu_item *mi;
    int active;
    
    active = GPOINTER_TO_INT(arg);
    if (active < 0 || active >= riglist->len) return;
    mcaps = (struct rig_caps *)z_ptr_array_index(riglist, active);
    
    dbg("%4d %4d %-20s %s\n", active, mcaps->rig_model, mcaps->mfg_name, mcaps->model_name);
    
    if (!(mi = new_menu(1))) return;

    model = GPOINTER_TO_INT(arg);
    for (i=active; i<riglist->len; i++){
        struct rig_caps *caps = (struct rig_caps *)z_ptr_array_index(riglist, i);
        if (strcasecmp(mcaps->mfg_name, caps->mfg_name)!=0) break;
        if (model==caps->rig_model) sel = i - active;
        add_to_menu(&mi, (char *)caps->model_name, "", "", MENU_FUNC set_rig, GINT_TO_POINTER(i), 0);
    }
    
    dbg("sel=%d\n", sel);
    do_menu_selected(mi, NULL, sel);
    
}

int choose_manufacturer(struct dialog_data *dlg, struct dialog_item_data *di){
    int i, sel=0, j=0, same, model;
    struct menu_item *mi;
    const char *old = NULL;
    
    if (!(mi = new_menu(1))) return 0;
    
	model = GPOINTER_TO_INT(di->cdata);
    dbg("rig_model=%d\n", model);
    for (i=0; i<riglist->len; i++){
        struct rig_caps *caps = (struct rig_caps *)z_ptr_array_index(riglist, i);
        same=0;
        if (old && strcasecmp(old, caps->mfg_name)==0) same=1;
        
        if (model==caps->rig_model) {
            dbg("i=%d j=%d\n", i, j);
            sel = j;
            if (same) sel--;
        }
        if (same) continue;
        
        add_to_menu(&mi, (char *)caps->mfg_name, "", "", MENU_FUNC choose_rig, GINT_TO_POINTER(i), 0);
        old = caps->mfg_name;
        j++;
    }
    dbg("sel=%d\n", sel);
    do_menu_selected(mi, di->cdata, sel);
    return 0;
}

void set_ptt_type(void *arg, void *arg2){
    rig_ptt_t2r = GPOINTER_TO_INT(arg);
    strcpy(rig_ptt_t2r_str, rig_ptt_types[rig_ptt_t2r]);
    redraw_later();
}

int choose_ptt_type(struct dialog_data *dlg, struct dialog_item_data *di){
    struct menu_item *mi;
    int i;
    
    if (!(mi = new_menu(1))) return 0;

    for (i = 0; i < 4; i++) add_to_menu(&mi, rig_ptt_types[i], "", "", set_ptt_type, GINT_TO_POINTER(i), 0);
    do_menu_selected(mi, di->cdata, rig_ptt_t2r);
    return 0;
}

void refresh_rig_opts(void *xxx){
    struct config_rig *crig = (struct config_rig *)xxx;

    if (!crig){
        crig = g_new0(struct config_rig, 1);
        crig->nr = cfg->crigs->len;
        g_ptr_array_add(cfg->crigs, crig);
    }

	STORE_INT(crig, rig_enabled);
	STORE_STR(crig, rig_desc);
    STORE_STR(crig, rig_filename);
    STORE_SINT(crig, rig_model);
    STORE_SINT(crig, rig_speed);
    STORE_INT(crig, rig_handshake_none);
	STORE_SHEX(crig, rig_civaddr);
    STORE_SINT(crig, rig_ssbcw_shift);
    STORE_SDBL(crig, rig_lo);
    STORE_SINT(crig, rig_poll_ms);
    STORE_INT(crig, rig_qrg_r2t);
    STORE_INT(crig, rig_qrg_t2r);
    STORE_INT(crig, rig_mode_t2r);
    STORE_INT(crig, rig_clr_rit);
    STORE_INT(crig, rig_ptt_t2r);
    STORE_INT(crig, rig_verbose);
    STORE_STR(crig, rig_conf);

    free_trigs(gtrigs);
    init_trigs();        
	progress(NULL);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

void rig_opts_fn(struct dialog_data *dlg)
{
    if (new_model > 0){
        dbg("new_model_str=%d (%s)\n", new_model, new_model_name);
        if (strlen(dlg->items[1].cdata) == 0) g_strlcpy(dlg->items[1].cdata, new_model_name, EQSO_LEN);
		g_snprintf(dlg->items[3].cdata, EQSO_LEN, "%d", new_model);
        new_model = 0;
    }

}

void menu_rig_opts(void *arg)
{
    struct dialog *d;
    int i, rigi;
    struct config_rig *crig;

    rigi = GPOINTER_TO_INT(arg);
    dbg("menu_rig_opts(%d)\n", rigi);
    if (rigi >= (int)cfg->crigs->len) return;

    if (rigi < 0){
        crig = NULL;
		rig_enabled = 1;
		strcpy(rig_desc, ""/*VTEXT(T_NEW_RIG)*/);
        strcpy(rig_filename, "");       
        strcpy(rig_model_str, "1");         
        strcpy(rig_speed_str, "0");     
		rig_handshake_none = 0;
        strcpy(rig_civaddr_str, "0x58");   
        strcpy(rig_ssbcw_shift_str, "0");
        strcpy(rig_lo_str, "0");        
        strcpy(rig_poll_ms_str, "300");   
        rig_qrg_r2t = 1;
        rig_qrg_t2r = 1;        
        rig_mode_t2r = 1;       
        rig_clr_rit = 0;       
		rig_ptt_t2r = 0;
        rig_verbose = 0;        
        strcpy(rig_conf, "");
    }else{
        crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, rigi);
        LOAD_INT(crig, rig_enabled);
        LOAD_STR(crig, rig_desc);
        LOAD_STR(crig, rig_filename);
        LOAD_SINT(crig, rig_model);
        LOAD_SINT(crig, rig_speed);
        LOAD_INT(crig, rig_handshake_none);
		LOAD_SHEX2(crig, rig_civaddr);
        LOAD_SINT(crig, rig_ssbcw_shift);
        LOAD_SDBL(crig, rig_lo);
        if (crig->rig_poll_ms < 100) crig->rig_poll_ms = 300;
        if (crig->rig_poll_ms > 9999) crig->rig_poll_ms = 9999;
        LOAD_SINT(crig, rig_poll_ms);
        LOAD_INT(crig, rig_qrg_r2t);
        LOAD_INT(crig, rig_qrg_t2r);
        LOAD_INT(crig, rig_mode_t2r);
        LOAD_INT(crig, rig_clr_rit);
        LOAD_INT(crig, rig_ptt_t2r);
        LOAD_INT(crig, rig_verbose);
        LOAD_STR(crig, rig_conf);
    }


	new_model = 0;
    strcpy(new_model_name, "");
    

    if (!(d = (struct dialog*)g_malloc(sizeof(struct dialog) + 20 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 20 * sizeof(struct dialog_item));
    d->title = VTEXT(T_RIGOPTS); 
    d->fn = dlg_pf_fn;
    d->fn2 = rig_opts_fn;
    d->refresh = (void (*)(void *))refresh_rig_opts;
    d->refresh_data= crig;
    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 *)&rig_enabled;
    d->items[i].msg = CTEXT(T_ENABLED);//CTEXT(T_RIG_QRG_R2T);
    d->items[i].wrap = 1;

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rig_desc;
    d->items[i].maxl = 31;
    d->items[i].msg  = CTEXT(T_DESC);//CTEXT(T_RIG_DEVICE);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rig_filename;
    d->items[i].maxl = 35;
    d->items[i].msg  = CTEXT(T_RIG_DEVICE);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rig_model_str;
    d->items[i].maxl = 7;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].msg  = CTEXT(T_RIG_MODEL);
    d->items[i].gnum = 999999;

	rig_model = atoi(rig_model_str);
    d->items[++i].type = D_BUTTON;   /* 2 */
    d->items[i].gid = 0;
    d->items[i].fn = choose_manufacturer;
	d->items[i].data = (char *)GINT_TO_POINTER(rig_model);
    d->items[i].text = VTEXT(T_RIG_CHOOSE);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rig_conf;
    d->items[i].maxl = 35;
    d->items[i].msg = TRANSLATE("Config:");//CTEXT(T_RIG_DEVICE);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rig_speed_str;
    d->items[i].maxl = 7;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].msg  = CTEXT(T_RIG_SPEED);
    d->items[i].gnum = 999999;

	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 *)&rig_handshake_none;
    d->items[i].msg = TRANSLATE("Force handshake NONE");
    d->items[i].wrap = 1;
		
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rig_civaddr_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_hex;
    d->items[i].gid  = 0;
    d->items[i].msg  = CTEXT(T_RIG_CIV);
    d->items[i].gnum = 255;
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rig_ssbcw_shift_str;
    d->items[i].maxl = 5;
    d->items[i].fn   = check_number;
    d->items[i].gid  = -2000;
    d->items[i].gnum = +2000;
    d->items[i].msg  = CTEXT(T_RIG_FREQSHIFT);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rig_lo_str;
    d->items[i].maxl = 16;
    d->items[i].fn   = check_qrg;
    d->items[i].msg  = CTEXT(T_BAND_LO);
    d->items[i].wrap = 1;
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rig_poll_ms_str;
    d->items[i].maxl = 6;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 100;
    d->items[i].gnum = 9999;
    d->items[i].msg  = CTEXT(T_RIG_POLL_MS);
    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 *)&rig_qrg_r2t;
    d->items[i].msg = CTEXT(T_RIG_QRG_R2T);
    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 *)&rig_qrg_t2r;
    d->items[i].msg = CTEXT(T_RIG_QRG_T2R);
    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 *)&rig_mode_t2r;
    d->items[i].msg = CTEXT(T_RIG_MODE_T2R);
    d->items[i].wrap = 1;

    strcpy(rig_ptt_t2r_str, rig_ptt_types[rig_ptt_t2r]);
    d->items[++i].type = D_BUTTON;      
    d->items[i].gid = 0;
    d->items[i].fn = choose_ptt_type;
    d->items[i].data=(char *)&rig_ptt_t2r;
    d->items[i].msg = CTEXT(T_SET_PTT_ON_RADIO);
    d->items[i].text = rig_ptt_t2r_str;
    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 *)&rig_clr_rit;
    d->items[i].msg = CTEXT(T_RIG_CLR_RIT);
    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 *)&rig_verbose;
    d->items[i].msg = CTEXT(T_RIG_DEBUG);
    d->items[i].wrap = 2;

    
    d->items[++i].type = D_BUTTON;   /* 6 */
    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_rig_delete(void *arg){
    struct config_rig *crig;
	int rigi;

	rigi = GPOINTER_TO_INT(arg);
    dbg("menu_rig_delete(%d)\n", rigi);
    if (rigi >= (int)cfg->crigs->len) return;
    crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, rigi);
    free_config_rig(crig);
    g_ptr_array_remove_index(cfg->crigs, rigi);
	
    free_trigs(gtrigs);
    init_trigs();    

    progress(NULL);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}



void menu_rigs_delete(void *arg)
{
    struct menu_item *mi = NULL;
    static char *rotstrs[]={"0","1","2","3","4","5","6","7","8","9"};

    int i;
  
    
    if (!(mi = new_menu(3))) return;

    for (i=0; i<cfg->crigs->len; i++){
        struct config_rig *crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, i);
        
        add_to_menu(&mi, 
            //g_strdup(rot->rot_desc && *rot->rot_desc?rot->rot_desc:"Rotator"), 
			g_strdup_printf("Rig #%d", crig->nr),
            rotstrs[crig->nr],
            rotstrs[crig->nr],
            MENU_FUNC menu_rig_delete, GINT_TO_POINTER(i), 0);
    }
    do_menu(mi, NULL);
}



void menu_rigs(void *arg)
{
    struct menu_item *mi = NULL;
    static char *rotstrs[]={"0","1","2","3","4","5","6","7","8","9"};
    int i;
    
    
    if (!(mi = new_menu(3))) return;

    for (i=0; i<cfg->crigs->len; i++){
        struct config_rig *crig = (struct config_rig *)g_ptr_array_index(cfg->crigs, i);
		char *c;

		if (crig->rig_desc && *crig->rig_desc) c = g_strdup(crig->rig_desc);
		else c = g_strdup_printf(VTEXT(T_RIG_D), crig->nr);

		if (!crig->rig_enabled){
			char *d = c;
			c = g_strconcat(c, VTEXT(T_DISABLED), NULL);
			g_free(d);
		}
        
        add_to_menu(&mi, 
            //g_strdup(crig->rig_filename && *rot->rot_desc?rot->rot_desc:"Rotator"), 
			c,
            rotstrs[crig->nr],
            rotstrs[crig->nr],
            MENU_FUNC menu_rig_opts, GINT_TO_POINTER(i), 0);
    }
    add_to_menu(&mi, g_strdup(""), "", M_BAR, NULL, NULL, 0);
    
    add_to_menu(&mi, 
        g_strdup(VTEXT(T_ADD_RIG)),
        "A",
        "A",
        MENU_FUNC menu_rig_opts, GINT_TO_POINTER(-1), 0);
    
    add_to_menu(&mi, 
        g_strdup(VTEXT(T_REMOVE_RIG)/*VTEXT(T_ROT_REMOVE)*/),
        "R", //VTEXT(T_HK_ROT_REMOVE),
        "R", //VTEXT(T_HK_ROT_REMOVE),
        MENU_FUNC menu_rigs_delete, GINT_TO_POINTER(-1), 1);
    do_menu(mi, NULL);
}

#endif
    


/************************** rotar ******************************/

char rot_desc[MAX_STR_LEN];
int rot_type;
char rot_filename[MAX_STR_LEN], rot_hostname[MAX_STR_LEN]; 
char rot_port_str[EQSO_LEN];
char rot_vid_str[EQSO_LEN];
char rot_pid_str[EQSO_LEN];
char rot_serial[EQSO_LEN];
char rot_timeout_ms_str[EQSO_LEN];
char rot_poll_ms_str[EQSO_LEN];
char rot_beamwidth_str[EQSO_LEN];
char rot_offset_str[EQSO_LEN];
char rot_saddr_str[EQSO_LEN], rot_model_str[EQSO_LEN], rot_speed_str[EQSO_LEN];
char rot_rem_rotstr[EQSO_LEN];

void refresh_rotar_opts(void *xxx){
    struct config_rotar *crot = (struct config_rotar *)xxx;

    if (!crot) {
        crot = g_new0(struct config_rotar, 1);
        crot->nr = cfg->crotars->len;
        g_ptr_array_add(cfg->crotars, crot);
    }

    STORE_STR (crot, rot_desc);
    STORE_ENUM(crot, rot_type, enum rot_type);
    STORE_STR (crot, rot_filename); 
    STORE_STR (crot, rot_hostname); 
    STORE_SINT(crot, rot_port);
    STORE_SHEX(crot, rot_vid);
    STORE_SHEX(crot, rot_pid);
    STORE_STR (crot, rot_serial);
    STORE_SINT(crot, rot_timeout_ms);
    STORE_SINT(crot, rot_poll_ms);
	STORE_SINT(crot, rot_beamwidth);
	STORE_SINT(crot, rot_offset);
	STORE_SINT(crot, rot_model);
	STORE_SINT(crot, rot_speed);
    STORE_SINT(crot, rot_saddr);
    STORE_STR (crot, rot_rem_rotstr); 

//MUTEX_LOCK(rotars);
    free_rotars();
    init_rotars();
	progress(NULL);
//MUTEX_UNLOCK(rotars);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}
        

void menu_rotar_opts(void *arg){
    struct dialog *d;
    int i, roti;
    struct config_rotar *crot;

	roti = GPOINTER_TO_INT(arg);
    dbg("menu_rotar_opts(%d)\n", roti);
    if (roti >= (int)cfg->crotars->len) return;

    if (roti < 0){
        crot = NULL;
        
        safe_strncpy0(rot_desc, "", MAX_STR_LEN);
        
        rot_type = ROT_HAMLIB;
        strcpy(rot_filename, "");
        strcpy(rot_hostname, "");
        strcpy(rot_port_str, "10001");
        strcpy(rot_vid_str, "a600");
        strcpy(rot_pid_str, "e112");
        strcpy(rot_serial, "");
        strcpy(rot_timeout_ms_str,"400");
        strcpy(rot_poll_ms_str,"500");
		strcpy(rot_beamwidth_str, "20");
		strcpy(rot_offset_str, "0");
        strcpy(rot_saddr_str, "240");
		strcpy(rot_model_str, "0");
		strcpy(rot_speed_str, "0");
        strcpy(rot_rem_rotstr, "A");
    }else{
        crot = (struct config_rotar *)g_ptr_array_index(cfg->crotars, roti);
        
        LOAD_STR  (crot, rot_desc);
        LOAD_INT  (crot, rot_type);
        LOAD_STR  (crot, rot_filename); 
        LOAD_STR  (crot, rot_hostname); 
        LOAD_SINT (crot, rot_port);
        LOAD_SHEX4(crot, rot_vid);
        LOAD_SHEX4(crot, rot_pid);
        LOAD_STR  (crot, rot_serial); 
        LOAD_SINT (crot, rot_timeout_ms);
        if (crot->rot_poll_ms < 300) crot->rot_poll_ms = 500;
        if (crot->rot_poll_ms > 2000) crot->rot_poll_ms = 2000;
        LOAD_SINT (crot, rot_poll_ms);
        LOAD_SINT (crot, rot_beamwidth);
		LOAD_SINT (crot, rot_offset);
		LOAD_SINT (crot, rot_saddr);
		LOAD_SINT (crot, rot_model);
		LOAD_SINT (crot, rot_speed);
        LOAD_STR  (crot, rot_rem_rotstr); 
    }

    if (!(d = (struct dialog *)g_malloc(sizeof(struct dialog) + 30 * sizeof(struct dialog_item)))) return;
    memset(d, 0, sizeof(struct dialog) + 30 * sizeof(struct dialog_item));
    d->title = VTEXT(T_ROTAROPTS);
    d->fn = dlg_pf_fn;
    d->refresh = (void (*)(void *))refresh_rotar_opts;
    d->refresh_data = crot;
    d->y0 = 1;
    

    d->items[i=0].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rot_desc;
    d->items[i].maxl = 30;
    d->items[i].msg = CTEXT(T_DESC);
    d->items[i].wrap = 1;

    
    d->items[++i].type = D_CHECKBOX;      
    d->items[i].gid = 1;
    d->items[i].gnum = ROT_NONE;
    d->items[i].dlen = sizeof(int);
    d->items[i].data=(char *)&rot_type;
    d->items[i].msg = CTEXT(T_ROT_NONE);
    
    d->items[++i].type = D_CHECKBOX;      
    d->items[i].gid = 1;
    d->items[i].gnum = ROT_OK1ZIA_TTYS;
    d->items[i].dlen = sizeof(int);
    d->items[i].data=(char *)&rot_type;
    d->items[i].msg = CTEXT(T_ROT_OK1ZIA_TTYS);
    
    d->items[++i].type = D_CHECKBOX;      
    d->items[i].gid = 1;
    d->items[i].gnum = ROT_OK1ZIA_FTDI;
    d->items[i].dlen = sizeof(int);
    d->items[i].data=(char *)&rot_type;
    d->items[i].msg = CTEXT(T_ROT_OK1ZIA_FTDI);
    
    d->items[++i].type = D_CHECKBOX;      
    d->items[i].gid = 1;
    d->items[i].gnum = ROT_HAMLIB;
    d->items[i].dlen = sizeof(int);
    d->items[i].data=(char *)&rot_type;
    d->items[i].msg = CTEXT(T_ROT_HAMLIB);
    
    d->items[++i].type = D_CHECKBOX;      
    d->items[i].gid = 1;
    d->items[i].gnum = ROT_REMOTE;
    d->items[i].dlen = sizeof(int);
    d->items[i].data=(char *)&rot_type;
    d->items[i].msg = CTEXT(T_ROT_REMOTE);
    d->items[i].wrap = 1;

    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rot_filename;
    d->items[i].maxl = 15;
    d->items[i].msg = CTEXT(T_FILENAME);
    d->items[i].wrap = 1;

    
    d->items[++i].type = D_FIELD;   // 5
    d->items[i].dlen = MAX_STR_LEN;
    d->items[i].data = rot_hostname;
    d->items[i].maxl = 15;
    d->items[i].msg = CTEXT(T_HOSTNAME);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_port_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 1;
    d->items[i].gnum = 65535;
    d->items[i].maxl = 6;
    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 = rot_vid_str;
    d->items[i].maxl = 6;
    d->items[i].msg = CTEXT(T_ROT_VID);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_pid_str;
    d->items[i].maxl = 6;
    d->items[i].msg = CTEXT(T_ROT_VID);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_serial;
    d->items[i].maxl = 10;
    d->items[i].msg = CTEXT(T_ROT_SERIAL);
    d->items[i].wrap = 1;
    
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_timeout_ms_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 50;
    d->items[i].gnum = 2000;
    d->items[i].maxl = 5;
    d->items[i].msg = CTEXT(T_TIMEOUT);

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_poll_ms_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 300;
    d->items[i].gnum = 2000;
    d->items[i].maxl = 5;
	d->items[i].msg = CTEXT(T_ROT_POLL_MS);
    d->items[i].wrap = 1;

    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_beamwidth_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 360;
    d->items[i].maxl = 5;
    d->items[i].msg = CTEXT(T_BEAMWIDTH);

	d->items[++i].type = D_FIELD;
	d->items[i].dlen = EQSO_LEN;
	d->items[i].data = rot_offset_str;
	d->items[i].fn = check_number;
	d->items[i].gid = 0;
	d->items[i].gnum = 359;
	d->items[i].maxl = 5;
	d->items[i].msg = TRANSLATE("Azimuth offset: "); //CTEXT(T_OFFSET);
	d->items[i].wrap = 1;


    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_saddr_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 128;
    d->items[i].gnum = 255;
    d->items[i].maxl = 5;
    d->items[i].msg = CTEXT(T_SADDR);
    
    d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_model_str;
    d->items[i].fn   = check_number;
    d->items[i].gid  = 0;
    d->items[i].gnum = 9999;
    d->items[i].maxl = 5;
    d->items[i].msg = CTEXT(T_MODEL);
    d->items[i].wrap = 1;
    
	d->items[++i].type = D_FIELD;
	d->items[i].dlen = EQSO_LEN;
	d->items[i].data = rot_speed_str;
	d->items[i].fn = check_number;
	d->items[i].gid = 0;
	d->items[i].gnum = 9999999;
	d->items[i].maxl = 8;
	d->items[i].msg = TRANSLATE("Hamlib speed:");
	d->items[i].wrap = 1;

	d->items[++i].type = D_FIELD;
    d->items[i].dlen = EQSO_LEN;
    d->items[i].data = rot_rem_rotstr;
    d->items[i].maxl = 3;
    d->items[i].msg = CTEXT(T_ROT_REM_ROTSTR);
    d->items[i].wrap = 2;
    
    
    
    d->items[++i].type = D_BUTTON;      // 10
    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_rotar_delete(void *arg){
    struct config_rotar *crot;
	int roti;

	roti = GPOINTER_TO_INT(arg);
    dbg("menu_rotar_delete(%d)\n", roti);
    if (roti >= (int)cfg->crotars->len) return;
    crot = (struct config_rotar *)g_ptr_array_index(cfg->crotars, roti);
    free_config_rotar(crot);
    g_ptr_array_remove_index(cfg->crotars, roti);

    free_rotars();
    init_rotars();
    progress(NULL);

#ifdef AUTOSAVE
    menu_save_rc(NULL);
#endif
}

void menu_rotars_delete(void *arg)
{
    struct menu_item *mi = NULL;
    static char *rotstrs[]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    int i;
    
    
    if (!(mi = new_menu(3))) return;

    for (i=0; i<cfg->crotars->len; i++){
        struct config_rotar *rot = (struct config_rotar *)g_ptr_array_index(cfg->crotars, i);
        
        add_to_menu(&mi, 
            g_strdup(rot->rot_desc && *rot->rot_desc?rot->rot_desc:"Rotator"), 
            rotstrs[rot->nr],
            rotstrs[rot->nr],
            MENU_FUNC menu_rotar_delete, GINT_TO_POINTER(i), 0);
    }
    do_menu(mi, NULL);
}

void menu_rotars(void *arg)
{
    struct menu_item *mi = NULL;
    static char *rotstrs[]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    int i;
    
    
    if (!(mi = new_menu(3))) return;

#ifdef OCT8TOR
	add_to_menu(&mi,
		g_strdup(TRANSLATE("Oct8tor")),
		TRANSLATE("O"),
		TRANSLATE("O"),
		MENU_FUNC menu_oct8tor_opts, GINT_TO_POINTER(-1), 0);
#endif

	for (i = 0; i<cfg->crotars->len; i++){
        struct config_rotar *rot = (struct config_rotar *)g_ptr_array_index(cfg->crotars, i);
        char *c;

        if (rot->rot_desc && *rot->rot_desc)
            c = g_strdup(rot->rot_desc);
        else 
            c = g_strdup_printf(VTEXT(T_ROTATOR_D), i);

        if (rot->rot_type == ROT_NONE){
			char *d = c;
			c = g_strconcat(c, VTEXT(T_DISABLED), NULL);
			g_free(d);
        }
        
        
        add_to_menu(&mi, 
            c, 
            rotstrs[rot->nr],
            rotstrs[rot->nr],
            MENU_FUNC menu_rotar_opts, GINT_TO_POINTER(i), 0);
    }

	if (cfg->crotars->len > 0){
		add_to_menu(&mi, g_strdup(""), "", M_BAR, NULL, NULL, 0);
	}
    
    add_to_menu(&mi, 
        g_strdup(VTEXT(T_ROT_ADD)),
        VTEXT(T_HK_ROT_ADD),
        VTEXT(T_HK_ROT_ADD),
        MENU_FUNC menu_rotar_opts, GINT_TO_POINTER(-1), 0);
    
    add_to_menu(&mi, 
        g_strdup(VTEXT(T_ROT_REMOVE)),
        VTEXT(T_HK_ROT_REMOVE),
        VTEXT(T_HK_ROT_REMOVE),
        MENU_FUNC menu_rotars_delete, GINT_TO_POINTER(-1), 1);

	do_menu(mi, NULL);
}

