#include <gtk/gtk.h>
#include <silcincludes.h>
#include <silcclient.h>
#include <glade/glade.h>

#include "log.h"
#include "support.h" /* for silkyStruct, FIXME */
#include "servers.h"
#include "ui_preferences.h"
#include "preferences.h"
#include "xmlconfig.h" /* xml_save_config() */
#include "xmllayout.h"

#include "common.h"

extern GladeXML *xmlmain;
extern silkyStruct *silky; /* from main.c */
extern gchar *privkey; /* from main.c */
extern SilkyServer *servers;
extern gchar *prefpath;

/*
  clears the passphrase dialog entries
*/
void prefs_clear_passphrase_dialog() {
  GtkEntry *entry_passphrase_old, *entry_passphrase_new, *entry_passphrase_new2;

  debug("clearing the preferences passphrase dialog");

  entry_passphrase_old = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_old"));
  entry_passphrase_new = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_new"));
  entry_passphrase_new2 = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_new2"));

  gtk_entry_set_text(entry_passphrase_old, "");
  gtk_entry_set_text(entry_passphrase_new, "");
  gtk_entry_set_text(entry_passphrase_new2, "");

  debug("*");
}


/*
  reads passphrase from the dialog,
  compares them,
  changes the passphrase
*/
void cb_prefs_change_passphrase(GtkWidget *dialog, gpointer pointer) {
  GtkEntry *entry_passphrase_old, *entry_passphrase_new, *entry_passphrase_new2;
  const gchar *passphrase_old, *passphrase_new, *passphrase_new2;
  GtkWidget *error_dialog;

  entry_passphrase_old = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_old"));
  entry_passphrase_new = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_new"));
  entry_passphrase_new2 = GTK_ENTRY(glade_xml_get_widget(xmlmain, "pref_passphrase_new2"));


  passphrase_old = gtk_entry_get_text(entry_passphrase_old);
  passphrase_new = gtk_entry_get_text(entry_passphrase_new);
  passphrase_new2 = gtk_entry_get_text(entry_passphrase_new2);


  if ( strcmp(passphrase_new, passphrase_new2)) {

    debug_error("new passphrases are not equal");

    error_dialog = gtk_message_dialog_new          ( GTK_WINDOW(dialog), 
						     GTK_DIALOG_MODAL & GTK_DIALOG_DESTROY_WITH_PARENT,
						     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("New passphrase confirmation failed") );

    gtk_dialog_run(GTK_DIALOG(error_dialog));
    gtk_widget_destroy(error_dialog);

    prefs_clear_passphrase_dialog();
    return;

  } else if (!silc_change_private_key_passphrase(privkey, passphrase_old, passphrase_new)) {

    debug_error("incorrect passphrase");

    error_dialog = gtk_message_dialog_new          ( GTK_WINDOW(dialog), 
						     GTK_DIALOG_MODAL & GTK_DIALOG_DESTROY_WITH_PARENT,
						     GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Incorrect passphrase") );

    gtk_dialog_run(GTK_DIALOG(error_dialog));
    gtk_widget_destroy(error_dialog);

    prefs_clear_passphrase_dialog();
    return;

  }

  /* on success, clear passphrases from GUI and hide the dialog */
  error_dialog = gtk_message_dialog_new          ( GTK_WINDOW(dialog), 
						   GTK_DIALOG_MODAL & GTK_DIALOG_DESTROY_WITH_PARENT,
						   GTK_MESSAGE_INFO, GTK_BUTTONS_OK, _("Passphrase changed") );

  gtk_dialog_run(GTK_DIALOG(error_dialog));
  gtk_widget_destroy(error_dialog);

  prefs_clear_passphrase_dialog();
  gtk_widget_hide(dialog);
  debug("passphrase changed ok");
}

/*
  Adds all entries to the server list on preferences-servers page
*/
void populate_prefs_serverlist() {
  SilkyServer *s;
  GtkTreeView *treeview;
  GtkListStore *liststore;
  GtkTreeIter iter;

  debug("populating server list for preferences");

  /* get and clear current treeview */
  treeview = GTK_TREE_VIEW(glade_xml_get_widget(xmlmain, "preferences_servers_treeview"));

  /* initialize treeview if it doesn't yet exist */
  if( !gtk_tree_view_get_column(treeview, srv_col_hostname) ) {
    gui_prefs_set_up_server_treeview();
  }

  liststore = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
  gtk_list_store_clear(liststore);

  /* populate the dialog's combo list with servers */
  for( s = servers; s; s = s->next ) {
    if(s->hostname && g_utf8_strlen(s->hostname, -1) && s->port ) {
      debug("server: '%s:%d'", s->hostname, s->port);

      gtk_list_store_append(liststore, &iter);

      gtk_list_store_set(liststore, &iter, srv_col_hostname, s->hostname, -1); /* name */
      gtk_list_store_set(liststore, &iter, srv_col_port, s->port, -1); /* port */
      /* 
	 gtk_list_store_set(liststore, &iter, srv_col_autoconnect, s->default, -1);
      */
      
    }
    else {
      debug("missing hostname or port, this is weird");
    }

  }

  debug("ready");

}


/*
  initializes server treeview in preferences dialog
  call populate_prefs_serverlist() later to add entries
*/
void gui_prefs_set_up_server_treeview() {
  GtkWidget *treeview;
  GtkCellRenderer *renderer_text;
  GtkCellRenderer *renderer_toggle;
  GtkListStore *liststore;
  GtkTreeViewColumn *column;

  debug("setting columns for server list in the preferences dialog");
  /*
    Set columns for the server list of the preferences dialog
  ALSO edit the enums for srv_col_... in gui.h
  */
  liststore = gtk_list_store_new (
                          3,
                          G_TYPE_BOOLEAN,  /* autoconnect */
                          G_TYPE_STRING,  /* hostname */
                          G_TYPE_INT  /* port */
                          );

  treeview = glade_xml_get_widget(xmlmain, "preferences_servers_treeview");

  /* set the model for treeview, overwrites the old one if present */
  gtk_tree_view_set_model (GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(liststore) );

  renderer_text = gtk_cell_renderer_text_new();
  renderer_toggle = gtk_cell_renderer_toggle_new();
  gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(renderer_toggle), TRUE); /* TRUE=radio, FALSE=checkbox */

  /* THIS SPECIFIES COLUMN ORDER ALSO: */
  /* hostname */
  column = gtk_tree_view_column_new_with_attributes (_("Hostname"), renderer_text, "text", srv_col_hostname, NULL);
  gtk_tree_view_column_set_expand(column, TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
  gtk_tree_view_set_search_column (GTK_TREE_VIEW(treeview), srv_col_hostname); /* set sortable column */
  gtk_tree_view_column_set_sort_column_id(column,  srv_col_hostname);

  /* port */
  column = gtk_tree_view_column_new_with_attributes (_("Port"), renderer_text, "text", srv_col_port, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
  gtk_tree_view_set_search_column (GTK_TREE_VIEW(treeview), srv_col_port); /* set sortable column */
  gtk_tree_view_column_set_sort_column_id(column,  srv_col_port);

  /* autoconnect */
  column = gtk_tree_view_column_new_with_attributes (_("Connect on start"), renderer_toggle, "active", srv_col_autoconnect, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
  gtk_tree_view_set_search_column (GTK_TREE_VIEW(treeview), srv_col_autoconnect);
  gtk_tree_view_column_set_sort_column_id(column,  srv_col_autoconnect);

  
}


/*
  add the user provided server to the server list
*/
void on_settings_server_add(GtkWidget *widget, gpointer user_data) {
  GtkWidget *ent_address;
  GtkWidget *ent_port;
  gchar *address;
  gint port;

  ent_address = glade_xml_get_widget (xmlmain, "prefs_servers_new_address");
  ent_port = glade_xml_get_widget (xmlmain, "prefs_servers_new_port");

  address = strdup(gtk_entry_get_text (GTK_ENTRY(ent_address)));
  port = atoi(strdup(gtk_entry_get_text (GTK_ENTRY(ent_port))));

  debug("adding new server '%s:%d'", address, port);
  if (server_add(address, port)) {
    debug("add ok");
  
    /* refresh the gui list */
    populate_prefs_serverlist();

    /* clear inputboxes */
    gtk_entry_set_text (GTK_ENTRY(ent_address), "");
    gtk_entry_set_text (GTK_ENTRY(ent_port), "");

  } else {
    debug("add failed");
  }

  g_free(address);
  
}

/*
  remove the selected server from the server list
*/

void on_settings_server_remove(GtkWidget *widget, gpointer user_data) {
  GtkTreeView *treeview;
  GtkTreeSelection *selection;
  GtkTreeModel *model;
  GtkTreeIter iter;
  SilkyServer *server;

  gchar *host;
  gint port;

  treeview = GTK_TREE_VIEW(glade_xml_get_widget (xmlmain, "preferences_servers_treeview"));

  selection = gtk_tree_view_get_selection(treeview);

  /* if something was selected */
  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    gtk_tree_model_get (model, &iter, srv_col_hostname, &host, -1);
    gtk_tree_model_get (model, &iter, srv_col_port, &port, -1); 
    debug("selected server '%s:%d' for removal", host, port);
    server = server_find_by_hostport(host, port);

    if( server_remove(server) ) {
      debug("remove ok");

      /* refresh the gui list */
      populate_prefs_serverlist();
     
    } else {
      debug("remove failed");
    }

  } else {
    debug("nothing selected for removal");
  }

}

/*
  This is called from the tips dialog.

  Reads toggle state from tips dialog,
  sets the value to preferences dialog,
  saves the preferences (which reads the value
  from the prefs. dialog).
*/
gboolean silky_tips_toggle (GtkWidget *widget, gpointer ptr) {
  gboolean isactive;
  GtkWidget *prefstoggle;

  isactive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  prefstoggle = glade_xml_get_widget(xmlmain, "set_tips");

  if (isactive) {
    debug("set to active");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefstoggle), TRUE);
  } else {
    debug("set to inactive");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefstoggle), FALSE);
    prefs_set("show_tips", PREF_OFF);
  }

  /* save the preferences */
  xml_save_config(CONFIG_MAIN, prefpath);

  return TRUE;

}




syntax highlighted by Code2HTML, v. 0.9.1