/*  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_layer_control.h"
#include "sg.h"
#include "sg_dialogs.h"
#include "sg_stock.h"
#include "../pixmaps/pixmaps.h"

#define LABEL_LEN 1000

typedef struct
{
    gint type;
    gpointer data;
    void (* action) (gpointer object);

    gchar *path;

} SGnodedata;

static GtkWidget *layer_control_dialog = NULL;
static GtkWidget *dialog;
static GtkWidget *paned;
static GtkWidget *swindow;
static GtkWidget *main_frame;
static GtkWidget *label;
static GtkWidget *tree;
static GtkWidget *window = NULL;
static GdkPixmap *layer_pixmap;
static GdkPixmap *plot2d_pixmap;
static GdkPixmap *plot3d_pixmap;
static GdkPixmap *polar_pixmap;
static GdkBitmap *layer_mask;
static GdkBitmap *plot2d_mask;
static GdkBitmap *plot3d_mask;
static GdkBitmap *polar_mask;
static GList *nodes;

static void 		(* update_function) 	(GtkWidget *widget);
static gboolean 	mw_destroy		(GtkWidget *widget);
static void 		build_tree		(SGplot *plot);
static void 		expand_tree		(gchar *path);
static void 		open_dialog		(GtkCTree *tree, 
						 GtkCTreeNode *node, 
						 gint column);


void 
sg_layer_control_destroy()
{
    if (layer_control_dialog) mw_destroy(window);
}

static gboolean
mw_destroy(GtkWidget *widget)
{
  GList *list;
  GtkCTreeNode *node;
  SGnodedata *data;

  sg_dialog_kill(widget);
  gtk_widget_destroy(widget);

  list = nodes;
  while(list){
     node = (GtkCTreeNode *) list->data;
     data = (SGnodedata *)gtk_ctree_node_get_row_data(GTK_CTREE(tree), node);
     g_free(data->path);
     g_free(data);
     nodes = g_list_remove_link(nodes, list);
     g_list_free_1(list);
     list = nodes;
  }

  layer_control_dialog = NULL;

  return FALSE;
}

static void
clear_paned(GtkWidget *widget, gpointer data)
{
  if(GTK_BIN(main_frame)->child != NULL) 
             gtk_widget_destroy(GTK_BIN(main_frame)->child);

}

static void
destroy_dialog(GtkWidget *widget, gpointer data)
{
  clear_paned(NULL, NULL);
  gtk_widget_destroy(GTK_WIDGET(data));
}

static void
button_press_apply(GtkWidget *widget, gpointer data)
{
  sg_project_changed(TRUE);

  if(update_function)
           update_function(dialog);
}

static void
button_press_ok(GtkWidget *widget, gpointer data)
{
  button_press_apply(widget, data);
  destroy_dialog(widget, data);
}

void
sg_layer_control_refresh(gchar *path)
{
  GList *list;
  GtkCTreeNode *node;
  SGnodedata *data;

  if(!layer_control_dialog) return;

  list = nodes;
  while(list){
     node = (GtkCTreeNode *) list->data;
     data = (SGnodedata *)gtk_ctree_node_get_row_data(GTK_CTREE(tree), node);
     g_free(data->path);
     g_free(data);
     nodes = g_list_remove_link(nodes, list);
     g_list_free_1(list);
     list = nodes;
  }

  gtk_container_remove(GTK_CONTAINER(swindow), tree);

  tree = gtk_ctree_new(1, 0);
  gtk_clist_set_row_height (GTK_CLIST (tree), 19);
  gtk_clist_set_column_auto_resize(GTK_CLIST(tree),0,TRUE);
  gtk_clist_set_selection_mode(GTK_CLIST(tree),GTK_SELECTION_SINGLE);
  gtk_ctree_set_line_style(GTK_CTREE(tree),GTK_CTREE_LINES_DOTTED);
  gtk_container_add(GTK_CONTAINER(swindow), tree);

  list = plots;
  while(list){
    SGplot *plot;

    plot = (SGplot *) list->data;

    build_tree(plot);    

    list = list->next;
  }

  /* connect signals */
  gtk_signal_connect(GTK_OBJECT(tree), "tree_select_row",
                     (GtkSignalFunc)open_dialog,
                     NULL);

  expand_tree(path);
  gtk_widget_show(tree);
}

static void
new_dataset_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_data_dialog_update_plot;
  dialog = sg_data_dialog_new((SGlayer*)p_layer);
  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Add/remove datasets");
}

static void
new_planes_dialog(gpointer p_layer)
{
  clear_paned(NULL, NULL);

  update_function = sg_planes_dialog_update_plot;

  dialog = sg_planes_dialog_new((SGlayer *)p_layer);
  gtk_container_add(GTK_CONTAINER(main_frame), dialog);
  gtk_widget_show_all(dialog);
  gtk_label_set_text(GTK_LABEL(label), "Edit planes properties");
}

static void
new_axis_dialog(gpointer p_layer)
{
  clear_paned(NULL, NULL);

  update_function = sg_axis_dialog_update_plot;

  dialog = sg_axis_dialog_new((SGlayer *)p_layer);
  gtk_container_add(GTK_CONTAINER(main_frame), dialog);
  gtk_widget_show_all(dialog);
  gtk_label_set_text(GTK_LABEL(label), "Edit axes properties");
}

static void
new_title_dialog(gpointer p_layer)
{
  clear_paned(NULL, NULL);

  update_function = sg_title_dialog_update_plot;

  dialog = sg_title_dialog_new((SGlayer *)p_layer);
  gtk_container_add(GTK_CONTAINER(main_frame), dialog);
  gtk_widget_show_all(dialog);
  gtk_label_set_text(GTK_LABEL(label), "Edit titles properties");
}

static void
new_grids_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_grids_dialog_update_plot;
  dialog = sg_grids_dialog_new((SGlayer *)p_layer);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit grids properties");
}


static void
new_legends_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_legends_dialog_update_plot;
  dialog = sg_legends_dialog_new((SGlayer *)p_layer);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit legends properties");
}

static void
new_labels_dialog(gpointer p_layer)
{
  clear_paned(NULL, NULL);

  update_function = sg_labels_dialog_update_plot;


  dialog = sg_labels_dialog_new((SGlayer *)p_layer);
  gtk_container_add(GTK_CONTAINER(main_frame), dialog);
  gtk_widget_show_all(main_frame);
  gtk_label_set_text(GTK_LABEL(label), "Edit labels properties");
}

static void
new_frame_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_frame_dialog_update_plot;
  dialog = sg_frame_dialog_new((SGlayer *)p_layer);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit frame properties");
}

static void
new_page_dialog(gpointer p_plot)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_page_dialog_update_plot;
  dialog = sg_page_dialog_new((SGplot *)p_plot);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit page properties");
}

static void
new_style_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);


  if(!((SGlayer *)p_layer)->datasets){
    dialog = gtk_label_new("This layer contains no datasets");
    update_function = NULL;
  } else {
    update_function = sg_style_dialog_update_plot;
    dialog = sg_style_dialog_new((SGlayer *)p_layer);
  }

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit dataset properties");
}

static void
new_layer_dialog(gpointer p_layer)
{
  GtkWidget *frame;

  clear_paned(NULL, NULL);

  update_function = sg_layer_dialog_update_plot;
  dialog = sg_layer_dialog_new((SGlayer *)p_layer);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(main_frame), frame);
  gtk_container_add(GTK_CONTAINER(frame), dialog);
  gtk_widget_show_all(frame);

  gtk_label_set_text(GTK_LABEL(label), "Edit layer properties");
}

static void
open_dialog(GtkCTree *tree, GtkCTreeNode *node, gint column)
{
  SGnodedata *nodedata;
  gpointer data;

  data = gtk_ctree_node_get_row_data(tree, node);
  if(data == NULL) return;

  nodedata = (SGnodedata *)data;
  if(nodedata->action == NULL) return;

  nodedata->action(nodedata->data);
}

SGnodedata *
sg_node_data_new(gint type, gpointer data, void (*action)(gpointer), gchar *path)
{
  SGnodedata *node;

  node = g_new(SGnodedata, 1);
 
  node->type = type;
  node->data = data;
  node->action = action;
  node->path = g_strdup(path);

  return node;
}
  
static void
build_tree(SGplot *plot)
{
  GtkCTreeNode *root_item, *item, *subitem, *subsubitem;
  GList *list;
  gchar *title[1];
  gchar *subtitle[1];
  gchar label[1000];
  gint n = 0;
  gchar path[1000];
  gchar *text[20] = {"Legends",
                     "Axes",
                     "Titles",
                     "Ticks Labels",
                     "Frame",
                     "Grids",
                     "Datasets",
                     "Properties",
                     "Planes",};

  title[0] = plot->name;

  root_item = gtk_ctree_insert_node(GTK_CTREE(tree), NULL, NULL, 
                                    &title[0],
                                    4, layer_pixmap, layer_mask, 
                                    layer_pixmap, layer_mask, FALSE, FALSE);
  gtk_ctree_node_set_row_data(GTK_CTREE(tree), root_item, 
                              sg_node_data_new(1, plot, 
                              new_page_dialog, plot->name));
  nodes = g_list_append(nodes, root_item);

  list = plot->layers;
  while(list){
    SGlayer *layer;

    layer = (SGlayer *)list->data;

    g_snprintf(label, LABEL_LEN, "%s:%i",title[0],++n);
    subtitle[0] = g_strdup(label);
  
    switch(layer->type){
      case SG_LAYER_2D: 
        item = gtk_ctree_insert_node(GTK_CTREE(tree), root_item, NULL, 
                                     &subtitle[0],
                                     4, plot2d_pixmap, plot2d_mask, 
                                     plot2d_pixmap, plot2d_mask, FALSE, FALSE);
        break;
      case SG_LAYER_3D: 
        item = gtk_ctree_insert_node(GTK_CTREE(tree), root_item, NULL, 
                                     &subtitle[0],
                                     4, plot3d_pixmap, plot3d_mask, 
                                     plot3d_pixmap, plot3d_mask, FALSE, FALSE);
        break;
      case SG_LAYER_POLAR: 
        item = gtk_ctree_insert_node(GTK_CTREE(tree), root_item, NULL, 
                                     &subtitle[0],
                                     4, polar_pixmap, polar_mask, 
                                     polar_pixmap, polar_mask, FALSE, FALSE);
        break;
    }

    gtk_ctree_node_set_row_data(GTK_CTREE(tree), item, 
                                sg_node_data_new(2, list->data, 
                                new_layer_dialog, label));
    nodes = g_list_append(nodes, item);

    g_free(subtitle[0]);

    g_snprintf(path, LABEL_LEN, "%s:%s",label, "frame");
    subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                    &text[4],
                                    4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                sg_node_data_new(2, list->data, 
                                new_frame_dialog, path));
    nodes = g_list_append(nodes, subitem);

    if(layer->type == SG_LAYER_3D){
      g_snprintf(path, LABEL_LEN, "%s:%s",label, "planes");
      subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                      &text[8],
                                      4, NULL, NULL, NULL, NULL, FALSE, FALSE);
      gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                  sg_node_data_new(2, list->data, 
                                  new_planes_dialog, path));

      nodes = g_list_append(nodes, subitem);
    }
  
    g_snprintf(path, LABEL_LEN, "%s:%s",label, "grids");
    subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                    &text[5],
                                    4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                sg_node_data_new(2, list->data, 
                                new_grids_dialog, path));
    nodes = g_list_append(nodes, subitem);

    g_snprintf(path, LABEL_LEN, "%s:%s",label, "legends");
    subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                    &text[0],
                                    4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                sg_node_data_new(2, list->data, 
                                new_legends_dialog, path));
    nodes = g_list_append(nodes, subitem);

    g_snprintf(path, LABEL_LEN, "%s:%s",label, "axis");
    subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                    &text[1],
                                    4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                sg_node_data_new(2, list->data, 
                                new_axis_dialog, path));
    nodes = g_list_append(nodes, subitem);
  
  
    g_snprintf(path, LABEL_LEN, "%s:%s",label, "axis:title");
    subsubitem = gtk_ctree_insert_node(GTK_CTREE(tree), subitem, NULL, 
                                       &text[2],
                                       4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subsubitem, 
                                sg_node_data_new(2, list->data, 
                                new_title_dialog, path));
    nodes = g_list_append(nodes, subsubitem);
    g_snprintf(path, LABEL_LEN, "%s:%s",label, "axis:labels");
    subsubitem = gtk_ctree_insert_node(GTK_CTREE(tree), subitem, NULL, 
                                       &text[3],
                                       4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subsubitem, 
                                sg_node_data_new(2, list->data, 
                                new_labels_dialog, path));
    nodes = g_list_append(nodes, subsubitem);
  
    g_snprintf(path, LABEL_LEN, "%s:%s",label, "dataset");
    subitem = gtk_ctree_insert_node(GTK_CTREE(tree), item, NULL, 
                                    &text[6],
                                    4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subitem, 
                                sg_node_data_new(2, list->data, 
                                new_dataset_dialog, path));
    nodes = g_list_append(nodes, subitem);

    g_snprintf(path, LABEL_LEN, "%s:%s",label, "dataset:style");
    subsubitem = gtk_ctree_insert_node(GTK_CTREE(tree), subitem, NULL, 
                                       &text[7],
                                       4, NULL, NULL, NULL, NULL, FALSE, FALSE);
    gtk_ctree_node_set_row_data(GTK_CTREE(tree), subsubitem, 
                                sg_node_data_new(2, list->data, 
                                new_style_dialog, path));
    nodes = g_list_append(nodes, subsubitem);

    list = list->next;
  }

}

static GtkCTreeNode * 
find_node_by_path(gchar *path)
{
  GList *list;
  gchar *node_path;
  GtkCTreeNode *node;
  SGnodedata *data;

  node_path = NULL;

  list = nodes;
  while(list){
     node = (GtkCTreeNode *) list->data;
     data = (SGnodedata *)gtk_ctree_node_get_row_data(GTK_CTREE(tree), node);

     node_path = data->path;
     if(strcmp(node_path, path) == 0) return node;

     list = list->next;
  } 

  return NULL;
}


static void
expand_tree(gchar *path)
{
  GtkCTreeNode *node;
  gchar *c; 
  gchar sub_node[1000];
  gint nlen;

  if(path == NULL) return;

  node = NULL;
  c = path;
  nlen = 0;

  while(*c != '\0' && *c != '\n' && c != NULL){
    if(*c == ':'){
      node = find_node_by_path(sub_node);
      if(node) gtk_ctree_expand(GTK_CTREE(tree), node);
    }
    nlen++;
    sub_node[nlen-1] = *c;
    sub_node[nlen]='\0';
    c++;
  } 

  node = find_node_by_path(sub_node);
  if(node) {
     gtk_ctree_expand(GTK_CTREE(tree), node);
     gtk_ctree_select(GTK_CTREE(tree), node);
  }
}


void
sg_layer_control (gchar *path)
{
  GtkWidget *main_box;
  GtkWidget *frame;
  GtkWidget *action_area;
  GtkWidget *right_box;
  GtkWidget *right_sub_box;
  GtkWidget *ok_button, *apply_button, *cancel_button;
  GList *list;
  SGplot *plot;

  if(layer_control_dialog){
      gdk_window_raise(layer_control_dialog->window);
      return;
  }

  nodes = NULL;

  layer_control_dialog = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width(GTK_CONTAINER(window), 2);
  gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);

  gtk_window_set_title (GTK_WINDOW(window),"Layer Control");

  sg_dialog_new(window);

  /* Create widgets */
  main_box = gtk_vbox_new(FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), main_box);

  paned = gtk_hpaned_new();
  gtk_paned_set_gutter_size (GTK_PANED(paned), 10);
  gtk_paned_set_position (GTK_PANED(paned), 150);
  gtk_box_pack_start (GTK_BOX(main_box), paned, TRUE, TRUE, 0);

  swindow = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow),
                                 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
  gtk_widget_set_usize(swindow, 200, 120);

  gtk_paned_pack1(GTK_PANED(paned), swindow, FALSE, FALSE);

  tree = gtk_ctree_new(1, 0);
  gtk_clist_set_row_height (GTK_CLIST (tree), 19);
  gtk_clist_set_column_auto_resize(GTK_CLIST(tree),0,TRUE);
  gtk_clist_set_selection_mode(GTK_CLIST(tree),GTK_SELECTION_SINGLE);
  gtk_ctree_set_line_style(GTK_CTREE(tree),GTK_CTREE_LINES_DOTTED);
  gtk_container_add(GTK_CONTAINER(swindow), tree);

  layer_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
                                                 gdk_colormap_get_system(),
                                                 &layer_mask,
                                                 NULL,
                                                 layer_xpm);
  plot2d_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
                                                 gdk_colormap_get_system(),
                                                 &plot2d_mask,
                                                 NULL,
                                                 _2d_small_xpm);
  plot3d_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
                                                 gdk_colormap_get_system(),
                                                 &plot3d_mask,
                                                 NULL,
                                                 _3d_small_xpm);
  polar_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
                                                 gdk_colormap_get_system(),
                                                 &polar_mask,
                                                 NULL,
                                                 polar_small_xpm);

  list = plots;
  while(list){
    plot = (SGplot *) list->data;

    build_tree(plot);    
    list = list->next;
  }
/***************************************************/
  right_box = gtk_vbox_new(FALSE, 5);
  gtk_paned_pack2(GTK_PANED(paned), right_box, FALSE, FALSE);
  
  /* Action area */
  action_area = gtk_hbutton_box_new ();
  gtk_button_box_set_layout(GTK_BUTTON_BOX(action_area), GTK_BUTTONBOX_END);
  gtk_button_box_set_spacing(GTK_BUTTON_BOX(action_area), 5);
  gtk_box_pack_end (GTK_BOX (right_box), action_area, FALSE, FALSE, 0);
  gtk_widget_show (action_area);

  ok_button = sg_stock_button(GNOME_STOCK_BUTTON_OK);
  gtk_box_pack_start (GTK_BOX (action_area), ok_button, FALSE, FALSE, 0);
/*  
  GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (ok_button);
*/
  gtk_widget_show (ok_button);

  apply_button = sg_stock_button(GNOME_STOCK_BUTTON_APPLY);
  gtk_box_pack_start (GTK_BOX (action_area), apply_button, FALSE, FALSE, 0);
  gtk_widget_show (apply_button);


  cancel_button = sg_stock_button(GNOME_STOCK_BUTTON_CLOSE);
  gtk_box_pack_start (GTK_BOX (action_area), cancel_button, FALSE, FALSE, 0);
  gtk_widget_show (cancel_button);


  right_sub_box = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(right_box), right_sub_box, TRUE, TRUE, 0);

  main_frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(main_frame), GTK_SHADOW_IN);
  gtk_box_pack_start(GTK_BOX(right_sub_box), main_frame, TRUE, TRUE, 0);

  frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_end(GTK_BOX(main_box), frame, FALSE, FALSE, 0);

  label = gtk_label_new("Layer control"); 
  gtk_misc_set_alignment(GTK_MISC(label), 0., 0.);
  gtk_container_add(GTK_CONTAINER(frame), label);

  /* connect signals */
  gtk_signal_connect(GTK_OBJECT(tree), "tree_select_row",
                     (GtkSignalFunc)open_dialog,
                     NULL);

  gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
                      GTK_SIGNAL_FUNC (button_press_ok),
                      window);

  gtk_signal_connect (GTK_OBJECT (apply_button), "clicked",
                      GTK_SIGNAL_FUNC (button_press_apply),
                      window);

  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
                      GTK_SIGNAL_FUNC (destroy_dialog),
                      window);


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

  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                      GTK_SIGNAL_FUNC (mw_destroy),NULL);

  /* Show widgets */
  expand_tree(path);
  gtk_widget_show_all (window);

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

}



syntax highlighted by Code2HTML, v. 0.9.1