/* 
 *    Version $Id: callbacks.c,v 1.20 2004/02/28 09:55:45 kerns Exp $
 */

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

#include "bacula.h"
#include "console.h"

#include "callbacks.h"
#include "interface.h"
#include "support.h"

#define KEY_Enter 65293
#define KEY_Up	  65362
#define KEY_Down  65364
#define KEY_Left  65361
#define KEY_Right 65363

gboolean
on_app1_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
   gtk_main_quit();
   return FALSE;
}

void
on_connect_activate(GtkMenuItem *menuitem, gpointer user_data)
{
   if (connect_to_director(user_data)) {
      start_director_reader(user_data);
   }
}


void
on_disconnect_activate(GtkMenuItem *menuitem, gpointer user_data)
{
   if (disconnect_from_director(user_data)) {
      stop_director_reader(user_data);
   }
}


void
on_exit_activate(GtkMenuItem *menuitem, gpointer user_data)
{
   gtk_main_quit();
}


void
on_cut1_activate(GtkMenuItem *menuitem, gpointer user_data)
{

}


void
on_copy1_activate(GtkMenuItem *menuitem, gpointer user_data)
{

}


void
on_paste1_activate(GtkMenuItem *menuitem, gpointer user_data)
{

}


void
on_clear1_activate(GtkMenuItem *menuitem, gpointer user_data)
{

}


void
on_properties1_activate(GtkMenuItem *menuitem, gpointer user_data)
{

}


void
on_preferences1_activate(GtkMenuItem *menuitem, gpointer user_data)
{
}


void
on_about_activate(GtkMenuItem *menuitem, gpointer user_data)
{
   gtk_widget_show(about1);
   gtk_main();
}


void
on_connect_button_clicked(GtkButton *button, gpointer user_data)
{
   if (connect_to_director(user_data)) {
      start_director_reader(user_data);
   }
}

/* Define max length of history and how many to delete when it gets there.  
 * If you make HIST_DEL > HIST_MAX, you shoot yourself in the foot. 
 */
#define HIST_MAX 2500
#define HIST_DEL  500

static GList *hist = NULL;
static GList *hc = NULL;
static int hist_len = 0;

static void add_to_history(gchar *ecmd)
{
   int len = strlen(ecmd);

   if (len > 0) {
      hist = g_list_append(hist, bstrdup(ecmd));
      hist_len++;
   }
   if (hist_len >= HIST_MAX) {
      int i;
      GList *hp;
      for (i=0; i<HIST_DEL; i++) {
	 hp = g_list_next(hist);
	 free(hp->data);
	 hist = g_list_remove(hist, hp->data);
      }
      hist_len -= HIST_DEL;
   }
   hc = NULL;		  
}

/*
 * Note, apparently there is a bug in GNOME where some of the
 *  key press events are lost -- at least it loses every other
 *  up arrow!
 */
gboolean
on_entry1_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
   if (event->keyval == KEY_Enter) {
      char *ecmd = (char *)gtk_entry_get_text((GtkEntry *)entry1);
      set_text(ecmd, strlen(ecmd));
      set_text("\n", 1);
      add_to_history(ecmd);
      write_director(ecmd);
      gtk_entry_set_text((GtkEntry *)entry1, "");
   } else if (event->keyval == KEY_Up) {
      if (!hc) {
	 hc = g_list_last(hist);
      } else {
	 hc = g_list_previous(hc);
      }
      if (!hc) {
	 hc = g_list_first(hist);
      }
      gtk_entry_set_text((GtkEntry *)entry1, (gchar *)hc->data);
   } else if (event->keyval == KEY_Down) {
      if (!hc) {
	 hc = g_list_first(hist);
      } else {
	 hc = g_list_next(hc);
      }
      if (!hc) {
	 hc = g_list_last(hist);
      }
      gtk_entry_set_text((GtkEntry *)entry1, (gchar *)hc->data);
   }
// gtk_entry_set_position((GtkEntry *)entry1, -1);
// gtk_window_set_focus((GtkWindow *)app1, entry1);
   return FALSE;
}


void
on_app1_show(GtkWidget *widget, gpointer user_data)
{
}



void
on_msgs_button_clicked(GtkButton *button, gpointer user_data)
{
   write_director("messages");
}

void
on_msgs_activate(GtkMenuItem *menuitem, gpointer user_data)
{
   write_director("messages");
}

void
on_about_button_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(about1);
   gtk_main_quit();
   set_status_ready();
}

void
on_select_director_OK_clicked(GtkButton *button, gpointer user_data)
{
   reply = OK;
   gtk_widget_hide(dir_dialog);
   gtk_main_quit();
   set_status_ready();
}


void
on_select_director_cancel_clicked(GtkButton *button, gpointer user_data)
{
   reply = CANCEL;
   gtk_widget_hide(dir_dialog);
   gtk_main_quit();
   set_status_ready();
}

/*
 * Compare list string items
 */
static gint compare_func(const void *data1, const void *data2)
{
   return strcmp((const char *)data1, (const char *)data2);
}

static GList *find_combo_list(char *name)
{
   if (strcmp(name, "job") == 0) {
      return job_list;
   }
   if (strcmp(name, "pool") == 0) {
      return pool_list;
   }
   if (strcmp(name, "client") == 0) {
      return client_list;
   }
   if (strcmp(name, "storage") == 0) {
      return storage_list;
   }
   if (strcmp(name, "fileset") == 0) {
      return fileset_list;
   }
   if (strcmp(name, "messages") == 0) {
      return messages_list;
   }
   if (strcmp(name, "type") == 0) {
      return type_list;
   }
   if (strcmp(name, "level") == 0) {
      return level_list;
   }
   return NULL;
}

/*
 * Set correct default values in the Run dialog box
 */
static void set_run_defaults()
{
   GtkWidget *combo, *entry;
   char *job, *def;
   GList *item, *list;
   char cmd[1000];
   int pos;

   stop_director_reader(NULL);

   combo = lookup_widget(run_dialog, "combo_job");
   job = (char *)gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
   bsnprintf(cmd, sizeof(cmd), ".defaults job=\"%s\"", job);
   write_director(cmd);
   while (bnet_recv(UA_sock) > 0) {
      def = strchr(UA_sock->msg, '=');
      if (!def) {
	 continue;
      }
      *def++ = 0;
      if (strcmp(UA_sock->msg, "job") == 0 ||
          strcmp(UA_sock->msg, "when") == 0) {
	 continue;
      }
      /* Where is an entry box */
      if (strcmp(UA_sock->msg, "where") == 0) {
         entry = lookup_widget(run_dialog, "entry_where");
	 gtk_entry_set_text(GTK_ENTRY(entry), def);
	 continue;
      }

      /* Now handle combo boxes */
      list = find_combo_list(UA_sock->msg);
      if (!list) {
	 continue;
      }
      item = g_list_find_custom(list, def, compare_func);
      bsnprintf(cmd, sizeof(cmd), "combo_%s", UA_sock->msg);
      combo = lookup_widget(run_dialog, cmd);
      if (!combo) {
	 continue;
      }
      pos = g_list_position(list, item);
      gtk_list_select_item(GTK_LIST(GTK_COMBO(combo)->list), pos);
   }
   start_director_reader(NULL);
}

void
on_entry_job_changed(GtkEditable *editable, gpointer user_data)
{
   set_run_defaults();
}


void
on_run_button_clicked(GtkButton *button, gpointer user_data)
{
   char dt[50];
   GtkWidget *entry;

   bstrutime(dt, sizeof(dt), time(NULL));
   entry = lookup_widget(run_dialog, "entry_when");
   gtk_entry_set_text(GTK_ENTRY(entry), dt);
   set_run_defaults();
   gtk_widget_show(run_dialog);
   gtk_main();
}


static char *get_combo_text(GtkWidget *dialog, char *combo_name)
{
   GtkWidget *combo;
   combo = lookup_widget(dialog, combo_name);
   if (!combo) {
      return NULL;
   }
   return (char *)gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
}

static char *get_entry_text(GtkWidget *dialog, char *entry_name)
{
   GtkWidget *entry;
   entry = lookup_widget(dialog, entry_name);
   if (!entry) {
      return NULL;
   }
   return (char *)gtk_entry_get_text(GTK_ENTRY(entry));
}

static char *get_spin_text(GtkWidget *dialog, char *spin_name)
{
   GtkSpinButton *spin;
   spin = (GtkSpinButton *)lookup_widget(dialog, spin_name);
   if (!spin) {
      return NULL;
   }
   return (char *)gtk_entry_get_text(GTK_ENTRY(&spin->entry));
}




void
on_run_ok_clicked(GtkButton *button, gpointer user_data)
{
   char *job, *fileset, *level, *client, *pool, *when, *where, *storage;

   gtk_widget_hide(run_dialog);
   gtk_main_quit();

   job     = get_combo_text(run_dialog, "combo_job");
   fileset = get_combo_text(run_dialog, "combo_fileset");
   client  = get_combo_text(run_dialog, "combo_client");
   pool    = get_combo_text(run_dialog, "combo_pool");
   storage = get_combo_text(run_dialog, "combo_storage");
   level   = get_combo_text(run_dialog, "combo_level");

   when    = get_entry_text(run_dialog, "entry_when");
   where   = get_entry_text(run_dialog, "entry_where");

   if (!job || !fileset || !client || !pool || !storage ||
       !level || !when || !where) {
      set_status_ready();
      return;
   }
      
   bsnprintf(cmd, sizeof(cmd), 
             "run job=\"%s\" fileset=\"%s\" level=%s client=\"%s\" pool=\"%s\" "
             "when=\"%s\" where=\"%s\" storage=\"%s\"", 
	     job, fileset, level, client, pool, when, where, storage);
   write_director(cmd);
   write_director("yes");
   return;
}


void
on_run_cancel_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(run_dialog);
   gtk_main_quit();
   set_status_ready();
}

gboolean
on_entry1_key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  return FALSE;
}

void
on_restore_button_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_show(restore_dialog);
   gtk_main();
}

void
on_view_fileset_clicked(GtkButton *button, gpointer user_data)
{
}

void
on_restore_ok_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(restore_dialog);
   gtk_main_quit();
   set_status_ready();
}


void
on_restore_cancel_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(restore_dialog);
   gtk_main_quit();
   set_status_ready();
}

void
on_apply_button_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_show(restore_files);
   gtk_main();
}

void
on_restore_file_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(restore_files);
   gtk_main_quit();
}

void
on_label_button_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_show(label_dialog);
   gtk_main();
}

void
on_label_ok_clicked(GtkButton *button, gpointer user_data)
{
   char *pool, *volume, *storage, *slot;

   gtk_widget_hide(label_dialog);
   gtk_main_quit();

   pool    = get_combo_text(label_dialog, "label_combo_pool");
   storage = get_combo_text(label_dialog, "label_combo_storage");

   volume  = get_entry_text(label_dialog, "label_entry_volume");

   slot    = get_spin_text(label_dialog, "label_slot");

   if (!pool || !storage || !volume || !(*volume)) {
      set_status_ready();
      return;
   }
      
   bsnprintf(cmd, sizeof(cmd), 
             "label name=\"%s\" pool=\"%s\" storage=\"%s\" slot=%s", 
	     volume, pool, storage, slot);
   write_director(cmd);
}


void
on_label_cancel_clicked(GtkButton *button, gpointer user_data)
{
   gtk_widget_hide(label_dialog);
   gtk_main_quit();
   set_status_ready();
}
