/* Callbacks for files menus
 *  Transcripted from Motif to GTK+ by P. Vincent to
 *  Replace fileswin.c
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>


#include "defines.h"

#include "globals.h"
#include "graphs.h"
#include "utils.h"
#include "files.h"
#include "noxprotos.h"

#include "gw_list.h"

#include "gg_protos.h"
#include "gg_gutil.h"
#include "gg_gtkinc.h"
#include "ge_protos.h"
#include "zc.h"

#include "nn_tree.h"  // Pour deboguer avec print_tree

static gint popup_width = 300 ,popup_height = 500;
extern GdkColor  bleuciel ,wheat;

extern gint* gg_N;

/* From files.c */
extern int sel_dataset_type;

extern GtkWidget *gg_main_window;

static GtkWidget *rdata_dialog = NULL;
static GtkWidget *gg_load_combo;
static GtkWidget *gg_typ_combo ,*gg_typ_item;
static GtkWidget *w_nx ,*w_ny;
static GtkWidget *w_label ,*radio1 ,*radio2;
static GtkWidget *gg_auto_combo;
static GtkWidget *sel_cols_item;
static GtkTextBuffer *preview;

static SetsMenu3Struct *sets_menu3;


/* Protos of some functions in gg_files.c */
// int gg_load_project_file (char *fn, int as_template);
int gg_load_project(char *fn);

void drawgraph(void);  // il semble que plotone.h ne marche pas ici

/************************************************************/
static GtkWidget *graph_list;
static GraphMenu3Struct *graph_menu3 = NULL;
static SetsMenu3Struct  *sets_menu3  = NULL;

GtkWidget *gg_get_fileswin_graph_list ()
{
  return (graph_list);
}

/************************************************************/

typedef struct {
  GtkWidget     *w_format;        /* format */
  GtkTextBuffer *w_descr;         /* description */
  GtkWidget     *w_diff_save;     /* save file in differential mode */
} gg_saveGUI;

static gg_saveGUI gg_save_gui;


/**
 *  Replace update_save_gui  fileswin.c 85
 */
static void gg_update_save_gui (gg_saveGUI *gui) 
{ 
  gg_setstr (gui->w_format, sformat);
  if (get_project_description() != NULL) {
    gtk_text_buffer_set_text (gg_save_gui.w_descr 
			      ,get_project_description()
			      ,-1);
  }
}


/**
 *  Replace create_write_popup    fileswin.c 308
 *  and     write_sets_proc       fileswin.c 341
 */

void gg_create_write_popup (void)
{
  static GtkWidget *fsb = NULL;
  static GtkWidget *fr ,*w_format ,*sel;
  char *filename;
  char format[32];
  FILE *cp;
  int *selset, cd, i ,gno ,setno;

  if (fsb == NULL) {
    fr = gtk_vbox_new (FALSE, 1);
    sel = gg_CreateSetChoice ("Write set(s):"
			      ,GTK_SELECTION_MULTIPLE ,0 ,0 ,NULL ,&sets_menu3 ,NULL);
    gtk_box_pack_start_defaults (GTK_BOX (fr) ,sel);
    w_format = gg_entry_new (fr ,"Format: " ,15);
    gg_setstr (w_format ,sformat);
    fsb = gg_create_file_popup ("Write sets" ,"*.dat" ,0 ,0 ,fr ,TRUE);
  }
  while (gtk_dialog_run (GTK_DIALOG(fsb)) != GTK_RESPONSE_CANCEL) {
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(fsb));
    cp = grace_openw (filename);
    if (cp == NULL) return;
    selset = gw_list_selected_list (GW_LIST (sel) ,&cd);
    if (cd < 1) {
      errmsg("No set selected");
    } else {
      gno = get_cg ();
      strncpy (format, gg_getstr (w_format), 31);
      for(i = 0; i < cd; i++) {
	setno = selset[i];
	write_set (gno, setno, cp, format, TRUE);
      }
      xfree (selset);
    }
    grace_close (cp);


  }
  gtk_widget_hide (fsb);
  
}


/**
 *  Replace create_rparams_popup fileswin.c 373
 *      and read_params_proc     fileswin.c 390
 */
void gg_create_rparams_CB (GtkWidget *w ,gpointer p)
{
  static GtkWidget *rparams_dialog = NULL;
  char *filename;

  gg_set_wait_cursor();

  if (rparams_dialog == NULL) {
    rparams_dialog = gg_create_file_popup ("Read parameters" ,"*.par"
					   ,popup_width ,popup_height
					   ,NULL
					   ,FALSE);
  }
  while (gtk_dialog_run (GTK_DIALOG(rparams_dialog)) != GTK_RESPONSE_CANCEL) {
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(rparams_dialog));
    getparms (filename);
    gg_update_all ();
    gg_drawgraph ();
    g_free (filename);
  }
  gtk_widget_hide (rparams_dialog);
  gg_unset_wait_cursor();
}

/**
 *   Replace create_wparam_frame    fileswin.c 403
 *       and write_params_proc      fileswin.c 429
 */
void gg_create_wparams_CB  (GtkWidget *w ,gpointer p)
{
  static GtkWidget *wparams_dialog = NULL;
  static GtkWidget *vbox ,*gw;
  int gno;
  char *filename;
  FILE *pp;

  gg_set_wait_cursor();

  if (wparams_dialog == NULL) {
    vbox = gtk_vbox_new (FALSE ,2);
    gw = gg_combo_new (vbox,"Write parameters from graph:" ,3
			       ,"Current"
			       ,"All");  
    wparams_dialog = gg_create_file_popup ("Write parameters" ,"*.par"
					   ,popup_width ,popup_height
					   ,vbox
					   ,TRUE);
  }
  while (gtk_dialog_run (GTK_DIALOG(wparams_dialog)) != GTK_RESPONSE_CANCEL) {
    if (gtk_combo_box_get_active (GTK_COMBO_BOX(gw)) == 0) {
      gno = get_cg();
    } else {
      gno = ALL_GRAPHS;
    }    
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(wparams_dialog));
    pp = grace_openw (filename);
    if (pp != NULL) {
      putparms (gno, pp, 0);
      grace_close (pp);
    }
  }
  gtk_widget_hide (GTK_WIDGET (wparams_dialog));
  gg_unset_wait_cursor();
}



/** Callback to start a new project
 *  Replace MenuCB / case MENU_NEW in xmgrace.c 471
 */
void gg_new_CB ()
{
  new_project (NULL);
  gg_drawgraph ();
  ge_update_explorer ();
}

/** Callback to save the current project
 *  Replace MenuCB / case MENU_SAVE in xmgrace.c 480
 */
void gg_save_CB ()
{
  if (strcmp (get_docname(), NONAME) != 0) {
    gg_set_wait_cursor();	    
    save_project (get_docname());	    
    gg_unset_wait_cursor();
  } else {
   gg_saveas_CB ();
  }
}

/** Create "Save as..." Popup  
 *  Replace create_saveproject_popup and save_proc
 */
void gg_saveas_CB ()
{
  GtkWidget *fr ,*rc ,*file_select;
  char *filename;
  gint response;
  GtkTextIter iStart , iEnd;
  char *s;
  int diff_save;

  gg_set_wait_cursor();

  fr = gtk_frame_new (NULL);
  rc =  gtk_vbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (rc) ,fr ,FALSE, TRUE, 0); 
  gg_save_gui.w_diff_save = gg_check_new (rc ,"Differential");
#ifdef WITH_TOOLTIPS
  gtk_widget_set_tooltip_text (gg_save_gui.w_diff_save 
			       ,"Save only parameters different from initial setting");
#endif
  gg_set_int (gg_save_gui.w_diff_save ,FALSE);
  gg_save_gui.w_descr = gg_CreateScrollTextItem2 (rc
 						     ,popup_width ,50
 						     ,"Project description:");
  gg_save_gui.w_format    = gg_entry_new (rc ,"Data format:" ,15);
  gg_update_save_gui (&gg_save_gui);

  file_select = gg_create_file_popup ("Grace : Save project", "*.agr"
				      ,popup_width ,popup_height
				      ,rc
				      ,TRUE);
  response = gtk_dialog_run (GTK_DIALOG( file_select ) ); 
  switch (response) {
  case GTK_RESPONSE_CANCEL :
    break;
  case  GTK_RESPONSE_ACCEPT :
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_select));
    gtk_text_buffer_get_bounds   (gg_save_gui.w_descr ,&iStart ,&iEnd);
    s = gtk_text_buffer_get_text (gg_save_gui.w_descr, &iStart, &iEnd, FALSE);
    set_project_description (s);
    strcpy (sformat ,gg_getstr (gg_save_gui.w_format));
    diff_save = gg_get_int (gg_save_gui.w_diff_save);
    if (diff_save) {
      if (yesno("Use differential saving of parameters only if you want to edit \n a simplified *.agr project file.\n OK to proceed ?") == FALSE){
	break;
      }
    }
    if (save_project_as (filename ,diff_save) != RETURN_SUCCESS) {
      errmsg ("save_project failed\n");
    }
  }
  gtk_widget_destroy (file_select);
  gg_unset_wait_cursor();
}

/** Open and read a *.agr project file
 *  Replace create_openproject_popup  and open_proc
 */
void gg_open_project_popup (void)
{
  static GtkWidget *file_select;
  static char *current_folder = NULL;
  char *filename;

  gg_set_wait_cursor();
  file_select = gg_create_file_popup ("Open Project", "*.agr"
 				      ,popup_width ,popup_height
 				      ,NULL
				      ,FALSE);
  if (current_folder != NULL) {
    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(file_select)
					 ,current_folder);
  }
  gg_unset_wait_cursor();
  while (gtk_dialog_run (GTK_DIALOG(file_select)) != GTK_RESPONSE_CANCEL) {
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_select));
    current_folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(file_select));
    if (gg_load_project (filename) == RETURN_SUCCESS) {
      gg_update_all     ();
      gg_drawgraph      ();
      ge_reset_explorer ();
      ge_explorer_hide  ();
    }       // Prevoir un message d'erreur sinon
  }   
  gtk_widget_destroy (file_select);
}

/*************** R E A D    S E T S ***************/


static void hide_CB (GtkWidget *w ,gpointer p)
{
  gtk_widget_hide (w);
}

/**  Select a graph in a list 
 *   Replace read_sets_proc     fileswin.c  249
 */
static void gg_read_sets_CB (GtkWidget *w ,gint response ,gpointer p)
{
  static char *filename = NULL;
  int graphno = 0 , load;

  if (response == GTK_RESPONSE_ACCEPT) {
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(rdata_dialog));
    if (filename != NULL) {
      load    = gg_get_int (gg_load_combo);
      curtype = gg_get_int (gg_typ_combo);
      if (load != LOAD_BLOCK) graphno = gg_get_int (graph_list);
      if (load == LOAD_SINGLE) {
      } else if (load == LOAD_SELXY) {
	if (settype_cols (curtype) > 3) {
	  errmsg ("Sorry, Select cols. is not able to read this type of set: use Block data");
	  return;
	}
	strcpy (sel_cols_str ,gg_getstr (sel_cols_item));
	stufftext ("\nImporting file \"");
	stufftext (filename);
	stufftext ("\"\n");
	if (sel_dataset_type == SET_XYCMAP) {
	  int nx = gg_get_int (w_nx);
	  int ny = gg_get_int (w_ny);
	  zc_set_map_nxy (nx ,ny);
	}
      }
      autoscale_onread = gg_get_int (gg_auto_combo);
      if (getdata (graphno, filename, cursource, load) == RETURN_SUCCESS) {
	if (load == LOAD_BLOCK) {
	  gg_eblock_create_frame (graphno);
	} else {
	  gg_update_all ();
	  ge_update_explorer ();
	  gg_drawgraph ();
	}
      } else {
	errmsg ("import ASCII data FAILED");
      }
    }
  }
  if (response == GTK_RESPONSE_CANCEL) {
    gtk_widget_hide (rdata_dialog);  
  }

}

/**
 *  Replace set_load_proc   fileswin.c  290
 */
static void gg_load_combo_CB (GtkWidget *w ,gpointer p)
{
  gtk_widget_set_sensitive (sel_cols_item ,gg_get_int(w) == LOAD_SELXY);
}

static void gg_typ_combo_CB (GtkWidget *w ,gpointer p)
{
  sel_dataset_type = gg_get_int (gg_typ_combo);
  switch (sel_dataset_type) {
  case SET_XYCMAP:
  case SET_XYVMAP:
    gtk_widget_set_sensitive (w_nx ,TRUE);
    gtk_widget_set_sensitive (w_ny ,TRUE);
    break;
  default:
    gtk_widget_set_sensitive (w_nx ,FALSE);
    gtk_widget_set_sensitive (w_ny ,FALSE);
    break;
  }
  strncpy (sel_cols_str ,get_default_sel_string (sel_dataset_type) ,MAX_STRING_LENGTH - 1);
  gg_fileswin_update_selxy ();
}

static void gg_SelSetString_CB (GtkWidget *w ,gpointer p)
{
  const char *s = gg_getstr (sel_cols_item);
  sprintf (sel_cols_str ,"%s" ,s);
}

void gg_fileswin_update_selxy (void)
{
  if (rdata_dialog != NULL) {
    gg_setstr (sel_cols_item ,sel_cols_str);
  }
}

static void preview_file_CB (GtkWidget *w ,gpointer p)
{
  static char *filename = NULL;
  FILE *fd = NULL;
  int i;
  char *buf;
  int buflen;
  GtkTextIter start ,end;

  if (rdata_dialog != NULL) {
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(rdata_dialog));
    if (filename != NULL) {
      fd = fopen (filename ,"r");
      if (fd != NULL) {
	gtk_text_buffer_get_bounds (preview ,&start ,&end);
	gtk_text_buffer_delete     (preview ,&start ,&end);
	buflen = 1028;
	buf = xmalloc (buflen);
	for (i = 0; i < 10; i++) {
	  if (read_long_line (fd ,&buf ,&buflen) == RETURN_SUCCESS) {
	    gtk_text_buffer_insert_at_cursor (preview ,buf ,-1);
	  }
	}
	fclose (fd);
	free (buf);
      }
    }
  }
}

/**
 *  Create a popup to import data file
 *  Replace  create_file_popup   fileswin.c  175
 */
void gg_import_popup  (GtkWidget *w ,gpointer p) 
{
  GtkWidget *vb ,*fr ,*rc2;
  int nbtyp;

  if (rdata_dialog == NULL) {
    fr = gtk_frame_new (NULL);
 
    /* extra_widget */
    vb =  gtk_vbox_new (FALSE, 2);
    gtk_box_pack_start (GTK_BOX (vb) ,fr ,FALSE, TRUE, 0); 

    /* Read to graph */
    graph_list = gg_CreateGraphChoice ("Read to graph" ,GTK_SELECTION_BROWSE ,0 ,0 ,NULL
				       ,&graph_menu3);
    gtk_box_pack_start_defaults (GTK_BOX (vb) ,graph_list);

    rc2 = gg_CreateHContainer (vb);
    /* Type of curve data combos */
    gg_load_combo = gg_combo_new (rc2 ,"Load as: " ,5
					  ,"Single set"          /* LOAD_SINGLE  0 */
					  ,"NXY"                 /* LOAD_NXY     1 */
					  ,"Block data"          /* LOAD_BLOCK   2 */
					  ,"Select cols.");      /* LOAD_SELXY   3 */
    nbtyp = NUMBER_OF_SETTYPES;
    gg_typ_combo = gg_combo_fun (rc2 ,"Set type:" ,&nbtyp ,set_types ,0);
    gg_typ_item  = gg_get_w_box ();
    w_nx         = gg_spin_new  (rc2 ,"nx :" ,2.0 ,1000.0 ,1.0);
    w_ny         = gg_spin_new  (rc2 ,"ny :" ,2.0 ,1000.0 ,1.0);

    /* Selection of columns by  x y y ... format  (uniread modified)  */
    sel_cols_item = gg_entry_new (vb ,"Sel:" ,41);
    gg_setstr (sel_cols_item ,sel_cols_str);
    gtk_widget_set_sensitive (sel_cols_item ,FALSE);
#ifdef WITH_TOOLTIPS
    gtk_widget_set_tooltip_text (sel_cols_item
	 ,"Each letter is a column:\n x for abscissa, y , z for ordinates, - to skip\n for each y, a new set is created");
#endif

    /*   source disk/pipe radio button*/
    rc2 =  gtk_hbox_new (FALSE, 2);
    w_label = gtk_label_new_with_mnemonic ("Data source:");
    radio1 = gtk_radio_button_new_with_label (NULL ,"disk"); 
    radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
							  "pipe");
    gtk_box_pack_start (GTK_BOX (rc2), w_label, FALSE, TRUE, 0);
    gtk_box_pack_start (GTK_BOX (rc2), radio1 , FALSE, TRUE, 5);
    gtk_box_pack_start (GTK_BOX (rc2), radio2 , FALSE, TRUE, 5);
    
    /*   autoscale on read  */
    gg_auto_combo = gg_combo_new (vb ,"Autoscale on read:" ,5
					  ,"None"     /* AUTOSCALE_NONE  0 */
					  ,"X"        /* AUTOSCALE_X     1 */
					  ,"Y"        /* AUTOSCALE_Y     2 */
					  ,"XY"       /* AUTOSCALE_XY    3 */
					  );
    gtk_combo_box_set_active  (GTK_COMBO_BOX(gg_auto_combo) ,autoscale_onread);

    /* preview first 10 lines */
    preview = gg_CreateScrollTextItem2 (vb ,0 ,0 ,"First 10 lines");

    rdata_dialog = gg_create_file_popup ("Read data file", "*.dat"
					 ,popup_width ,popup_height
					 ,vb
					 ,FALSE);
    g_signal_connect (gg_load_combo ,"changed"  	 ,G_CALLBACK (gg_load_combo_CB)    ,NULL);
    g_signal_connect (gg_typ_combo  ,"changed"  	 ,G_CALLBACK (gg_typ_combo_CB)     ,NULL);
    g_signal_connect (sel_cols_item ,"activate" 	 ,G_CALLBACK (gg_SelSetString_CB)  ,NULL);
    g_signal_connect (rdata_dialog  ,"response"     	 ,G_CALLBACK (gg_read_sets_CB) 	   ,NULL);
    g_signal_connect (rdata_dialog  ,"delete-event" 	 ,G_CALLBACK (hide_CB) 	           ,NULL);
    g_signal_connect (rdata_dialog  ,"selection-changed" ,G_CALLBACK (preview_file_CB) 	   ,NULL);

    gtk_widget_set_sensitive (w_nx ,FALSE);
    gtk_widget_set_sensitive (w_ny ,FALSE);
  }
  gtk_widget_show_all (rdata_dialog);
  
}


/**
 * Reload the last opened file
 */
void gg_revert_to_saved_CB  (GtkWidget *w ,gpointer p) 
{
  char *s;
  
  gg_set_wait_cursor();
  s = copy_string(NULL, get_docname());
  if (strcmp (s, NONAME) != 0) {
    load_project (s);
  } else {
    new_project (NULL);
  }
  xfree(s);
  gg_drawgraph();
  ge_reset_explorer ();
  gg_unset_wait_cursor();
}
