/* GAdmin-OpenVPN - An easy to use GTK+ frontend for the openvpn client.
 * Copyright (C) 2008 - 2012 Magnus Loef <magnus-swe@telia.com> 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
*/


#include "../config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "gettext.h"
#include "widgets.h"
#include "make_settings_entries.h"
#include "make_settings_combos.h"
#include "make_settings_buttons.h"
#include "make_settings_spinbuttons.h"
#include "make_settings_progressbars.h"
#include "make_settings_labels.h"
#include "make_settings_hseparators.h"
#include "create_client_settings.h"
#include "allocate.h"
#include "commands.h"
#include "show_info.h"
#include "file_chooser.h"


/* Scroll to the last row in a treeview */
void scroll_to_last_row(GtkTreeView *treeview, GtkTreeIter iter)
{
    GtkTreeModel *model;
    GtkTreePath *path;
    GtkTreeSelection *selection;

    model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
    path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    gtk_tree_selection_select_path(GTK_TREE_SELECTION(selection), path);
    gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), path, 0, TRUE);
    gtk_tree_path_free(path);
}

/* Adds a new server row */
void add_server_row(struct w *widgets)
{
    GtkTreeIter iter;
    gchar *info;

    gtk_list_store_append(GTK_LIST_STORE(widgets->address_store), &iter);
    scroll_to_last_row(GTK_TREE_VIEW(widgets->address_treeview), iter);

    info = g_strdup_printf("%s",
       _("A new row has been added.\nClick the cells in this row and add a new server.\n"));
    show_info(info);
    g_free(info);
}

/* Deletes the selected server treeview row */
void delete_server_row(GtkTreeView *treeview)
{
    GtkTreeIter iter;
    GtkTreeModel *model;
    GtkTreeStore *model_store;
    GtkTreeSelection *select;
    gboolean val;

    model_store = (GtkTreeStore *) gtk_tree_view_get_model(treeview);
    select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));

    if( gtk_tree_selection_get_selected(select, &model, &iter) )
    {
    	val = gtk_list_store_remove(GTK_LIST_STORE(model_store), &iter);
    }
    // Fix: Else popup, select a row first
    if( val ) // Fixes: variable not used.
    {
    }
}


/* Text cell edited */
void text_cell_edited(GtkCellRendererText *cell, gchar *path_string,
	            gchar *new_text, GtkListStore *store)
{
    /* Changes the edited cells text */
    GtkTreeIter iter;
    GtkTreePath *path = NULL;
    int column = (gint) (glong) g_object_get_data(G_OBJECT(cell), "column");

    path = gtk_tree_path_new_from_string(path_string);
    gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path);

    if( path!=NULL )
        gtk_tree_path_free(path);

    gtk_list_store_set(GTK_LIST_STORE(store), &iter, column, new_text, -1);
}





/* Adds an example mount command to the entry */
void add_mount_command(struct w *widgets)
{
    gchar *info, *utf8;
    info = g_strdup_printf("mkdir -p /media/usb-device ; mount /dev/sdb1 /media/usb-device");
    utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
    gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[4]), utf8);
    if( utf8!=NULL )
        g_free(utf8);
    g_free(info);
}

char * get_import_filename(gchar *path)
{
    long i = 0;
    char *filename = allocate(strlen(path)+3);

    if( path!=NULL )
    {
        for(i=strlen(path)-1; i>0; i--)
        if( path[i]=='/' )
        {
            snprintf(filename, strlen(path), "%s", &path[i+1]);
            break;
        }
    }
    return filename;
}

void copy_import_file(struct w *widgets, gchar *path)
{
    gchar *connection_name, *cmd, *info;
    int i = 0;

    connection_name = g_strdup_printf("%s", gtk_entry_get_text(GTK_ENTRY(widgets->client_set_entry[0])));
    for(i=0; connection_name[i]!='\0'; i++)
      if( connection_name[i]==' ' )
        connection_name[i]='-';

    cmd = g_strdup_printf("mkdir -p %s/client/%s/certs", OPENVPN_SYSCONF_DIR, connection_name);
    if( ! run_command(cmd) )
    {
        info = g_strdup_printf(_("Could not create the clients certificate directory.\n"));
        show_info(info);
        g_free(info);
        return;
    }
    g_free(cmd);

    cmd = g_strdup_printf("cp '%s' %s/client/%s/certs", path, OPENVPN_SYSCONF_DIR, connection_name);
    if( ! run_command(cmd) )
    {
        info = g_strdup_printf(_("Error: Copying certificate or key file failed.\n"));
        show_info(info);
        g_free(info);
        return;
    }
    g_free(cmd);
}

int valid_connection_name(struct w *widgets)
{
    G_CONST_RETURN gchar *connection_name;
    gchar *info;

    connection_name = gtk_entry_get_text(GTK_ENTRY(widgets->client_set_entry[0]));
    if( connection_name == NULL || strlen(connection_name) < 3 )
    {
        info = g_strdup_printf(_("You must specify a valid connection name first.\n"));
        show_info(info);
        g_free(info);
        return 0;
    }
    return 1;
}

void import_cacert(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
        return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
        filename = get_import_filename(path);
        gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[6]), filename);
        if( filename!=NULL )
          free(filename);

        /* Copy the file to the correct location */
        copy_import_file(widgets, path);

        g_free(path);
    }
}

void import_cert(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
        return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
        filename = get_import_filename(path);
        gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[7]), filename);
        if( filename!=NULL )
          free(filename);

        /* Copy the file to the correct location */
        copy_import_file(widgets, path);

        g_free(path);
    }
}

void import_key(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
        return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
        filename = get_import_filename(path);
        gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[8]), filename);
        if( filename!=NULL )
          free(filename);

        /* Copy the file to the correct location */
        copy_import_file(widgets, path);

        g_free(path);
    }
}

/* Optional for the client. Use if used on the server. */
void import_takey(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
        filename = get_import_filename(path);
        gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[9]), filename);
        if( filename!=NULL )
          free(filename);

        /* Copy the file to the correct location */
        copy_import_file(widgets, path);

        g_free(path);
    }
}

void create_client_settings(struct w *widgets)
{
    GtkWidget *address_scrolled_window;
    GtkWidget *address_vbox;
    GtkCellRenderer *comment_cell, *addr_cell, *port_cell; //, *proto_cell;
    GtkTreeViewColumn *col[2];
    int colnr = 0;
    GtkTooltips *tooltips;
    gchar *utf8 = NULL;
    gchar *combo_text;

    /* Counters for the widgets and positions in the table */
    int a = 0;
    int b = 1;
    int ent  = 0;
    int spin = 0;
    int comb = 0;

    /* Max lengths and input */
    int entry_size = 100;

    tooltips = gtk_tooltips_new();

    /* Connection name */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
                _(" Connection name: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], 
                _("A name for this VPN connection"), NULL);
    a++; b++; ent++;

    /* Create the address treeview in a scrolled window */
    address_vbox = gtk_vbox_new(FALSE, 0);

    address_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_box_pack_start(GTK_BOX(address_vbox), address_scrolled_window, FALSE, FALSE, 0);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(address_scrolled_window), 
			                GTK_POLICY_AUTOMATIC, 
			                GTK_POLICY_ALWAYS);
    gtk_widget_set_size_request(address_scrolled_window, -1, 100);

    /* 3 columns */
    widgets->address_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING,
			               G_TYPE_STRING);

    widgets->address_treeview = gtk_tree_view_new();
    gtk_tree_view_set_model(GTK_TREE_VIEW(widgets->address_treeview),
                                GTK_TREE_MODEL(widgets->address_store));

    gtk_container_add(GTK_CONTAINER(address_scrolled_window), widgets->address_treeview);
    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(widgets->address_treeview), TRUE);

    /* A hbuttonbox below the treeview */
    GtkWidget *hbuttonbox1;
    hbuttonbox1 = gtk_hbutton_box_new();
    gtk_box_pack_start(GTK_BOX(address_vbox), hbuttonbox1, FALSE, FALSE, 0);
    gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_SPREAD);

    /* Add remote address button */
    GtkWidget *add_address_button = gtk_button_new();
    gtk_tooltips_set_tip(tooltips, add_address_button, _("Add more servers."), NULL);
    GtkWidget *alignment62 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_container_add(GTK_CONTAINER(add_address_button), alignment62);
    GtkWidget *hbox60 = gtk_hbox_new(FALSE, 2);
    gtk_container_add(GTK_CONTAINER(alignment62), hbox60);
    GtkWidget *image52 = gtk_image_new_from_stock("gtk-add", GTK_ICON_SIZE_BUTTON);
    gtk_box_pack_start(GTK_BOX(hbox60), image52, FALSE, FALSE, 0);
    GtkWidget *label230 = gtk_label_new_with_mnemonic(_("Add server"));
    gtk_box_pack_start(GTK_BOX(hbox60), label230, FALSE, FALSE, 0);
    gtk_label_set_justify(GTK_LABEL(label230), GTK_JUSTIFY_LEFT);

    gtk_box_pack_start(GTK_BOX(hbuttonbox1), add_address_button, TRUE, TRUE, 0);
    /* The add address signal hookup */
    g_signal_connect_swapped(add_address_button, "clicked",
                    	     G_CALLBACK(add_server_row), widgets);

    /* Remove address button */
    GtkWidget *del_address_row_button = gtk_button_new();
    gtk_tooltips_set_tip(tooltips, del_address_row_button, _("Remove selected server."), NULL);
    GtkWidget *alignment64 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_container_add(GTK_CONTAINER(del_address_row_button), alignment64);
    GtkWidget *hbox64 = gtk_hbox_new(FALSE, 2);
    gtk_container_add(GTK_CONTAINER(alignment64), hbox64);
    GtkWidget *image56 = gtk_image_new_from_stock("gtk-delete", GTK_ICON_SIZE_BUTTON);
    gtk_box_pack_start(GTK_BOX(hbox64), image56, FALSE, FALSE, 0);
    GtkWidget *label234 = gtk_label_new_with_mnemonic(_("Remove selected server"));
    gtk_box_pack_start(GTK_BOX(hbox64), label234, FALSE, FALSE, 0);
    gtk_label_set_justify(GTK_LABEL(label234), GTK_JUSTIFY_LEFT);

    gtk_box_pack_start(GTK_BOX(hbuttonbox1), del_address_row_button, TRUE, TRUE, 0);
    /* Remove address signal hookup */
    g_signal_connect_swapped(del_address_row_button, "clicked",
                    	     G_CALLBACK(delete_server_row), widgets->address_treeview);


    GtkWidget *servers_label = gtk_label_new_with_mnemonic (_("Servers:"));
    gtk_table_attach((GtkTable *)widgets->settings_table, servers_label, 0, 1, a, b,
                                                            GTK_FILL, GTK_EXPAND, 5, 5);
    gtk_misc_set_alignment(GTK_MISC(servers_label), 0, 0.5);
    gtk_misc_set_padding(GTK_MISC(servers_label), 2, 2);

    gtk_table_attach((GtkTable *)widgets->settings_table, address_vbox, 1, 3, a, b,
                                    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 20, 5);
    

    /* Setup the cell renderers for editing */
    comment_cell = gtk_cell_renderer_text_new();
    g_object_set(comment_cell, "editable", TRUE, NULL);
    g_signal_connect(comment_cell, "edited",  
             G_CALLBACK(text_cell_edited), widgets->address_store);

    addr_cell = gtk_cell_renderer_text_new();
    g_object_set(addr_cell, "editable", TRUE, NULL);
    g_signal_connect(addr_cell, "edited",  
             G_CALLBACK(text_cell_edited), widgets->address_store);

    port_cell = gtk_cell_renderer_text_new();
    g_object_set(port_cell, "editable", TRUE, NULL);
    g_signal_connect(port_cell, "edited",  
             G_CALLBACK(text_cell_edited), widgets->address_store);

//    proto_cell = gtk_cell_renderer_text_new();
//    g_object_set(proto_cell, "editable", TRUE, NULL);
//    g_signal_connect(proto_cell, "edited",  
//		     G_CALLBACK(cell_edited), widgets);

    /* Set column numbers for the cells */
    g_object_set_data(G_OBJECT(comment_cell), "column", (void*)(0));
    g_object_set_data(G_OBJECT(addr_cell), "column", (void*)(1));
    g_object_set_data(G_OBJECT(port_cell), "column", (void*)(2));

    /* Set edited signals for the cells */
    g_signal_connect(comment_cell, "edited",  
        G_CALLBACK(text_cell_edited), widgets->address_store);
    g_signal_connect(addr_cell, "edited",  
        G_CALLBACK(text_cell_edited), widgets->address_store);
    g_signal_connect(port_cell, "edited",  
        G_CALLBACK(text_cell_edited), widgets->address_store);


    /* Add columns: | Comment | Name | Address | Port (| Proto |) */
    col[colnr] = gtk_tree_view_column_new_with_attributes(_("Comment"), comment_cell, "text", colnr, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(widgets->address_treeview), GTK_TREE_VIEW_COLUMN(col[colnr]));
    colnr++;
    col[colnr] = gtk_tree_view_column_new_with_attributes(_("Address"), addr_cell, "text", colnr, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(widgets->address_treeview), GTK_TREE_VIEW_COLUMN(col[colnr]));
    colnr++;
    col[colnr] = gtk_tree_view_column_new_with_attributes(_("Port"), port_cell, "text", colnr, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(widgets->address_treeview), GTK_TREE_VIEW_COLUMN(col[colnr]));
    colnr++;
//    col[colnr] = gtk_tree_view_column_new_with_attributes(_("Protocol"), proto_cell, "text", colnr, NULL);
//    gtk_tree_view_append_column(GTK_TREE_VIEW(widgets->address_treeview), GTK_TREE_VIEW_COLUMN(col[colnr]));
//    colnr++;

    a++, b++;


    /* Server Protocol UDP/TCP (Can be set in the remote option on a site by site basis) */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Server protocol: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("TCP"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("UDP"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;


    /* The TUN/TAP interface to create and use */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Device: "), 0,1,a,b,50);
    combo_text = g_strdup_printf("Tap0");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap1");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap2");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap3");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);

    combo_text = g_strdup_printf("Tun0");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tun1");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tun2");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tun3");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);

    a++; b++; comb++;

    /* Username */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" Username: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent],
            _("A username for the server if required"), NULL);
    a++; b++; ent++;

    /* Password */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" Password: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent],
            _("A password for the server if required"), NULL);
    a++; b++; ent++;

    /* Passfile location */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" Passfile: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent],
    _("Location of the passfile.\nIE: /etc/gadmin-openvpn/client/connection-name/passfile\nor /media/usb-device/passfile3"), NULL);
    a++; b++; ent++;

    /* Mount button and entry */
    GtkWidget *mount_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    mount_button = make_button_with_entry(GTK_TABLE(widgets->settings_table),
                                              widgets->client_set_entry[ent],
                    	                                       "gtk-refresh",
            	        		                                    "Mount:",
                                           _("Add an example mount command"),
            		        		                               0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(mount_button), "clicked",
    	                   G_CALLBACK(add_mount_command), widgets);

    /* Encryption type: BlowFish, AES or Triple-DES */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Encryption type: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("BlowFish"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("AES-128"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("AES-256"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Triple-DES"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Use compression */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Use compression: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Share connection */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Share connection: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Using Firestarter */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Using Firestarter: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Start at boot */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->settings_table),
            _(" Start at boot: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;


    /* LAN interface name */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" LAN interface name: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("The name of the LAN network interface, IE: eth1"), NULL);
    a++; b++; ent++;
*/
    /* LAN interface address */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" LAN interface address: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 192.168.10.100\nYour LAN should not have the same network address as connecting clients commonly have, IE: 192.168.0 or 10.0.0. Also change this setting in your DHCP server and firewall."), NULL);
    a++; b++; ent++;
*/
    /* LAN Subnet mask */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" LAN subnet mask: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 255.255.255.0"), NULL);
    a++; b++; ent++;
*/
    /* LAN Broadcast address */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" LAN broadcast address: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 192.168.10.255"), NULL);
    a++; b++; ent++;
*/



    /* Log level (verb 3) */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->settings_table),
            _(" Log level: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin],
            _("Log verbosity level."), NULL);
    a++; b++; spin++;

    /* HTTP Proxy server address */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->settings_table),
            _(" Proxy server: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], 
            _("Local HTTP Proxy server address if any"), NULL);
    a++; b++; ent++;

    /* HTTP proxy server port */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->settings_table),
            _(" Proxy port: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin],
            _("Local HTTP proxy server port if any"), NULL);
    a++; b++; spin++;

    /* MSS fix */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->settings_table),
            _(" MSS value: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin],
    _("The MSSfix option adjusts MSS in the packet header. Default is 1200. Range is: 1000-1450"), NULL);
    a++; b++; spin++;


    /* CA Cert button and entry */
    GtkWidget *cacert_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    cacert_button = make_button_with_entry(GTK_TABLE(widgets->settings_table),
                                               widgets->client_set_entry[ent],
                                                                "gtk-refresh",
                                                                   "CA cert:",
                                                 _("Import a CA certificate"),
            	                                                    0,1,a,b,-1);
    gtk_widget_set_sensitive(GTK_WIDGET(widgets->client_set_entry[ent]), FALSE);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(cacert_button), "clicked",
	            G_CALLBACK(import_cacert), widgets);

    /* Cert */
    GtkWidget *cert_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    cert_button = make_button_with_entry(GTK_TABLE(widgets->settings_table),
                                             widgets->client_set_entry[ent],
                                                              "gtk-refresh",
                                                                    "Cert:",
                                           _("Import a client certificate"),
                                                                  0,1,a,b,-1);
    gtk_widget_set_sensitive(GTK_WIDGET(widgets->client_set_entry[ent]), FALSE);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(cert_button), "clicked",
	            G_CALLBACK(import_cert), widgets);

    /* Key */
    GtkWidget *key_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    key_button = make_button_with_entry(GTK_TABLE(widgets->settings_table),
                                            widgets->client_set_entry[ent],
                                                             "gtk-refresh",
            	                                                    "Key:",
                                                  _("Import a client key"),
            		                                             0,1,a,b,-1);
    gtk_widget_set_sensitive(GTK_WIDGET(widgets->client_set_entry[ent]), FALSE);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(key_button), "clicked",
	            G_CALLBACK(import_key), widgets);

    /* TA key */
    GtkWidget *takey_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    takey_button = make_button_with_entry(GTK_TABLE(widgets->settings_table),
                                              widgets->client_set_entry[ent],
                                                               "gtk-refresh",
                                                                   "TA key:",
      _("Import a TLS-Auth key. Required if TLS-Auth is used by the server"),
                                                                   0,1,a,b,-1);
    gtk_widget_set_sensitive(GTK_WIDGET(widgets->client_set_entry[ent]), FALSE);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(takey_button), "clicked",
	            G_CALLBACK(import_takey), widgets);


    gtk_widget_show_all(widgets->main_window);
}
