/*  SciGraphica - Scientific graphics and data manipulation
 *  Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>
#include <gtk/gtk.h>
#include <gtkextra/gtkextra.h>
#include "sg_axis_dialog.h"
#include "sg.h"
#include <math.h>

struct _SGaxisdialog{

  SGlayer *layer;
  SGplot *plot;

  GtkPlotAxis *axis;

  GtkPlotAxis *axis1, *axis2;
  
  GtkPlotTicks *ticks;
  GtkWidget *from_entry, *to_entry, *major_entry, *first_entry, *last_entry;
  GtkWidget *major_spin,*minor_spin;
  GtkWidget *scale_combo, *rescale_combo;
  GtkWidget *axis_1, *axis_2;
  GtkWidget *labels_1, *labels_2;
  GtkWidget *titles_1, *titles_2;
  GtkWidget *major_1_in, *major_2_in;
  GtkWidget *major_1_out, *major_2_out;
  GtkWidget *minor_1_in, *minor_2_in;
  GtkWidget *minor_1_out, *minor_2_out;
  GtkWidget *minor_grids, *major_grids;
  GtkWidget *opposite, *origin;
  GtkPlotOrientation orientation;
  gdouble min,max;
};

typedef struct _SGaxisdialog SGaxisdialog;

static SGaxisdialog axis_dialog[3];

static gchar *scale[] = {"Linear", "Log10", NULL};
/*, "Ln", "Log2", NULL};
*/

static gchar *rescale[] = { "Optimal", "Fixed", NULL};
static gchar *major_choice[] = {"Interval", "Number", NULL};

void
sg_axis_dialog_update_plot(GtkWidget *notebook)
{
  SGaxisdialog *dialog;
  GtkPlot *plot;
  GtkWidget *child;
  gboolean state;
  gchar *text;
  gchar *text_begin, *text_end;
  gdouble max, min;
  gdouble major;
  gint nminor,nmajor;
  gboolean set_limits;
  gint page;
  gint mask1, mask2;
 
  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
  dialog = &axis_dialog[page];
  plot = GTK_PLOT(dialog->layer->real_plot);
 
  min = atof(gtk_entry_get_text(GTK_ENTRY(dialog->from_entry))); 
  max = atof(gtk_entry_get_text(GTK_ENTRY(dialog->to_entry))); 

  if(min >= max) return;

  major = atof(gtk_entry_get_text(GTK_ENTRY(dialog->major_entry))); 

  if(major < 0) return;

  nminor = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->minor_spin));

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->labels_1));
  dialog->axis1->label_mask = state * GTK_PLOT_LABEL_OUT;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->labels_2));
  dialog->axis2->label_mask = state * GTK_PLOT_LABEL_OUT;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->titles_1));
  dialog->axis1->title_visible = state;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->titles_2));
  dialog->axis2->title_visible = state;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->major_1_out));
  mask1 = state * GTK_PLOT_TICKS_OUT;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->major_2_out));
  mask2 = state * GTK_PLOT_TICKS_OUT;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->major_1_in));
  mask1 |= state * GTK_PLOT_TICKS_IN;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->major_2_in));
  mask2 |= state * GTK_PLOT_TICKS_IN;

  dialog->axis1->major_mask = mask1;
  dialog->axis2->major_mask = mask2;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->minor_1_out));
  mask1 = state * GTK_PLOT_TICKS_OUT;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->minor_2_out));
  mask2 = state * GTK_PLOT_TICKS_OUT;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->minor_1_in));
  mask1 |= state * GTK_PLOT_TICKS_IN;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->minor_2_in));
  mask2 |= state * GTK_PLOT_TICKS_IN;

  dialog->axis1->minor_mask = mask1;
  dialog->axis2->minor_mask = mask2;

  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->major_grids));
  dialog->axis->show_major_grid = state;
  state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->minor_grids));
  dialog->axis->show_minor_grid = state;

  if(dialog->layer->type != SG_LAYER_3D){
    GtkPlotScale scale;
    gdouble begin, end;

    state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->axis_1));
    dialog->axis1->is_visible = state;

    state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->axis_2));
    dialog->axis2->is_visible = state;

    state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->opposite));
    if(dialog->orientation == GTK_PLOT_AXIS_X)
      plot->show_y0 = state;
    else
      plot->show_x0 = state;
  
    state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->origin));
    if(dialog->orientation == GTK_PLOT_AXIS_X)
      plot->show_x0 = state;
    else
      plot->show_y0 = state;
  
    child = (GtkWidget *)GTK_LIST(GTK_COMBO(dialog->scale_combo)->list)->selection->data;
    scale = (GtkPlotScale)gtk_list_child_position(GTK_LIST(GTK_COMBO(dialog->scale_combo)->list), child);

    if(dialog->orientation == GTK_PLOT_AXIS_X)
      gtk_plot_set_xscale(plot, scale);
    else
      gtk_plot_set_yscale(plot, scale);
    
    child = (GtkWidget *)GTK_LIST(GTK_COMBO(dialog->rescale_combo)->list)->selection->data;
    dialog->layer->rescale=(GtkPlotScale)gtk_list_child_position(GTK_LIST(GTK_COMBO(dialog->rescale_combo)->list), child);

    text_begin = gtk_entry_get_text(GTK_ENTRY(dialog->first_entry));
    text_end = gtk_entry_get_text(GTK_ENTRY(dialog->last_entry));

    begin = min;
    end = max;

    if(strlen(text_begin) == 0 && strlen(text_end) == 0){
      set_limits = FALSE;
    }else{
      set_limits = TRUE;
      if(strlen(text_begin) != 0) begin = atof(text_begin);
      if(strlen(text_end) != 0) end = atof(text_end);
    }

    if(set_limits)
      gtk_plot_axis_set_ticks_limits(plot, dialog->orientation, begin, end);
    else
      gtk_plot_axis_unset_ticks_limits(plot, dialog->orientation);
  }

  if(dialog->layer->type == SG_LAYER_3D){
    switch(dialog->orientation){
      case GTK_PLOT_AXIS_X: 
        gtk_plot3d_set_xrange(GTK_PLOT3D(plot), min, max);
        break;
      case GTK_PLOT_AXIS_Y: 
        gtk_plot3d_set_yrange(GTK_PLOT3D(plot), min, max);
        break;
      case GTK_PLOT_AXIS_Z: 
        gtk_plot3d_set_zrange(GTK_PLOT3D(plot), min, max);
        break;
    }
  } else {
    switch(dialog->orientation){
      case GTK_PLOT_AXIS_X: 
        gtk_plot_set_xrange(plot, min, max);
        break;
      case GTK_PLOT_AXIS_Y: 
        gtk_plot_set_yrange(plot, min, max);
        break;
      default:
        break;
    }
  }

  if(dialog->layer->type != SG_LAYER_3D) 
  { if (fabs(dialog->ticks->step)>0)
      nmajor=ceil(fabs((max - min)/major));
    else 
      nmajor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->major_spin));
    if (nmajor>100)
      { nmajor=100;
        major=ceil(fabs((max-min)/nmajor));
      }

    gtk_plot_axis_set_ticks(plot, dialog->orientation, major, nminor);
  }
  else
    gtk_plot3d_axis_set_ticks(GTK_PLOT3D(plot), dialog->orientation, major, nminor);


  gtk_plot_canvas_paint(GTK_PLOT_CANVAS(dialog->plot->real_canvas));
  gtk_plot_canvas_refresh(GTK_PLOT_CANVAS(dialog->plot->real_canvas));
}

static void
init_dialog(SGaxisdialog *dialog)
{
  GtkPlot *plot;
  gboolean state;
  gchar text[100];
  gchar text_begin[100];
  gchar text_end[100];
  GtkPlotOrientation orientation;
  gint mask1, mask2, nmajor;

  plot = GTK_PLOT(dialog->layer->real_plot);
  orientation = dialog->axis->orientation;

  sprintf(text,"%g",dialog->axis->min);
  gtk_entry_set_text(GTK_ENTRY(dialog->from_entry), text); 

  sprintf(text,"%g",dialog->axis->max);
  gtk_entry_set_text(GTK_ENTRY(dialog->to_entry), text); 

  sprintf(text,"%g",dialog->ticks->step);
  gtk_entry_set_text(GTK_ENTRY(dialog->major_entry), text); 

  gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->minor_spin), dialog->ticks->nminor);
  
  if (fabs(dialog->ticks->step)>0)
    nmajor=ceil(fabs((dialog->axis->max - dialog->axis->min)/dialog->ticks->step));
  else 
    nmajor=8;

  gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->major_spin), nmajor);

  mask1 = dialog->axis1->label_mask;
  mask2 = dialog->axis2->label_mask;
  state = mask1 & GTK_PLOT_LABEL_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->labels_1), state);
  state = mask2 & GTK_PLOT_LABEL_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->labels_2), state);
  state = dialog->axis1->title_visible; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->titles_1), state);
  state = dialog->axis2->title_visible; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->titles_2), state);

  mask1 = dialog->axis1->major_mask;
  mask2 = dialog->axis2->major_mask;
  state = mask1 & GTK_PLOT_TICKS_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->major_1_out), state);
  state = mask1 & GTK_PLOT_TICKS_IN; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->major_1_in), state);
  state = mask2 & GTK_PLOT_TICKS_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->major_2_out), state);
  state = mask2 & GTK_PLOT_TICKS_IN; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->major_2_in), state);

  mask1 = dialog->axis1->minor_mask;
  mask2 = dialog->axis2->minor_mask;
  state = mask1 & GTK_PLOT_TICKS_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->minor_1_out), state);
  state = mask1 & GTK_PLOT_TICKS_IN; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->minor_1_in), state);
  state = mask2 & GTK_PLOT_TICKS_OUT; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->minor_2_out), state);
  state = mask2 & GTK_PLOT_TICKS_IN; 
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->minor_2_in), state);

  state = dialog->axis->show_major_grid;
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->major_grids), state);
  state = dialog->axis->show_minor_grid;
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->minor_grids), state);

  if(dialog->layer->type != SG_LAYER_3D){
    sprintf(text_begin,"%g",dialog->ticks->begin);
    sprintf(text_end,"%g",dialog->ticks->end);
    if(dialog->ticks->set_limits){
         gtk_entry_set_text(GTK_ENTRY(dialog->first_entry), text_begin); 
         gtk_entry_set_text(GTK_ENTRY(dialog->last_entry), text_end); 
    }

    state = dialog->axis1->is_visible; 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->axis_1), state);

    state = dialog->axis2->is_visible; 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->axis_2), state);

    state = (((orientation == GTK_PLOT_AXIS_Y) & plot->show_x0) || 
             ((orientation == GTK_PLOT_AXIS_X) & plot->show_y0)); 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->opposite), state);

    state = (((orientation == GTK_PLOT_AXIS_Y) & plot->show_y0) || 
             ((orientation == GTK_PLOT_AXIS_X) & plot->show_x0)); 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->origin), state);

    gtk_list_select_item(GTK_LIST(GTK_COMBO(dialog->rescale_combo)->list),
                         dialog->layer->rescale);

  }
}

void insert_min(GtkWidget *button, gpointer data)
{ gchar text[20];
  SGaxisdialog *dialog;
  
  dialog=(SGaxisdialog *)data;
  snprintf(text,20,"%g",dialog->min);
  gtk_entry_set_text(GTK_ENTRY(dialog->from_entry), text);
}

void insert_max(GtkWidget *button, gpointer data)
{ gchar text[20];
  SGaxisdialog *dialog;
  
  dialog=(SGaxisdialog *)data;
  snprintf(text,20,"%g",dialog->max);
  gtk_entry_set_text(GTK_ENTRY(dialog->to_entry), text);
}

void insert_interval(GtkWidget *button, gpointer data)
{ gchar text[20];
  SGaxisdialog *dialog;
  gint nmajor;
  gdouble min,max,intv;
  
  dialog=(SGaxisdialog *)data;
  nmajor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->major_spin));
  min = atof(gtk_entry_get_text(GTK_ENTRY(dialog->from_entry))); 
  max = atof(gtk_entry_get_text(GTK_ENTRY(dialog->to_entry))); 
  if (nmajor>0)
    intv=(max-min)/nmajor;
  else intv=max-min;

  snprintf(text,20,"%g",intv);
  gtk_entry_set_text(GTK_ENTRY(dialog->major_entry), text);
  gtk_widget_set_sensitive(button,FALSE);
}

void spin_major_changed(GtkWidget *widget, GtkWidget *button)
{
  gtk_widget_set_sensitive(button,TRUE);
}

static GtkWidget *
sg_build_axis_dialog (SGlayer *layer, GtkPlotAxis *axis, SGaxisdialog *dialog)
{
  GtkPlot *plot;
  GtkWidget *main_box;
  GtkWidget *frame;
  GtkWidget *label;
  GtkWidget *box;
  GtkWidget *table;
  GtkWidget *align;
  GtkWidget *button;
  GtkRequisition req;
  GtkAdjustment *adj;
  gchar text[20];
  gchar *title[2];
  static  gboolean h, v;
  gchar *titles[3][2] = {{"bottom", "top"}, 
                         {"left", "right"}, 
                         {"front", "back"}};
  gchar *titles3d[3][2] = {{"XY", "XZ"}, {"YX", "YZ"}, {"ZX", "ZY"}};
  gchar *grids[] = {"Vertical", "Horizontal", "Z"};
  gchar *origin[] = {"X", "Y", ""};
  gint table_y=0;

  dialog->layer = layer;
  dialog->plot = (SGplot *)layer->parent;
  plot = GTK_PLOT(layer->real_plot);
  dialog->orientation = axis->orientation;
  dialog->axis = axis;

  if(layer->type == SG_LAYER_3D){
    title[0] = titles3d[dialog->orientation][0];
    title[1] = titles3d[dialog->orientation][1];
  } else {
    title[0] = titles[dialog->orientation][0];
    title[1] = titles[dialog->orientation][1];
  }

  switch(dialog->orientation){
    case GTK_PLOT_AXIS_X:
      dialog->ticks = &plot->bottom->ticks;
      if(layer->type != SG_LAYER_3D){
        dialog->axis1 = plot->bottom;
        dialog->axis2 = plot->top;
      } else {
        dialog->axis1 = &GTK_PLOT3D(plot)->xy;
        dialog->axis2 = &GTK_PLOT3D(plot)->xz;
      }
      break;
    case GTK_PLOT_AXIS_Y:
      dialog->ticks = &plot->left->ticks;
      if(layer->type != SG_LAYER_3D){
        dialog->axis1 = plot->left;
        dialog->axis2 = plot->right;
      } else {
        dialog->axis1 = &GTK_PLOT3D(plot)->yx;
        dialog->axis2 = &GTK_PLOT3D(plot)->yz;
      }
      break;
    case GTK_PLOT_AXIS_Z:
      dialog->ticks = &plot->top->ticks;
      dialog->axis1 = &GTK_PLOT3D(plot)->zx;
      dialog->axis2 = &GTK_PLOT3D(plot)->zy;
      break;
  }

  /* Create widgets */
  main_box = gtk_hbox_new (FALSE,5);
  gtk_container_set_border_width(GTK_CONTAINER(main_box), 10);

  frame = gtk_frame_new("Scale");
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start (GTK_BOX (main_box), frame, FALSE, FALSE, 0);

  box = gtk_vbox_new(FALSE, 5);
  gtk_container_add (GTK_CONTAINER (frame), box);
 
  table = gtk_table_new(9,3,FALSE);
  gtk_container_set_border_width(GTK_CONTAINER(table), 5);
  gtk_box_pack_start(GTK_BOX(box), table, FALSE, FALSE, 0);
  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
  gtk_table_set_row_spacings(GTK_TABLE(table), 10);

  label = gtk_label_new("From:");
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 

  dialog->from_entry = gtk_entry_new();
  gtk_widget_size_request(dialog->from_entry, &req);
  req.width /= 2;
  gtk_widget_set_usize(dialog->from_entry, req.width, req.height);
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->from_entry, 1, 2, table_y, table_y+1); 
  /*sg_entry_set_numeric(GTK_ENTRY(dialog->from_entry), 15);*/

  button=gtk_button_new_with_label("Get min...");
  gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, table_y, table_y+1); 
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (insert_min),
                      dialog);


  table_y++;
  label = gtk_label_new("To:");
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
  dialog->to_entry = gtk_entry_new();
  gtk_widget_set_usize(dialog->to_entry, req.width, req.height);
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->to_entry, 1, 2,table_y, table_y+1); 
/*  sg_entry_set_numeric(GTK_ENTRY(dialog->to_entry), 15);*/

  button=gtk_button_new_with_label("Get max...");
  gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, table_y, table_y+1); 
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (insert_max),
                      dialog);


  table_y++;
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 3, table_y, table_y+1); 

  table_y++;
  label = gtk_label_new("Major tick interval:");
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
  dialog->major_entry = gtk_entry_new();
  gtk_widget_set_usize(dialog->major_entry, req.width, req.height);
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->major_entry, 1, 2, table_y, table_y+1); 
/*  sg_entry_set_numeric(GTK_ENTRY(dialog->major_entry), 15);*/

  button=gtk_button_new_with_label("Get from #");
  gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, table_y, table_y+1); 
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (insert_interval),
                      dialog);
  gtk_widget_set_sensitive(button, FALSE);


  table_y++;
  label = gtk_label_new("# Major ticks:");
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
  adj = (GtkAdjustment *)gtk_adjustment_new(0., 0., 100., 1., 1., 0.);

  dialog->major_spin = gtk_spin_button_new(adj, 0, 0);
  gtk_widget_set_usize(dialog->major_spin, req.width, req.height);
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->major_spin, 1, 2, table_y, table_y+1); 
  gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->major_spin), TRUE);
  gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->major_spin), 0);
  gtk_signal_connect (GTK_OBJECT (adj), "value-changed",
                      GTK_SIGNAL_FUNC (spin_major_changed),
                      button);
  gtk_signal_connect (GTK_OBJECT (dialog->from_entry), "changed",
                      GTK_SIGNAL_FUNC (spin_major_changed),
                      button);
  gtk_signal_connect (GTK_OBJECT (dialog->to_entry), "changed",
                      GTK_SIGNAL_FUNC (spin_major_changed),
                      button);
  gtk_signal_connect (GTK_OBJECT (dialog->major_entry), "changed",
                      GTK_SIGNAL_FUNC (spin_major_changed),
                      button);

  table_y++;
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 3, table_y, table_y+1); 

  table_y++;
  label = gtk_label_new("# Minor ticks:");
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
  adj = (GtkAdjustment *)gtk_adjustment_new(0., 0., 100., 1., 1., 0.);

  dialog->minor_spin = gtk_spin_button_new(adj, 0, 0);
  gtk_widget_set_usize(dialog->minor_spin, req.width, req.height);
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->minor_spin, 1, 2, table_y, table_y+1); 
  gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->minor_spin), TRUE);
  gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->minor_spin), 0);

  table_y++;
  if(dialog->layer->type != SG_LAYER_3D){
    label = gtk_label_new("1st tick:");
    gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
    dialog->first_entry = gtk_entry_new();
    gtk_widget_set_usize(dialog->first_entry, req.width, req.height);
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->first_entry, 1, 2, table_y, table_y+1); 
/*    sg_entry_set_numeric(GTK_ENTRY(dialog->first_entry), 15);*/

    table_y++;
    label = gtk_label_new("last tick:");
    gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
    dialog->last_entry = gtk_entry_new();
    gtk_widget_set_usize(dialog->last_entry, req.width, req.height);
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->last_entry, 1, 2, table_y, table_y+1); 
/*    sg_entry_set_numeric(GTK_ENTRY(dialog->last_entry), 15);*/

    table_y++;
    gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 3, table_y, table_y+1); 

    table_y++;
    label = gtk_label_new("Type:");
    gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
    dialog->scale_combo = gtk_combo_new();
    gtk_widget_set_usize(dialog->scale_combo, req.width, req.height);
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->scale_combo, 1, 3, table_y, table_y+1); 
    gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(dialog->scale_combo)->entry), FALSE);

    sg_combo_set_items(GTK_COMBO(dialog->scale_combo), scale);

    gtk_list_select_item(GTK_LIST(GTK_COMBO(dialog->scale_combo)->list),
                       axis->scale);

    table_y++;
    label = gtk_label_new("Autoscale type:");
    gtk_misc_set_alignment(GTK_MISC(label), 1., 0.);
    gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, table_y, table_y+1); 
    dialog->rescale_combo = gtk_combo_new();
    gtk_widget_set_usize(dialog->rescale_combo, req.width, req.height);
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->rescale_combo, 1, 3, table_y, table_y+1); 
    gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(dialog->rescale_combo)->entry), FALSE);

    sg_combo_set_items(GTK_COMBO(dialog->rescale_combo), rescale);

    gtk_list_select_item(GTK_LIST(GTK_COMBO(dialog->rescale_combo)->list),
                         layer->rescale);
  }

/***************************************************************************/
  frame = gtk_frame_new("Display");
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start (GTK_BOX (main_box), frame, FALSE, FALSE, 0);

  box = gtk_vbox_new(FALSE, 2);
  gtk_container_add (GTK_CONTAINER (frame), box);

  table = gtk_table_new(8,6,FALSE);
  gtk_container_set_border_width(GTK_CONTAINER(table), 5);
  gtk_box_pack_start(GTK_BOX(box), table, FALSE, FALSE, 0);
  gtk_table_set_col_spacings(GTK_TABLE(table), 2);
  gtk_table_set_row_spacings(GTK_TABLE(table), 2);

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new(title[0]),1,3,0,1);
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new(title[1]),3,5,0,1);

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 5, 1, 2); 

  if(dialog->layer->type != SG_LAYER_3D){
    gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Axis"),0,1,2,3);

    align = gtk_alignment_new(.5, 0., 0., 0.);
    dialog->axis_1 = gtk_check_item_new();
    gtk_container_add(GTK_CONTAINER(align), dialog->axis_1);
    gtk_table_attach_defaults(GTK_TABLE(table),align,1,3,2,3);
    align = gtk_alignment_new(.5, 0., 0., 0.);
    dialog->axis_2 = gtk_check_item_new();
    gtk_container_add(GTK_CONTAINER(align), dialog->axis_2);
    gtk_table_attach_defaults(GTK_TABLE(table),align,3,5,2,3);
  }
 
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Ticks labels"),0,1,3,4);

  align = gtk_alignment_new(.5, 0., 0., 0.);
  dialog->labels_1 = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->labels_1);
  gtk_table_attach_defaults(GTK_TABLE(table),align,1,3,3,4);
  align = gtk_alignment_new(.5, 0., 0., 0.);
  dialog->labels_2 = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->labels_2);
  gtk_table_attach_defaults(GTK_TABLE(table),align,3,5,3,4);

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Titles"),0,1,4,5);

  align = gtk_alignment_new(.5, 0., 0., 0.);
  dialog->titles_1 = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->titles_1);
  gtk_table_attach_defaults(GTK_TABLE(table),align,1,3,4,5);
  align = gtk_alignment_new(.5, 0., 0., 0.);
  dialog->titles_2 = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->titles_2);
  gtk_table_attach_defaults(GTK_TABLE(table),align,3,5,4,5);



  gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 5, 5, 6); 

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Ticks"),0,1,6,7);

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("out"),1,2,6,7);
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("in"),2,3,6,7);
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("out"),3,4,6,7);
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("in"),4,5,6,7);

  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Major"),0,1,7,8);
  gtk_table_attach_defaults(GTK_TABLE(table),gtk_label_new("Minor"),0,1,8,9);


  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->major_1_out = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->major_1_out);
  gtk_table_attach_defaults(GTK_TABLE(table),align,1,2,7,8);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->major_1_in = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->major_1_in);
  gtk_table_attach_defaults(GTK_TABLE(table),align,2,3,7,8);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->major_2_out = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->major_2_out);
  gtk_table_attach_defaults(GTK_TABLE(table),align,3,4,7,8);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->major_2_in = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->major_2_in);
  gtk_table_attach_defaults(GTK_TABLE(table),align,4,5,7,8);

  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->minor_1_out = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->minor_1_out);
  gtk_table_attach_defaults(GTK_TABLE(table),align,1,2,8,9);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->minor_1_in = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->minor_1_in);
  gtk_table_attach_defaults(GTK_TABLE(table),align,2,3,8,9);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->minor_2_out = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->minor_2_out);
  gtk_table_attach_defaults(GTK_TABLE(table),align,3,4,8,9);
  align = gtk_alignment_new(1., 0., 0., 0.);
  dialog->minor_2_in = gtk_check_item_new();
  gtk_container_add(GTK_CONTAINER(align), dialog->minor_2_in);
  gtk_table_attach_defaults(GTK_TABLE(table),align,4,5,8,9);

  gtk_box_pack_start(GTK_BOX(box), gtk_hseparator_new(), FALSE, FALSE, 0);

  table = gtk_table_new(5,2,FALSE);
  gtk_container_set_border_width(GTK_CONTAINER(table), 5);
  gtk_box_pack_start(GTK_BOX(box), table, FALSE, FALSE, 0);
  gtk_table_set_col_spacings(GTK_TABLE(table), 2);
  gtk_table_set_row_spacings(GTK_TABLE(table), 2);

  sprintf(text,"%s %s",grids[axis->orientation], "Grids");

  gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(text),0,2,0,1);

  dialog->major_grids = gtk_check_item_new_with_label("major");
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->major_grids,0,1,1,2);

  dialog->minor_grids = gtk_check_item_new_with_label("minor");
  gtk_table_attach_defaults(GTK_TABLE(table), dialog->minor_grids,1,2,1,2);

  if(dialog->layer->type != SG_LAYER_3D){
    gtk_table_attach_defaults(GTK_TABLE(table),gtk_hseparator_new(), 0, 4, 2, 3); 

    gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new("Aditional lines"),0,4,3,4);

    dialog->opposite = gtk_check_item_new_with_label("opposite");
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->opposite,0,1,4,5);

    sprintf(text,"%s %s",origin[axis->orientation], "=0");

    dialog->origin = gtk_check_item_new_with_label(text);
    gtk_table_attach_defaults(GTK_TABLE(table), dialog->origin,1,2,4,5);
  }

  /* Show widgets */
  gtk_widget_show_all (main_box);

  init_dialog(dialog);

  return (main_box);
}


GtkWidget *
sg_axis_dialog_new(SGlayer *layer)
{
  GtkWidget *dialog;
  GtkWidget *notebook;
  GtkPlot *plot;
  gdouble xmin,xmax,ymin,ymax;
  gchar *titles[3][3] = {{"X axis", "Y axis", ""},
                         {"X axis", "Y axis", "Z axis"},
                         {"A axis", "R axis", ""}};
  notebook = gtk_notebook_new();


  plot = GTK_PLOT(layer->real_plot);
  sg_layer_min_max(layer,&xmin,&xmax,&ymin,&ymax);

  dialog = sg_build_axis_dialog(layer, plot->bottom, &axis_dialog[0]);
  axis_dialog[0].min=xmin;
  axis_dialog[0].max=xmax;
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dialog,
                           gtk_label_new(titles[layer->type][0]));
  dialog = sg_build_axis_dialog(layer, plot->left, &axis_dialog[1]);
  axis_dialog[1].min=ymin;
  axis_dialog[1].max=ymax;

  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dialog,
                           gtk_label_new(titles[layer->type][1]));

  if(GTK_IS_PLOT3D(plot)){
    dialog = sg_build_axis_dialog(layer, plot->top, &axis_dialog[2]);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dialog,
                             gtk_label_new(titles[layer->type][2]));
  }

  return notebook;
}


syntax highlighted by Code2HTML, v. 0.9.1