/*  File gg_wavelet_win.c
 *
 *  Window to compute wavelet transform
 */


#include <gtk/gtk.h>

#include "defines.h"

#include "gw_list.h"

#include "utils.h"

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

#include "wavelet.h"


extern GdkColor  bleuciel ,wheat;

static void gg_wavelet_AAC_CB (GtkWidget *w ,gint reponse);

static GtkWidget *wavelet_win = NULL;
static GtkWidget *vb;
static GtkWidget *w_typ ,*w_invflag ,*w_stride;
static GtkWidget *w_k_daube ,*w_k_bspline;
static GtkWidget *w_b_daube ,*w_b_bspline;
static gg_SrcDestStructure *srcdest;

static void gg_wavelet_typ_CB (GtkWidget *w ,gpointer p);

/* Allowed values by GSL */
static int bspline_k[] = {103 ,105 ,202 ,204 ,206 ,208 ,301 ,303 ,305 ,307 ,309};

void gg_wavelet_create_win (GtkWidget *w ,gpointer p)
{
  GtkWidget *fr ,*hb;
  if (wavelet_win == NULL) {
    wavelet_win = gg_CreateAACDialog ("Wavelet transform" ,gg_wavelet_AAC_CB ,0 ,0 ,&vb);
    srcdest    = gg_CreateSrcDestSelector (vb ,GTK_SELECTION_MULTIPLE);

    fr = gg_frame (vb ,"General" ,&wheat ,0 ,1);
    w_typ  = gg_combo_new (fr ,"type:" ,7
			   ,"Daubechies"                 /* WAVELET_DAUBECHIES          */
			   ,"Daubechies_centered"        /* WAVELET_DAUBECHIES_CENTERED */
			   ,"Haar"                       /* WAVELET_HARR             	  */
			   ,"Haar_centered"              /* WAVELET_HARR_CENTERED    	  */
			   ,"Bspline"                    /* WAVELET_BSPLINE          	  */
			   ,"Bspline_centered");         /* WAVELET_BSPLINE_CENTERED 	  */
    hb 		= gg_CreateHContainer (fr);
    w_invflag   = gg_check_new (hb ,"Backward transform");
    w_stride    = gg_spin_new  (hb ,"Stride" ,1.0 ,100.0 ,1.0);
    w_k_daube   = gg_spin_new  (fr ,"member of the Daubechies family: k = " ,4.0 ,20.0 ,2.0);
    w_b_daube   = gg_get_w_box ();
    w_k_bspline = gg_combo_new (fr ,"member of the Bspline family: k = " ,12
				,"103" ,"105" ,"202" ,"204" ,"206" ,"208" ,"301" ,"303" ,"305" ,"307" ,"309");
    w_b_bspline = gg_get_w_box ();

    g_signal_connect (w_typ ,"changed" ,G_CALLBACK (gg_wavelet_typ_CB) ,NULL);
  }
  gtk_widget_show_all (wavelet_win);
  gg_set_int (w_typ ,WAVELET_DAUBECHIES);
  gg_wavelet_typ_CB (w_typ ,NULL);
}

void gg_wavelet_update (void)
{
  if (wavelet_win != NULL) {
    WAVParams p;
    if (wavelet_params_get (&p) == RETURN_SUCCESS) {
      gg_set_int  (w_typ  ,p.typ);
      gg_set_int  (w_stride  ,p.stride);
      gg_set_int  (w_invflag  ,p.invflag);
      switch (p.typ) {
      case WAVELET_DAUBECHIES:
      case WAVELET_DAUBECHIES_CENTERED:
	gg_set_int  (w_k_daube  ,p.k);
      case WAVELET_HARR:
      case WAVELET_HARR_CENTERED:
	break;
      case WAVELET_BSPLINE:
      case WAVELET_BSPLINE_CENTERED:
	gg_set_int  (w_k_bspline  ,p.k);
	break;
      }
    }
  }
}

static void gg_wavelet_AAC_CB (GtkWidget *w ,gint reponse)
{
  WAVParams p;
  int gno1 ,gno2 ,ns1 ,ns2;
  gint *sl1 ,*sl2;
  if (reponse == GTK_RESPONSE_ACCEPT || reponse == GTK_RESPONSE_APPLY   ) {
    p.typ     = gg_get_int (w_typ);
    p.stride  = gg_get_int (w_stride);
    p.invflag = gg_get_int (w_invflag);
    switch (p.typ) {
    case WAVELET_DAUBECHIES:
    case WAVELET_DAUBECHIES_CENTERED:
      p.k = p.pk = gg_get_int  (w_k_daube);
    case WAVELET_HARR:
    case WAVELET_HARR_CENTERED:
      break;
    case WAVELET_BSPLINE:
    case WAVELET_BSPLINE_CENTERED:
      p.pk = gg_get_int (w_k_bspline);
      p.k  = bspline_k[p.pk];
      break;
    }
    wavelet_params_set (&p);

    if (gg_GetSrcDestSettings (srcdest ,SD_SET1_UNIQUE | SD_NSET1_EQ_NSET2
                               ,&gno1 ,&gno2
                               ,&ns1  ,&ns2
                               ,&sl1  ,&sl2) == RETURN_FAILURE) return;
    if (do_wavelet (gno1 ,sl1[0] ,gno2 ,sl2[0]) == RETURN_SUCCESS) {
      gg_drawgraph ();
      ge_update_explorer ();
    } else {
      errmsg ("Error in do_wavelet ()");
    }
    xfree (sl1);
    xfree (sl2);
    
  }
  if (reponse == GTK_RESPONSE_ACCEPT || reponse == GTK_RESPONSE_CLOSE) {
    gtk_widget_hide (wavelet_win);
  }

}

static void gg_wavelet_typ_CB (GtkWidget *w ,gpointer p)
{
  if (w != NULL) {
    WAVELET_type  choice = (WAVELET_type) gg_get_int (w);
    switch (choice) {
    case WAVELET_DAUBECHIES:
    case WAVELET_DAUBECHIES_CENTERED:
      gtk_widget_show (w_b_daube);
      gtk_widget_hide (w_b_bspline);
      break;
    case WAVELET_HARR:
    case WAVELET_HARR_CENTERED:
      gtk_widget_hide (w_b_daube);
      gtk_widget_hide (w_b_bspline);
      break;
    case WAVELET_BSPLINE:
    case WAVELET_BSPLINE_CENTERED:
      gtk_widget_hide (w_b_daube);
      gtk_widget_show (w_b_bspline);
      break;
    }
  }
}
