 #ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gnome.h>
#include "options.h"
#include "callbacks.h"
#include "interface.h"
#include "support.h"
#include "utils.h"

/* Global variables */
extern GtkWidget *window1;
extern GtkWidget *dlgAbout;
extern GtkWidget *dlgConfig;
extern GtkWidget *dlgSettings;
extern Options *options;

gboolean conf_changed;

/* Internally used globals */
int confRowSelected;
int confRowCount;

void exit_app(GtkObject *object,gpointer user_data) {
exit(0);
}

void on_exit_app() {
  /* Exit program */
  printf("Exiting and ");
  if(options->save_host_name || options->save_host_settings) {
    printf("saving configuration file\n");
    if(conf_changed==1)
      saveSettings(NULL,options);
    else
      printf("On second thought.. naah, why bother. Nothing has changed\n");
  } else printf("not saving options\n");
}

void on_btnAbout_clicked(GtkButton *button, gpointer user_data) {
  /* Show about box */
  dlgAbout=create_dlgAbout();
  gtk_widget_show(dlgAbout);
}

void on_btnOptions_clicked(GtkButton *button,gpointer user_data) {
  GtkWidget *btn1=NULL;
  GtkWidget *btn2=NULL;
  GtkWidget *btn3=NULL;
  GtkEntry *txtSsh=NULL;
  GtkEntry *txtTerminal=NULL;
  /* Show configuration screen */
  btn1 = lookup_widget(dlgConfig,"chkSaveHostName");
  btn2 = lookup_widget(dlgConfig,"chkSaveHostSettings");
  btn3 = lookup_widget(dlgConfig,"chkUseHostSettings");
  txtSsh = GTK_ENTRY(lookup_widget(dlgConfig,"txtSsh"));
  txtTerminal = GTK_ENTRY(lookup_widget(dlgConfig,"txtTerminal"));
  confRowSelected=-1;
  updateHostBox();
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn1),options->save_host_name);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn2),options->save_host_settings);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn3),options->use_host_settings);
  gtk_entry_set_text(txtSsh,options->ssh_cmd);
  gtk_entry_set_text(txtTerminal,options->term_cmd);
  gtk_widget_show(dlgConfig);
}


void on_btnAdd_clicked(GtkButton *button,gpointer user_data) {
  /* Add a new host to the list */
  GtkWidget *txtHost=NULL;
  gchar *text[1];
  txtHost = lookup_widget(dlgConfig,"txtAddHost");
  text[0] = gtk_entry_get_text(GTK_ENTRY(txtHost));
  confRowCount=hostList_addEntry(text,-1);
  gtk_entry_set_text(GTK_ENTRY(txtHost),"");
}


void on_btnRemove_clicked(GtkButton *button, gpointer user_data) {
  /* Delete a host */
  GtkWidget *hostList=NULL;
  if(confRowSelected==-1) return;
  hostList = lookup_widget(dlgConfig,"lstHosts");
  gtk_clist_remove(GTK_CLIST(hostList),confRowSelected);
  confRowCount--;
  if(confRowSelected==confRowCount) confRowSelected--;
}


void on_btnUp_clicked(GtkButton *button,gpointer user_data) {
  GtkWidget *hostList=NULL;
  if(confRowSelected<=0) return;
  hostList = lookup_widget(dlgConfig,"lstHosts");
  gtk_clist_swap_rows(GTK_CLIST(hostList),confRowSelected,confRowSelected-1);
  confRowSelected--;
}


void on_btnDown_clicked(GtkButton *button,gpointer user_data) {
  GtkWidget *hostList=NULL;
  if(confRowSelected==-1 || confRowSelected==confRowCount-1) return;
  hostList = lookup_widget(dlgConfig,"lstHosts");
  gtk_clist_swap_rows(GTK_CLIST(hostList),confRowSelected,confRowSelected+1);
  confRowSelected++;
}


void on_btnCancelConf_clicked(GtkButton *button,gpointer user_data) {
  /* Hide configuration dialog */
  gtk_widget_hide(dlgConfig);
}


void on_lstHosts_select_row(GtkCList *clist,gint row,gint column,GdkEvent *event,gpointer user_data) {
  /* Keep track of the selections */
  confRowSelected=row;
}


void on_btnImport_clicked(GtkWidget *button,gpointer user_data) {
  GtkWidget *chkAppend;
  char filename[512];
  chkAppend = lookup_widget(dlgConfig,"chkAppend");

  sprintf(filename,"%s/.kde/share/config/ksshrc",getenv("HOME"));
  if(importkssh(filename,options,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkAppend)))) {
    fprintf(stderr,"Error while importing ksshrc from file %s !\n",filename);
    return;
  }
  updateHostBox();
  conf_changed=1;
}

void on_btnOkConf_clicked(GtkButton *button,gpointer user_data) {
  GtkCList *hostList;
  SSH_Entry *tmp;
  GtkToggleButton *btn1=NULL;
  GtkToggleButton *btn2=NULL;
  GtkToggleButton *btn3=NULL;
  GtkEntry *txtSsh=NULL;
  GtkEntry *txtTerminal=NULL;
  int r;
  hostList = GTK_CLIST(lookup_widget(dlgConfig,"lstHosts"));
  btn1 = GTK_TOGGLE_BUTTON(lookup_widget(dlgConfig,"chkSaveHostName"));
  btn2 = GTK_TOGGLE_BUTTON(lookup_widget(dlgConfig,"chkSaveHostSettings"));
  btn3 = GTK_TOGGLE_BUTTON(lookup_widget(dlgConfig,"chkUseHostSettings"));
  txtSsh = GTK_ENTRY(lookup_widget(dlgConfig,"txtSsh"));
  txtTerminal = GTK_ENTRY(lookup_widget(dlgConfig,"txtTerminal"));
  /* Put data back into the Options structure */
  options->save_host_name=gtk_toggle_button_get_active(btn1);
  options->save_host_settings=gtk_toggle_button_get_active(btn2);
  options->use_host_settings=gtk_toggle_button_get_active(btn3);
  options->ssh_cmd = g_strdup(gtk_entry_get_text(txtSsh));
  options->term_cmd = g_strdup(gtk_entry_get_text(txtTerminal));
  if(options->entries->numEntries!=confRowCount) {
    /* Reallocate space for entries list */
    options->entries->numEntries=confRowCount;
    if(options->entries->entries) free(options->entries->entries);
    options->entries->entries = malloc(sizeof(SSH_Entry)*confRowCount);
  }
  for(r=0;r<confRowCount;r++) {
    tmp=gtk_clist_get_row_data(hostList,r);
    if(tmp==NULL) {
      fprintf(stderr,"Error ! Got NULL while update host entry list position %d !\n",r);
      exit(1);
    }
    options->entries->entries[r]=*tmp;
  }
  // Save data
  saveSettings(NULL,options);
  // Update the combo host list
  gtk_clist_clear(GTK_CLIST(hostList));
  updateComboBox();
  gtk_widget_hide(dlgConfig);
}

void on_btnConnect_clicked(GtkButton *button,gpointer user_data) {
  GtkWidget *txtHost=NULL;
  GtkWidget *txtUser=NULL;
  GtkWidget *txtPort=NULL;
  GtkWidget *chkPort=NULL;
  gchar *user,*host;
  int port,r=0,pos;
  int found;
  // Get widgets
  txtHost = lookup_widget(window1,"txtHostname");
  txtUser = lookup_widget(window1,"txtUsername");
  txtPort = lookup_widget(window1,"txtPort");
  chkPort = lookup_widget(window1,"chkPort");
  // Get data from widgets
  host = g_strdup(gtk_entry_get_text(GTK_ENTRY(txtHost)));
  user = g_strdup(gtk_entry_get_text(GTK_ENTRY(txtUser)));
  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkPort)))
    port  = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(txtPort));
  else
    port = 0;
  if(strlen(user)==0) return;
  // Check if this host is used before
  if(options->save_host_name || options->save_host_settings) {
    found=-1;
    for(r=0;r<options->entries->numEntries;r++) {
      if(!strcmp(host,options->entries->entries[r].hostname)) {
        if(options->save_host_settings) {
          options->entries->entries[r].username=user;
          conf_changed=1;
          pos=r;
        }
        found=r;
        break;
      }
    }
    if(found==-1 && options->save_host_name) {
      pos=options->entries->numEntries;
      options->entries->numEntries++;
      options->entries->entries = realloc(options->entries->entries,sizeof(SSH_Entry)*options->entries->numEntries);
      options->entries->entries[pos].hostname = host;
      options->entries->entries[pos].username = user;
      options->entries->entries[pos].usePort = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkPort));
      options->entries->entries[pos].port = port;
      options->entries->entries[pos].forwardLocalDest=NULL;
      options->entries->entries[pos].forwardRemoteDest=NULL;
      options->entries->entries[pos].forwardX11=NULL;
      options->entries->entries[pos].forwardAuth=NULL;
      options->entries->entries[pos].cipherType=NULL;
      options->entries->entries[pos].customEscape=NULL;
      options->entries->entries[pos].identityFile=NULL;
      options->entries->entries[pos].allocatePseudoTTY=NULL;
      options->entries->entries[pos].customOptions=NULL;
      options->entries->entries[pos].remoteCmd=NULL;

      conf_changed=1;
      updateComboBox();
    }
  }
  openTerminal(host,user,port,options,r);
}


void on_txtHostname_changed(GtkEditable *editable, gpointer user_data) {
  char *hostname;
  GtkEntry *usrname;
  GtkToggleButton *usePort;
  GtkSpinButton *port;
  int r;
  // Set proper username
  if(!options->use_host_settings) return;
  usrname = GTK_ENTRY(lookup_widget(window1,"txtUsername"));
  usePort = GTK_TOGGLE_BUTTON(lookup_widget(window1,"chkPort"));
  port = GTK_SPIN_BUTTON(lookup_widget(window1,"txtPort"));
  hostname=gtk_editable_get_chars(editable,0,-1);
  if(hostname==NULL) return;
  for(r=0;r<options->entries->numEntries;r++) {
    if(strcmp(options->entries->entries[r].hostname,hostname)==0) {
      if(options->entries->entries[r].username)
        gtk_entry_set_text(usrname,options->entries->entries[r].username);
      gtk_toggle_button_set_active(usePort,options->entries->entries[r].usePort);
      if(options->entries->entries[r].usePort)
        gtk_spin_button_set_value(port,options->entries->entries[r].port);
    }
  }
}


void on_btnHostSettings_clicked(GtkButton *button,gpointer user_data) {
  GtkEntry *txtSettingsUsername,*txtForwardLocal,*txtForwardRemote;
  GtkEntry *txtX11,*txtAuth,*txtCipher,*txtEscape,*txtIdent,*txtPseudoTTY,*txtCustom;
  GtkSpinButton *txtSettingsPort,*txtForwardLocalPort,*txtForwardRemotePort,*txtForwardLocalPortC,*txtForwardRemotePortC;
  GtkToggleButton *btnSettingsUsePort,*chkEnableExtra,*btnForwardLocal,*btnForwardRemote;
  GtkToggleButton *chkAllowRemote,*chkDisableKerberos,*chkNonprivPort,*chkCompress;
  GtkToggleButton *chkFork,*chkDevNull,*chkExecCmd;
  GtkEntry *txtExecCmd;
  GtkCList *hostList;

  SSH_Entry *tmp;
  hostList = GTK_CLIST(lookup_widget(dlgConfig,"lstHosts"));
  if(confRowSelected==-1) return;
  tmp=gtk_clist_get_row_data(hostList,confRowSelected);

  txtSettingsUsername = GTK_ENTRY(lookup_widget(dlgSettings,"txtSettingsUsername"));
  txtSettingsPort = GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtSettingsPort"));
  btnSettingsUsePort = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnSettingsUsePort"));
  chkEnableExtra = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkEnableExtra"));

  btnForwardLocal = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnForwardLocal"));
  btnForwardRemote = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnForwardRemote"));
  txtForwardLocal = GTK_ENTRY(lookup_widget(dlgSettings,"txtForwardLocal"));
  txtForwardRemote = GTK_ENTRY(lookup_widget(dlgSettings,"txtForwardRemote"));
  txtForwardLocalPort = GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardLocalPort"));
  txtForwardRemotePort = GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardRemotePort"));
  txtForwardLocalPortC = GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardLocalPortC"));
  txtForwardRemotePortC = GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardRemotePortC"));

  txtX11 = GTK_ENTRY(lookup_widget(dlgSettings,"txtX11"));
  txtAuth = GTK_ENTRY(lookup_widget(dlgSettings,"txtAuth"));
  chkAllowRemote = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkAllowRemote"));
  chkDisableKerberos = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkDisableKerberos"));

  txtCipher = GTK_ENTRY(lookup_widget(dlgSettings,"txtCipher"));
  txtEscape = GTK_ENTRY(lookup_widget(dlgSettings,"txtEscape"));
  txtIdent = GTK_ENTRY(lookup_widget(dlgSettings,"txtIdent"));
  txtPseudoTTY = GTK_ENTRY(lookup_widget(dlgSettings,"txtPseudoTTY"));
  txtCustom = GTK_ENTRY(lookup_widget(dlgSettings,"txtCustom"));
  chkNonprivPort = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkNonprivPort"));
  chkCompress = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkCompression"));

  chkFork = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkFork"));
  chkDevNull = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkDevNull"));
  chkExecCmd = GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkExecCmd"));
  txtExecCmd = GTK_ENTRY(lookup_widget(dlgSettings,"txtExecCmd"));
  /* Basic -page */
  gtk_entry_set_text(txtSettingsUsername,tmp->username);
  gtk_spin_button_set_value(txtSettingsPort,tmp->port);
  gtk_toggle_button_set_active(btnSettingsUsePort,tmp->usePort);
  gtk_toggle_button_set_active(chkEnableExtra,tmp->useExtra);
  /* Forwarding -page */
  gtk_toggle_button_set_active(btnForwardLocal,tmp->forwardLocal);
  gtk_toggle_button_set_active(btnForwardRemote,tmp->forwardRemote);
  gtk_toggle_button_set_active(chkAllowRemote,tmp->allowRemoteConnect);
  gtk_toggle_button_set_active(chkDisableKerberos,tmp->disableKerberosForwarding);
  gtk_entry_set_text(txtForwardLocal,tmp->forwardLocalDest);
  gtk_entry_set_text(txtForwardRemote,tmp->forwardRemoteDest);
  gtk_entry_set_text(txtX11,tmp->forwardX11);
  gtk_entry_set_text(txtAuth,tmp->forwardAuth);
  gtk_spin_button_set_value(txtForwardLocalPort,tmp->forwardLocalPort);
  gtk_spin_button_set_value(txtForwardRemotePort,tmp->forwardRemotePort);
  gtk_spin_button_set_value(txtForwardLocalPortC,tmp->forwardLocalPortC);
  gtk_spin_button_set_value(txtForwardRemotePortC,tmp->forwardRemotePortC);
  /* Protocol -page */
  gtk_entry_set_text(txtCipher,tmp->cipherType);
  gtk_entry_set_text(txtEscape,tmp->customEscape);
  gtk_entry_set_text(txtIdent,tmp->identityFile);
  gtk_entry_set_text(txtPseudoTTY,tmp->allocatePseudoTTY);
  gtk_entry_set_text(txtCustom,tmp->customOptions);
  gtk_toggle_button_set_active(chkNonprivPort,tmp->useNonPrivilegedPort);
  gtk_toggle_button_set_active(chkCompress,tmp->compress);
  /* Command execution -page */
  gtk_toggle_button_set_active(chkFork,tmp->forkToBg);
  gtk_toggle_button_set_active(chkDevNull,tmp->devNull);
  gtk_toggle_button_set_active(chkExecCmd,tmp->execCmd);
  gtk_entry_set_text(txtExecCmd,tmp->remoteCmd);

  gtk_widget_show(dlgSettings);
}


gboolean on_window_delete_event(GtkWidget *widget,GdkEvent *event,gpointer user_data)
{
  gtk_widget_hide( widget );
  return TRUE;
}

void on_btnSettingsOk_clicked(GtkButton *button,gpointer user_data)
{
  GtkCList *hostList;
  SSH_Entry *tmp;

  hostList = GTK_CLIST(lookup_widget(dlgConfig,"lstHosts"));
  tmp=gtk_clist_get_row_data(hostList,confRowSelected);

  tmp->username = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtSettingsUsername")),0,-1);
  tmp->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtSettingsPort")));
  tmp->usePort = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnSettingsUsePort")));
  tmp->useExtra = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkEnableExtra")));

  tmp->forwardLocal = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnForwardLocal")));
  tmp->forwardRemote = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"btnForwardRemote")));
  tmp->forwardLocalDest = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtForwardLocal")),0,-1);
  tmp->forwardRemoteDest = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtForwardRemote")),0,-1);
  tmp->forwardLocalPort = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardLocalPort")));
  tmp->forwardRemotePort = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardRemotePort")));
  tmp->forwardLocalPortC = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardLocalPortC")));
  tmp->forwardRemotePortC = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(dlgSettings,"txtForwardRemotePortC")));
  tmp->forwardX11 = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtX11")),0,-1);
  tmp->forwardAuth = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtAuth")),0,-1);
  tmp->allowRemoteConnect = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkAllowRemote")));
  tmp->disableKerberosForwarding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkDisableKerberos")));

  tmp->cipherType  = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtCipher")),0,-1);
  tmp->customEscape = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtEscape")),0,-1);
  tmp->identityFile = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtIdent")),0,-1);
  tmp->allocatePseudoTTY = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtPseudoTTY")),0,-1);
  tmp->customOptions = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtCustom")),0,-1);
  tmp->useNonPrivilegedPort = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkNonprivPort")));
  tmp->compress = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkCompression")));

  tmp->forkToBg = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkFork")));
  tmp->devNull = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkDevNull")));
  tmp->execCmd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dlgSettings,"chkExecCmd")));
  tmp->remoteCmd = gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dlgSettings,"txtExecCmd")),0,-1);

  gtk_widget_hide(dlgSettings);
}


void on_btnSettingsCancel_clicked(GtkButton *button, gpointer user_data)
{
gtk_widget_hide(dlgSettings);
}

