/* IglooFTP - Graphical and User Friendly FTP Client.
 * Copyright (c) 1998-1999 Jean-Marc Jacquet. 
 * All rights reserved.
 * 
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE
 *
 * IglooFTP Original Packages, information and support,  
 * can be obtained at :
 *                              http://www.littleigloo.org
 * 
 *
 */

#include <gtk/gtk.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <time.h>

#include "protos.h"
#include "site_manager.h"
#include "site_notebook.h"



/* SITE MANAGER Functions */
/*
 * PUBLIC:
 * SMAN_bookmark_site_edit
 * SMAN_bookmark_save_local_dir
 * SMAN_bookmark_save_remote_dir 
 * SMAN_bookmark_path_dialog
 * SMAN_bookmark_site_dialog
 * STATIC:
 * SMAN_bookmark_retrieve_current_local_dir
 * SMAN_bookmark_path
 * SMAN_bookmark_site
 */

void
SMAN_bookmark_site_edit (void)
{
  IS_SITE_EDITED = TRUE;
  site_notebook (current_bookmark_site, "Site Manager - Edit Site");
}

void
SMAN_bookmark_save_local_dir (void)
{
  char buf[1024];
  SMAN_bookmark_retrieve_current_local_dir (current_bookmark_site);
  current_bookmark_site->USE_DEFAULT = FALSE;
  SMAN_save_bookmarks_file ();
  sprintf (buf, "Local path for %s set to :\n%s", current_bookmark_site->name, current_bookmark_site->session.local_dir);
  alert_ok ("Bookmark Local Path", buf, "Ok");
}

void
SMAN_bookmark_save_remote_dir (void)
{
  char buf[1024];

  strcpy (current_bookmark_site->session.start_dir, this_session.cwd_dir);
  current_bookmark_site->USE_DEFAULT = FALSE;
  SMAN_save_bookmarks_file ();
  sprintf (buf, "Remote path for %s set to :\n%s", current_bookmark_site->name, current_bookmark_site->session.start_dir);
  alert_ok ("Bookmark Remote Path", buf, "Ok");
}


static void
SMAN_bookmark_retrieve_current_local_dir (MANAGERsite * this_site)
{
  char path[1024];
  if (getcwd (path, sizeof (path)) != NULL)
    strcpy (this_site->session.local_dir, path);
}

static void
SMAN_bookmark_path (GtkWidget * widget, BMKpathdlg * bmk_dlg)
{
  char MUST_SAVE = FALSE;

  if (GTK_TOGGLE_BUTTON (bmk_dlg->check_remote)->active)
    {
      strcpy (current_bookmark_site->session.start_dir, this_session.cwd_dir);
      MUST_SAVE = TRUE;
    }

  if (GTK_TOGGLE_BUTTON (bmk_dlg->check_local)->active)
    {
      SMAN_bookmark_retrieve_current_local_dir (current_bookmark_site);
      MUST_SAVE = TRUE;
    }

  if (MUST_SAVE)
    SMAN_save_bookmarks_file ();

  gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  g_free (bmk_dlg);
}

void
SMAN_bookmark_path_dialog (GtkWidget * widget, gpointer data)
{
  GtkWidget *alert_window;
  GtkWidget *alert_vbox;
  GtkWidget *alert_vbox1;
  GtkWidget *alert_hbox;
  GtkWidget *alert_frame;
  GtkWidget *alert_button;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  BMKpathdlg *bmk_dlg = g_malloc0 (sizeof (BMKpathdlg));

  pixmap = man_site_pixmap (&mask);

  alert_window = create_dialog_window (GTK_WINDOW_DIALOG, GTK_WIN_POS_CENTER, "Bookmark Path", &alert_vbox);

  alert_vbox1 = v_box (alert_vbox, FALSE, 5, 10);
  alert_hbox = h_box (alert_vbox1, FALSE, 7, 0);
  gtk_box_pack_start (GTK_BOX (alert_hbox), gtk_pixmap_new (pixmap, mask), FALSE, TRUE, 0);
  create_alert_label (alert_hbox, current_bookmark_site->name, 0, 0.5);
  gdk_pixmap_unref (pixmap);
  gdk_pixmap_unref (mask);

  hseparator (alert_vbox);

  alert_frame = create_frame (alert_vbox, " Save : ", FALSE, TRUE, GTK_SHADOW_ETCHED_IN);
  gtk_container_border_width (GTK_CONTAINER (alert_frame), 10);
  alert_vbox1 = v_box (alert_frame, FALSE, 10, 0);
  gtk_container_border_width (GTK_CONTAINER (alert_vbox1), 20);


  bmk_dlg->check_local = gtk_check_button_new_with_label (" Local Dir");
  bmk_dlg->check_remote = gtk_check_button_new_with_label (" Remote Dir");
  gtk_box_pack_start (GTK_BOX (alert_vbox1), bmk_dlg->check_remote, FALSE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (alert_vbox1), bmk_dlg->check_local, FALSE, TRUE, 0);
  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (bmk_dlg->check_remote), TRUE);

  hseparator (alert_vbox);

  alert_hbox = h_box (alert_vbox, FALSE, 10, 5);
  program_icon (alert_hbox);
  alert_hbox = hbutton_box (alert_hbox);


  alert_button = box_button (alert_hbox, "Save");
  gtk_signal_connect (GTK_OBJECT (alert_button), "clicked", GTK_SIGNAL_FUNC (SMAN_bookmark_path), bmk_dlg);

  box_button_cancel_destroy_window (alert_hbox, alert_window);

  gtk_widget_show_all (alert_window);
}



static void
SMAN_bookmark_site (GtkWidget * widget, BMKsitedlg * bmk_dlg)
{
  GList *selection = GTK_CLIST (bmk_dlg->clist)->selection;
  MANAGERsite *this_site = SMAN_allocate_site_struct ();
  gchar *buf = NULL;
  int row;


  strcpy (this_site->name, gtk_entry_get_text (GTK_ENTRY (bmk_dlg->entry)));

  row = (selection == NULL) ? 0 : (int) selection->data;
  if (row)
    {
      gtk_clist_get_text (GTK_CLIST (bmk_dlg->clist), row, 1, &buf);
      this_site->parent = atoi (buf);
      this_site->parent_node = SMAN_convert_bookmark_group_index_to_node (this_site->parent);
      gtk_ctree_expand (sman_tree, this_site->parent_node);
    }
  else
    {
      this_site->parent = 0;
      this_site->parent_node = sman_book_node;
    }

  this_site->session = this_session;
  MemFrob (this_site->session.userpass, strlen (this_site->session.userpass));
  SMAN_bookmark_retrieve_current_local_dir (this_site);
  strcpy (this_site->session.start_dir, this_session.cwd_dir);
  this_site->USE_DEFAULT = FALSE;

  this_site->node = SMAN_add_site_to_tree (this_site->parent_node, this_site, booksite);
  SMAN_SITE_list = g_list_append (SMAN_SITE_list, (MANAGERsite *) this_site);
  SMAN_save_bookmarks_file ();

  gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  g_free (bmk_dlg);

  current_bookmark_site = this_site;
  USER_CONNECT_VIA_SITE_MANAGER = TRUE;
  toolbar_buttons_set_sensitive ();
  bookmark_menu_set_sensitive ();
}


void
SMAN_bookmark_site_dialog (GtkWidget * widget, gpointer data)
{
  GtkWidget *alert_window;
  GtkWidget *alert_vbox;
  GtkWidget *alert_vbox1;
  GtkWidget *alert_hbox;
  GtkWidget *alert_button;
  GtkWidget *alert_entry;
  GtkWidget *alert_clist;
  GtkWidget *alert_clist_window;
  GdkPixmap *grppix;
  GdkBitmap *grpmsk;
  GdkPixmap *grpopenpix;
  GdkBitmap *grpopenmsk;
  GList *this_list = g_list_first (SMAN_GRP_list);
  MANAGERgroup *this_group = NULL;

  int row = 0;
  gchar *col[2] =
  {" Select Parent Group : ", ""};
  char index_buf[20];

  BMKsitedlg *bmk_dlg = g_malloc0 (sizeof (BMKsitedlg));

  grppix = man_grp_pixmap (&grpmsk);
  grpopenpix = man_grp_open_pixmap (&grpopenmsk);

  alert_window = create_dialog_window (GTK_WINDOW_DIALOG, GTK_WIN_POS_CENTER, "Bookmark Site", &alert_vbox);

  alert_vbox1 = v_box (alert_vbox, FALSE, 5, 10);

  create_alert_label (alert_vbox1, "Site Name :", 0, 0.5);

  bmk_dlg->entry = alert_entry = gtk_entry_new ();
  gtk_widget_show (alert_entry);
  gtk_entry_set_text (GTK_ENTRY (alert_entry), this_connexion.hostname);
  gtk_box_pack_start (GTK_BOX (alert_vbox1), alert_entry, FALSE, TRUE, 0);


  bmk_dlg->clist = alert_clist = gtk_clist_new_with_titles (2, col);
  gtk_clist_column_titles_show (GTK_CLIST (alert_clist));
  gtk_clist_set_column_visibility (GTK_CLIST (alert_clist), 1, FALSE);
  gtk_clist_set_row_height (GTK_CLIST (alert_clist), 16);
  gtk_clist_set_selection_mode (GTK_CLIST (alert_clist), GTK_SELECTION_SINGLE);


  alert_clist_window = scroll_win ();
  gtk_container_add (GTK_CONTAINER (alert_clist_window), alert_clist);
  gtk_box_pack_start (GTK_BOX (alert_vbox1), alert_clist_window, FALSE, TRUE, 0);
  gtk_widget_set_usize (alert_clist_window, 300, 150);

  col[0] = "Bookmarked FTP Sites";
  gtk_clist_insert (GTK_CLIST (alert_clist), row, col);
  gtk_clist_set_foreground (GTK_CLIST (alert_clist), row, &LBLUE);
  gtk_clist_set_pixtext (GTK_CLIST (alert_clist), row++, 0, col[0], 5, grpopenpix, grpopenmsk);

  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      col[0] = this_group->name;
      sprintf (index_buf, "%i", this_group->index);
      col[1] = index_buf;
      gtk_clist_insert (GTK_CLIST (alert_clist), row, col);
      gtk_clist_set_foreground (GTK_CLIST (alert_clist), row, &BLUE);
      gtk_clist_set_pixtext (GTK_CLIST (alert_clist), row++, 0, this_group->name, 5, grppix, grpmsk);
      this_list = this_list->next;
    }

  gtk_clist_select_row (GTK_CLIST (alert_clist), 0, 0);

  hseparator (alert_vbox);

  alert_hbox = h_box (alert_vbox, FALSE, 10, 5);
  program_icon (alert_hbox);
  alert_hbox = hbutton_box (alert_hbox);


  alert_button = box_button (alert_hbox, "Save");
  gtk_signal_connect (GTK_OBJECT (alert_button), "clicked", GTK_SIGNAL_FUNC (SMAN_bookmark_site), bmk_dlg);

  box_button_cancel_destroy_window (alert_hbox, alert_window);

  gtk_widget_show_all (alert_window);

  gdk_pixmap_unref (grppix);
  gdk_pixmap_unref (grpmsk);
  gdk_pixmap_unref (grpopenpix);
  gdk_pixmap_unref (grpopenmsk);
}






/* DRAG & DROP */

/* STATIC :
 * SMAN_drag_data_received
 * SMAN_bookmark_site_from_url
 */

static void
SMAN_drag_data_received (GtkWidget * widget, GdkDragContext * context, gint x, gint y, GtkSelectionData * data, guint info, guint time)
{
  if (info == DND_TARGET_STRING)
    {
      if ((data->length >= 0) && (data->format == 8))
	{
	  printf ("DND [SITEMANAGER] Received \"%s\"\n", (gchar *) data->data);
	  SMAN_bookmark_site_from_url (g_strdup ((gchar *) data->data));
	  gtk_drag_finish (context, TRUE, TRUE, time);
	}
      else
	gtk_drag_finish (context, FALSE, TRUE, time);
    }
}

static void
SMAN_bookmark_site_from_url (char *this_url)
{
  MANAGERsite *this_site = SMAN_allocate_site_struct ();
  FTPsession that_session;
  char this_port[256];
  char this_file[256];
  char this_type[256];
  char VALID_URL = FALSE;

  MEM0 (this_port);
  MEM0 (this_file);
  MEM0 (this_type);
  IGLOO_init_session (&that_session);
  MEM0 (that_session.username);
  MEM0 (that_session.userpass);

  VALID_URL =
    parse_ftp_url (this_url, that_session.username, that_session.userpass, that_session.hostname, this_port, that_session.start_dir, this_file, this_type);

  if (!VALID_URL
      || !strlen (that_session.hostname))
    {
      g_free (this_site);
      g_free (this_url);
      alert_ok ("Error", "Not a valid FTP URL.", "Ok");
      return;
    }


  if (strlen (this_port))
    that_session.port = atoi (this_port);

  this_site->session = that_session;

  if (!strcmp (this_site->session.userpass, user_rc.default_session.userpass))
    strcpy (this_site->session.userpass, SITE_DEFAULT_PASSWORD_TEXT);
  else
    MemFrob (this_site->session.userpass, strlen (this_site->session.userpass));

  this_site->USE_DEFAULT = (strlen (that_session.start_dir) < 1);
  strcpy (this_site->name, that_session.hostname);

  this_site->parent = 0;
  this_site->parent_node = sman_book_node;
  this_site->node = SMAN_add_site_to_tree (this_site->parent_node, this_site, booksite);

  SMAN_SITE_list = g_list_append (SMAN_SITE_list, (MANAGERsite *) this_site);
  SMAN_save_bookmarks_file ();

  g_free (this_url);
}



/* SITE MANAGER TREE */


/*
 *PUBLIC:
 *switch_smanager_panel
 *create_smanager
 *STATIC:
 *SMAN_add_group_to_tree
 *SMAN_add_site_to_tree
 * SMAN_build_tree
 */

void
switch_smanager_panel (void)
{
  is_smanager_visible = !is_smanager_visible;
  show_hide_widget (smanager_box, is_smanager_visible);
  hide_ftp_panel (!is_smanager_visible);
  menu_set_smanager (!is_smanager_visible);
}



GtkWidget *
create_smanager (void)
{
  GtkWidget *scrolled_win;
  GtkWidget *label;
  GtkWidget *hbox;
  GtkWidget *vbox;
  GtkWidget *button_lnk;
  GtkWidget *button_manager;
  GtkCTree *ctree = NULL;
  GtkStyle *style;
  gchar *titles[4] =
  {" Name ", " IP Address ", " Port ", " User "};
  char buf[256];

/* DND */
  static GtkTargetEntry DND_target_table[] =
  {
    {"STRING", 0, DND_TARGET_STRING}
  };



  smanager_box = gtk_vbox_new (FALSE, 0);

  label = gtk_label_new (http_version_infos (buf));
  style = gtk_style_new ();
  style->fg[GTK_STATE_NORMAL] = LBLUE;
  style->fg[GTK_STATE_INSENSITIVE] = LBLUE;
  gtk_widget_set_style (label, style);
  gtk_widget_set_sensitive (label, FALSE);
  gtk_widget_show (label);

  button_lnk = gtk_button_new ();
  gtk_button_set_relief (GTK_BUTTON (button_lnk), GTK_RELIEF_NONE);
  gtk_widget_show (button_lnk);
  gtk_widget_set_usize (button_lnk, -1, 24);

  hbox = h_box (button_lnk, FALSE, 0, 0);
  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);

  vbox = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (vbox);

  button_manager = browser_button (MANAGER_BUTTON);
  GTK_BUTTON (button_manager)->relief = GTK_RELIEF_NONE;

  gtk_box_pack_start (GTK_BOX (vbox), button_manager, FALSE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), button_lnk, TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (smanager_box), vbox, FALSE, TRUE, 0);

  sman_tree = ctree = GTK_CTREE (gtk_ctree_new_with_titles (4, 0, titles));
  gtk_widget_show (GTK_WIDGET (ctree));
  gtk_clist_set_row_height (GTK_CLIST (ctree), 18);
  gtk_clist_column_titles_passive (GTK_CLIST (ctree));
  gtk_clist_set_reorderable (GTK_CLIST (ctree), TRUE);
  gtk_clist_columns_autosize (GTK_CLIST (ctree));

  gtk_clist_set_column_min_width (GTK_CLIST (ctree), 0, 240);
  gtk_clist_set_column_min_width (GTK_CLIST (ctree), 1, 100);
  gtk_clist_set_column_min_width (GTK_CLIST (ctree), 2, 30);
  gtk_clist_set_column_min_width (GTK_CLIST (ctree), 3, 70);
  gtk_clist_set_column_justification (GTK_CLIST (ctree), 1, GTK_JUSTIFY_RIGHT);
  gtk_clist_set_column_justification (GTK_CLIST (ctree), 2, GTK_JUSTIFY_RIGHT);
  gtk_clist_set_column_justification (GTK_CLIST (ctree), 3, GTK_JUSTIFY_RIGHT);
  gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
  gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 1, TRUE);
  gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 2, TRUE);
  gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 3, TRUE);

  gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
  gtk_ctree_show_stub (ctree, TRUE);

  gtk_clist_set_hadjustment (GTK_CLIST (ctree), NULL);
  gtk_clist_set_vadjustment (GTK_CLIST (ctree), NULL);
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_widget_show (scrolled_win);
  gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));

  gtk_drag_dest_set (scrolled_win, GTK_DEST_DEFAULT_ALL, DND_target_table, 1, GDK_ACTION_COPY);
  gtk_signal_connect (GTK_OBJECT (scrolled_win), "drag_data_received",
		      GTK_SIGNAL_FUNC (SMAN_drag_data_received), NULL);


  gtk_box_pack_start (GTK_BOX (smanager_box), scrolled_win, TRUE, TRUE, 0);

  gtk_widget_show (smanager_box);
  gtk_widget_hide (smanager_box);

  sman_text = gtk_text_new (NULL, NULL);
  gtk_widget_set_name (sman_text, "SmanText");

  gtk_text_set_editable (GTK_TEXT (sman_text), FALSE);
  {
    GtkWidget *text_scrolled_win = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (text_scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_widget_show (text_scrolled_win);
    gtk_widget_set_usize (text_scrolled_win, -1, 41);
    gtk_container_add (GTK_CONTAINER (text_scrolled_win), GTK_WIDGET (sman_text));
    gtk_widget_show (sman_text);
    gtk_box_pack_start (GTK_BOX (smanager_box), text_scrolled_win, FALSE, TRUE, 0);
  }


  gtk_signal_connect (GTK_OBJECT (button_lnk), "clicked",
		 GTK_SIGNAL_FUNC (open_URL_from_widget), strdup (HOME_URL));

  gtk_signal_connect (GTK_OBJECT (button_manager), "clicked",
		      GTK_SIGNAL_FUNC (switch_smanager_panel), NULL);


  gtk_signal_connect (GTK_OBJECT (ctree), "event",
		      GTK_SIGNAL_FUNC (SMAN_tree_event_handler), NULL);

  gtk_signal_connect (GTK_OBJECT (ctree), "tree_select_row",
		      GTK_SIGNAL_FUNC (SMAN_tree_row_selected), NULL);

  gtk_signal_connect (GTK_OBJECT (ctree), "tree_expand",
    GTK_SIGNAL_FUNC (SMAN_tree_expand_or_collapse), GINT_TO_POINTER (TRUE));


  gtk_signal_connect (GTK_OBJECT (ctree), "tree_collapse",
   GTK_SIGNAL_FUNC (SMAN_tree_expand_or_collapse), GINT_TO_POINTER (FALSE));

  gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
			    GTK_SIGNAL_FUNC (SMAN_tree_node_move), NULL);

  gtk_signal_connect (GTK_OBJECT (ctree), "select_row",
		      GTK_SIGNAL_FUNC (SMAN_tree_site_selected), NULL);

  SMAN_build_tree ();

  sman_popup_menu = create_sman_popup_menu ();
  return smanager_box;
}



static GtkCTreeNode *
SMAN_add_group_to_tree (GtkCTreeNode * parent, char *groupname, char IS_OPEN, gpointer row_data, char ON_TOP)
{
  GtkCTreeNode *node = NULL;
  GtkCTreeNode *first_child_node = NULL;
  GdkPixmap *grppix;
  GdkBitmap *grpmsk;
  GdkPixmap *grpopenpix;
  GdkBitmap *grpopenmsk;
  gchar *col[4] =
  {"", "", "", ""};

  grppix = man_grp_pixmap (&grpmsk);
  grpopenpix = man_grp_open_pixmap (&grpopenmsk);

  col[0] = groupname;

  if (parent != NULL && ON_TOP)
    first_child_node = GTK_CTREE_ROW (parent)->children;

  node = gtk_ctree_insert_node (sman_tree, parent, first_child_node, col, 7, grppix, grpmsk, grpopenpix, grpopenmsk, FALSE, FALSE);

  if (IS_OPEN)
    gtk_ctree_expand (sman_tree, node);

  if (row_data != NULL)
    gtk_ctree_node_set_row_data (sman_tree, node, row_data);

  gtk_ctree_node_set_foreground (sman_tree, node, parent == NULL ? &LBLUE : &BLUE);

  gdk_pixmap_unref (grppix);
  gdk_pixmap_unref (grpmsk);
  gdk_pixmap_unref (grpopenpix);
  gdk_pixmap_unref (grpopenmsk);
  return node;
}




static GtkCTreeNode *
SMAN_add_site_to_tree (GtkCTreeNode * parent, MANAGERsite * this_site, gpointer row_data)
{
  GtkCTreeNode *node = NULL;
  GdkPixmap *sitepix;
  GdkBitmap *sitemsk;
  char col_buf[10];
  gchar *col[4] =
  {"", "", "", ""};

  sitepix = man_site_pixmap (&sitemsk);

  col[0] = this_site->name;
  col[1] = this_site->session.hostname;
  sprintf (col_buf, "%i", this_site->session.port);
  col[2] = col_buf;
  col[3] = this_site->session.username;

  node = gtk_ctree_insert_node (sman_tree, this_site->parent_node, node, col, 7, sitepix, sitemsk, sitepix, sitemsk, TRUE, FALSE);

  if (row_data != NULL)
    gtk_ctree_node_set_row_data (sman_tree, node, row_data);

  gdk_pixmap_unref (sitepix);
  gdk_pixmap_unref (sitemsk);
  return node;
}



static void
SMAN_build_tree ()
{
  GList *this_list = g_list_first (SMAN_GRP_list);
  MANAGERgroup *this_group = NULL;
  MANAGERsite *this_site = NULL;


  gtk_clist_freeze (GTK_CLIST (sman_tree));
  gtk_clist_clear (GTK_CLIST (sman_tree));
  clear_text (sman_text);

  sman_book_node = SMAN_add_group_to_tree (NULL, "Bookmarked FTP Sites", TRUE, bookroot, FALSE);



  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      if (this_group->parent == 0)
	this_group->parent_node = sman_book_node;
      else
	{
	  if ((this_group->parent_node = SMAN_convert_bookmark_group_index_to_node (this_group->parent)) == NULL)
	    this_group->parent_node = sman_book_node;
	}
      this_group->node = SMAN_add_group_to_tree (this_group->parent_node, this_group->name, this_group->is_open, bookgroup, FALSE);
      this_list = this_list->next;
    }


  this_list = g_list_first (SMAN_SITE_list);
  while (this_list != NULL)
    {
      this_site = (MANAGERsite *) this_list->data;
      if (this_site->parent == 0)
	this_site->parent_node = sman_book_node;
      else
	{
	  if ((this_site->parent_node = SMAN_convert_bookmark_group_index_to_node (this_site->parent)) == NULL)
	    this_site->parent_node = sman_book_node;
	}
      this_site->node = SMAN_add_site_to_tree (this_site->parent_node, this_site, booksite);
      this_list = this_list->next;
    }


  gtk_clist_thaw (GTK_CLIST (sman_tree));
}










/* CTREE  MANAGEMENT FUNCTIONS */

/*
   * SMAN_return_selected_node
   * SMAN_return_selected_node_parent_group
   * SMAN_tree_event_handler
   * SMAN_tree_row_selected
   * SMAN_tree_expand_or_collapse 
 */

static GtkCTreeNode *
SMAN_return_selected_node (void)
{
  GList *selection = GTK_CLIST (sman_tree)->selection;
  return (selection == NULL) ? NULL : GTK_CTREE_NODE (g_list_nth (GTK_CLIST (sman_tree)->row_list, GTK_CLIST (sman_tree)->focus_row));
}

static GtkCTreeNode *
SMAN_return_selected_node_parent_group (void)
{
  GtkCTreeNode *parent_node = SMAN_return_selected_node ();
  if (IS_BOOKMARK_SITE (parent_node))
    {
      MANAGERsite *this_site = SMAN_return_MANAGERsite_from_node (parent_node);
      parent_node = this_site->parent_node;
    }
  return parent_node;
}


static gint
SMAN_tree_event_handler (GtkWidget * widget, GdkEvent * event, gpointer data)
{
  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      switch (event->button.button)
	{
	case 3:
	  {
	    GdkEventButton *bevent = (GdkEventButton *) event;
	    GtkCTreeNode *this_node = SMAN_return_selected_node ();
	    if (this_node != NULL)
	      sman_popup_menu_set_sensitive (IS_BOOKMARK_ROOT (this_node), IS_BOOKMARK_GROUP (this_node), IS_BOOKMARK_SITE (this_node));
	    else
	      sman_popup_menu_set_sensitive (FALSE, FALSE, FALSE);
	    gtk_menu_popup (GTK_MENU (sman_popup_menu), NULL, NULL, NULL, NULL,
			    bevent->button, bevent->time);
	    return TRUE;
	  }
	  break;

	default:
	  break;
	}
      break;

    default:
      break;
    }
  return FALSE;
}



static void
SMAN_tree_site_selected (GtkWidget * widget, gint row, gint column, GdkEventButton * bevent, gpointer data)
{
  if (bevent)
    switch (bevent->type)
      {
      case GDK_2BUTTON_PRESS:
	{
	  GtkCTreeNode *this_node = SMAN_return_selected_node ();
	  MANAGERsite *this_site;
	  if (this_node == NULL)
	    return;
	  if (IS_BOOKMARK_SITE (this_node))
	    {
	      this_site = SMAN_return_MANAGERsite_from_node (this_node);
	      current_bookmark_site = this_site;
	      IGLOO_connect_from_site_manager (this_site);
	    }
	}
	break;
      default:
	break;
      }
}


static void
SMAN_tree_row_selected (GtkCTree * ctree, GtkCTreeNode * this_node, gint col, /*GdkEventButton *event, */ GtkWidget * label)
{
  char *this_comment = NULL;
  if (IS_BOOKMARK_GROUP (this_node))
    {
      MANAGERgroup *this_group = SMAN_return_MANAGERgroup_from_node (this_node);
      this_comment = this_group->comment;
    }
  if (IS_BOOKMARK_SITE (this_node))
    {
      MANAGERsite *this_site = SMAN_return_MANAGERsite_from_node (this_node);
      this_comment = this_site->comment;
    }
  clear_text (sman_text);
  if (this_comment != NULL)
    realize_text (sman_text, this_comment);
}

static void
SMAN_tree_expand_or_collapse (GtkCTree * ctree, GtkCTreeNode * this_node, /*GdkEventButton *event, */ int IS_OPEN)
{
  MANAGERgroup *this_group = SMAN_return_MANAGERgroup_from_node (this_node);
  if (!IS_BOOKMARK_GROUP (this_node))
    return;
  this_group->is_open = IS_OPEN;
}


void
SMAN_tree_node_move (GtkCTree * ctree, GtkCTreeNode * child, GtkCTreeNode * parent, GtkCTreeNode * sibling, gpointer data)
{
  if (IS_BOOKMARK_GROUP (child) || IS_BOOKMARK_SITE (child))
    {
      if (!(IS_BOOKMARK_ROOT (parent) || IS_BOOKMARK_GROUP (parent) || IS_BOOKMARK_SITE (parent)))
	gtk_ctree_move (ctree, child, sman_book_node, NULL);

      if (IS_BOOKMARK_GROUP (child))
	{
	  MANAGERgroup *this_group = SMAN_return_MANAGERgroup_from_node (child);
	  this_group->parent_node = parent;
	  this_group->parent = SMAN_convert_bookmark_group_node_to_index (this_group->parent_node);
	  SMAN_save_bookmarks_file ();
	}
      if (IS_BOOKMARK_SITE (child))
	{
	  MANAGERsite *this_site = SMAN_return_MANAGERsite_from_node (child);
	  this_site->parent_node = parent;
	  this_site->parent = SMAN_convert_bookmark_group_node_to_index (this_site->parent_node);
	  SMAN_save_bookmarks_file ();
	}
    }
}








/* GROUP FUNCTIONS */

/*
   *PUBLIC
   *SMAN_group_add_dialog 
   *SMAN_group_edit_dialog  
   *SMAN_group_delete_dialog  
   *STATIC
   *SMAN_group_add 
   *SMAN_group_edit 
   *SMAN_group_delete 
   *SMAN_delete_group_children 
 */


/* ADD */

static void
SMAN_group_add (GtkWidget * widget, GtkWidget * entry)
{
  MANAGERgroup *this_group = SMAN_allocate_group_struct ();
  GtkWidget *alert_window = gtk_widget_get_toplevel (widget);
  GtkWidget *alert_text = gtk_object_get_data (GTK_OBJECT (alert_window), "text");

  strcpy (this_group->name, gtk_entry_get_text (GTK_ENTRY (entry)));
  strcpy (this_group->comment, gtk_editable_get_chars (GTK_EDITABLE (alert_text), 0, -1));
  gtk_widget_destroy (alert_window);

  this_group->parent_node = SMAN_return_selected_node_parent_group ();
  this_group->parent = SMAN_convert_bookmark_group_node_to_index (this_group->parent_node);
  this_group->is_open = FALSE;
  this_group->index = SMAN_return_free_group_index ();

  this_group->node = SMAN_add_group_to_tree (this_group->parent_node, this_group->name, this_group->is_open, bookgroup, TRUE);
  gtk_ctree_expand (sman_tree, this_group->parent_node);

  SMAN_GRP_list = g_list_append (SMAN_GRP_list, (MANAGERgroup *) this_group);
  SMAN_save_bookmarks_file ();
}

void
SMAN_group_add_dialog (GtkWidget * widget, gpointer data)
{
  entry_text_dialog ("Add Group", "Group Name:", "Comment :", "Add", "", "", GTK_SIGNAL_FUNC (SMAN_group_add));
}


/* EDIT */

static void
SMAN_group_edit (GtkWidget * widget, GtkWidget * entry)
{
  MANAGERgroup *this_group;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  GtkWidget *alert_window = gtk_widget_get_toplevel (widget);
  GtkWidget *alert_text = gtk_object_get_data (GTK_OBJECT (alert_window), "text");
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  guint8 spacing;

  this_group = SMAN_return_MANAGERgroup_from_node (this_node);
  strcpy (this_group->name, gtk_entry_get_text (GTK_ENTRY (entry)));
  strcpy (this_group->comment, gtk_editable_get_chars (GTK_EDITABLE (alert_text), 0, -1));
  gtk_widget_destroy (alert_window);

  gtk_ctree_node_get_pixtext (sman_tree, this_node, 0, NULL, &spacing, &pixmap, &mask);
  gtk_ctree_node_set_pixtext (sman_tree, this_node, 0, this_group->name, spacing, pixmap, mask);
  clear_text (sman_text);
  realize_text (sman_text, this_group->comment);

  SMAN_save_bookmarks_file ();
}


void
SMAN_group_edit_dialog (GtkWidget * widget, gpointer data)
{
  MANAGERgroup *this_group;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  this_group = SMAN_return_MANAGERgroup_from_node (this_node);
  entry_text_dialog ("Edit Group", "Group Name:", "Comment :", "Save", this_group->name, this_group->comment, GTK_SIGNAL_FUNC (SMAN_group_edit));
}



/* DELETE */

static void
SMAN_group_delete (GtkWidget * widget, gpointer data)
{
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  gtk_ctree_remove_node (sman_tree, this_node);
  clear_text (sman_text);
  SMAN_save_bookmarks_file ();
  SMAN_CLISTS_free ();
  SMAN_parse_bookmarks_file ();
  SMAN_build_tree ();
}

void
SMAN_group_delete_dialog (void)
{
  MANAGERgroup *this_group;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  char msg_buf[256];

  this_group = SMAN_return_MANAGERgroup_from_node (this_node);
  sprintf (msg_buf, " Delete %s\nand all its content ?", this_group->name);
  alert_ok_cancel ("Delete Group", msg_buf, "Delete", GTK_SIGNAL_FUNC (SMAN_group_delete));
}








/* SITE FUNCTIONS */

/*
   *PUBLIC
   *SMAN_site_add
   *SMAN_site_edit
   *SMAN_site_delete_dialog  
   *STATIC
   *SMAN_site_delete 
 */

void
SMAN_site_add (void)
{
  MANAGERsite *this_site = SMAN_allocate_site_struct ();
  this_site->parent_node = SMAN_return_selected_node_parent_group ();
  this_site->parent = SMAN_convert_bookmark_group_node_to_index (this_site->parent_node);
  IS_SITE_EDITED = FALSE;
  site_notebook (this_site, "Site Manager - Add Site");
}

void
SMAN_site_edit (void)
{
  MANAGERsite *this_site;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  this_site = SMAN_return_MANAGERsite_from_node (this_node);
  IS_SITE_EDITED = TRUE;
  site_notebook (this_site, "Site Manager - Edit Site");
}




void
SMAN_site_duplicate (void)
{
  MANAGERsite *new_site = SMAN_allocate_site_struct ();
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  char buf[1024];

  *new_site = *SMAN_return_MANAGERsite_from_node (this_node);
  sprintf (buf, "(Copy of %s)", new_site->name);
  strncpy (new_site->name, buf, sizeof (new_site->name));

  new_site->node = SMAN_add_site_to_tree (new_site->parent_node, new_site, booksite);
  gtk_ctree_expand (sman_tree, new_site->parent_node);
  SMAN_SITE_list = g_list_append (SMAN_SITE_list, (MANAGERsite *) new_site);
  SMAN_save_bookmarks_file ();
}

static void
SMAN_site_delete (GtkWidget * widget, gpointer data)
{
  MANAGERsite *this_site;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  this_site = SMAN_return_MANAGERsite_from_node (this_node);
  gtk_ctree_remove_node (sman_tree, this_node);
  SMAN_save_bookmarks_file ();
  SMAN_SITE_list = g_list_remove (SMAN_SITE_list, (MANAGERsite *) this_site);
  g_free (this_site);
  clear_text (sman_text);
}

void
SMAN_site_delete_dialog (void)
{
  MANAGERsite *this_site;
  GtkCTreeNode *this_node = SMAN_return_selected_node ();
  char msg_buf[256];
  this_site = SMAN_return_MANAGERsite_from_node (this_node);
  sprintf (msg_buf, " Delete %s ?", this_site->name);
  alert_ok_cancel ("Delete Site", msg_buf, "Delete", GTK_SIGNAL_FUNC (SMAN_site_delete));
}



















/* GLIST MANAGEMENT FUNCTIONS */
/* STATIC :
   * SMAN_is_group_index_in_use
   * SMAN_return_free_group_index
   * SMAN_convert_bookmark_group_index_to_node 
   * SMAN_return_MANAGERgroup_from_node
   * SMAN_return_MANAGERsite_from_node 
   * SMAN_CLISTS_free
 */

static char
SMAN_is_group_index_in_use (int this_index)
{
  MANAGERgroup *this_group = NULL;
  GList *this_list = g_list_first (SMAN_GRP_list);
  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      if (this_group->index == this_index)
	return TRUE;
      this_list = this_list->next;
    }
  return FALSE;
}

static int
SMAN_return_free_group_index (void)
{
  register int f = 1;
  while (SMAN_is_group_index_in_use (f))
    f++;
  return f;
}

static GtkCTreeNode *
SMAN_convert_bookmark_group_index_to_node (int index)
{
  MANAGERgroup *this_group = NULL;
  GList *this_list = g_list_first (SMAN_GRP_list);

  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      if (this_group->index == index)
	return this_group->node;
      this_list = this_list->next;
    }
  return NULL;
}

static int
SMAN_convert_bookmark_group_node_to_index (GtkCTreeNode * node)
{
  MANAGERgroup *this_group = NULL;
  GList *this_list = g_list_first (SMAN_GRP_list);
  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      if (this_group->node == node)
	return this_group->index;
      this_list = this_list->next;
    }
  return 0;
}

static MANAGERgroup *
SMAN_return_MANAGERgroup_from_node (GtkCTreeNode * node)
{
  MANAGERgroup *this_group = NULL;
  GList *this_list = g_list_first (SMAN_GRP_list);

  while (this_list != NULL)
    {
      this_group = (MANAGERgroup *) this_list->data;
      if (this_group->node == node)
	return this_group;
      this_list = this_list->next;
    }
  return NULL;
}

static MANAGERsite *
SMAN_return_MANAGERsite_from_node (GtkCTreeNode * node)
{
  MANAGERsite *this_site = NULL;
  GList *this_list = g_list_first (SMAN_SITE_list);

  while (this_list != NULL)
    {
      this_site = (MANAGERsite *) this_list->data;
      if (this_site->node == node)
	return this_site;
      this_list = this_list->next;
    }
  return NULL;
}


static void
SMAN_CLISTS_free (void)
{
  GList *this_list = g_list_first (SMAN_GRP_list);
  while (this_list != NULL)
    {
      MANAGERgroup *this_group = (MANAGERgroup *) this_list->data;
      g_free (this_group);
      this_list = this_list->next;
    }
  this_list = g_list_first (SMAN_SITE_list);
  while (this_list != NULL)
    {
      MANAGERsite *this_site = (MANAGERsite *) this_list->data;
      g_free (this_site);
      this_list = this_list->next;
    }
}








/* IO Functions */

/* PUBLIC:
 * SMAN_parse_bookmarks_file 
 * SMAN_save_bookmarks_file 
 * STATIC:
 * SMAN_allocate_group_struct
 * SMAN_allocate_site_struct
 * SMAN_write_node_to_bookmarks_file
 *
 */

static MANAGERgroup *
SMAN_allocate_group_struct (void)
{
  MANAGERgroup *this_group;
  this_group = g_malloc0 (sizeof (MANAGERgroup));
  this_group->node = NULL;
  this_group->parent_node = NULL;
  return this_group;
}

static MANAGERsite *
SMAN_allocate_site_struct (void)
{
  MANAGERsite *this_site;
  this_site = g_malloc0 (sizeof (MANAGERsite));
  this_site->node = NULL;
  this_site->parent_node = NULL;
  this_site->session = user_rc.default_session;
  strcpy (this_site->session.userpass, SITE_DEFAULT_PASSWORD_TEXT);
  strcpy (this_site->session.local_dir, "");
  this_site->session.dmode = PASV_MODE;
  this_site->session.use_RDC = TRUE;
  this_site->USE_DEFAULT = TRUE;
  return this_site;
}

void
SMAN_parse_bookmarks_file (void)
{
  FILE *in;
  char this_path[1024];
  char this_line[SMAN_MAX_INI_LINE_LENGTH];
  int this_line_number = 0;
  char READ_GROUP = FALSE;
  char READ_SITE = FALSE;
  MANAGERgroup *this_group = NULL;
  MANAGERsite *this_site = NULL;

#define MANAGER_ERROR_ON(x) if(x) goto end_on_error;
#define FIELD_STRING strchr(this_line,'=')+1
#define FIELD_INT (int) atoi(strchr(this_line,'=')+1)

  bookmarks_path (this_path);

  if ((in = fopen (this_path, "r")) == NULL)
    return;

  g_list_free (SMAN_GRP_list);
  g_list_free (SMAN_SITE_list);
  SMAN_GRP_list = NULL;
  SMAN_SITE_list = NULL;


  while (fgets (this_line, sizeof (this_line), in) != NULL)
    {
      this_line_number++;

      if (this_line[strlen (this_line) - 1] == '\n')
	this_line[strlen (this_line) - 1] = 0;

      if (!strlen (this_line))
	continue;

      if (this_line[0] == '#')
	continue;


      /* GROUP AND SITE */

      if (strstr (this_line, "PARENT="))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) && (!READ_SITE))
	    if (READ_GROUP)
	    this_group->parent = FIELD_INT;
	  else
	    this_site->parent = FIELD_INT;
	  continue;
	}

      if (strstr (this_line, "NAME="))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) && (!READ_SITE))
	    if (READ_GROUP)
	    strcpy (this_group->name, FIELD_STRING);
	  else
	    strcpy (this_site->name, FIELD_STRING);
	  continue;
	}

      if (strstr (this_line, "COMMENT="))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) && (!READ_SITE))
	    strlf (FIELD_STRING);
	  if (READ_GROUP)
	    strcpy (this_group->comment, FIELD_STRING);
	  else
	    strcpy (this_site->comment, FIELD_STRING);
	  continue;
	}


      /* SITE ONLY */

      if (strstr (this_line, "{SITE"))
	{
	  MANAGER_ERROR_ON (READ_GROUP || READ_SITE);
	  READ_SITE = TRUE;
	  this_site = SMAN_allocate_site_struct ();
	  continue;
	}

      if (strstr (this_line, "SITE}"))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    READ_SITE = FALSE;
	  SMAN_SITE_list = g_list_append (SMAN_SITE_list, (MANAGERsite *) this_site);
	  continue;
	}

      if (strstr (this_line, "URL="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    strcpy (this_site->session.hostname, FIELD_STRING);
	  continue;
	}

      if (strstr (this_line, "USER="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    strcpy (this_site->session.username, FIELD_STRING);
	  continue;
	}

      if (strstr (this_line, "PASS="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    strcpy (this_site->session.userpass, FIELD_STRING);
	  continue;
	}

      if (strstr (this_line, "PORT="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.port = FIELD_INT;
	  continue;
	}

      /* advanced options */

      if (strstr (this_line, "REMOTEDIR="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    strcpy (this_site->session.start_dir, FIELD_STRING);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "LOCALDIR="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    strcpy (this_site->session.local_dir, FIELD_STRING);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "SYST="))
	{
	  char *ptr = FIELD_STRING;
	  register int f;
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    if (ptr != NULL)
	    {
	      for (f = 0; f < MAX_HOST_TYPE; f++)
		{
		  if (!strcmp (host_type_name[f], ptr))
		    this_site->session.host_type = f;
		}
	      this_site->USE_DEFAULT = FALSE;
	      continue;
	    }
	}

      if (strstr (this_line, "TRANSFERT="))
	{
	  char *ptr = FIELD_STRING;
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    if (ptr != NULL)
	    {
	      strupr (ptr);
	      if (strstr (ptr, "ASCII"))
		this_site->session.tmode = TYPE_ASCII;
	      if (strstr (ptr, "BIN") || strstr (ptr, "IMAGE"))
		this_site->session.tmode = TYPE_BIN;
	      if (strstr (ptr, "LOCAL"))
		this_site->session.tmode = TYPE_LOCAL;
	      this_site->USE_DEFAULT = FALSE;
	      continue;
	    }
	}

      if (strstr (this_line, "RESOLVELINKS="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.resolve_link = (FIELD_INT != FALSE);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}


      if (strstr (this_line, "RDC="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.use_RDC = (FIELD_INT != FALSE);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "PASV="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.dmode = (FIELD_INT == 0) ? SENDP_MODE : PASV_MODE;
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}


      if (strstr (this_line, "UPLOADS_FILENAME_CASE="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.uploads_filename = FIELD_INT;
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "UPLOADS_PRESERVE_PERM="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.uploads_perm = (FIELD_INT == 1);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "UPLOADS_PRESERVE_DATE="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.uploads_date = (FIELD_INT == 1);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "DOWNLOADS_FILENAME_CASE="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.downloads_filename = FIELD_INT;
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "DOWNLOADS_PRESERVE_PERM="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.downloads_perm = (FIELD_INT == 1);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}

      if (strstr (this_line, "DOWNLOADS_PRESERVE_DATE="))
	{
	  MANAGER_ERROR_ON (READ_GROUP || (!READ_SITE))
	    this_site->session.downloads_date = (FIELD_INT == 1);
	  this_site->USE_DEFAULT = FALSE;
	  continue;
	}




      /* GROUP ONLY */

      if (strstr (this_line, "{GRP"))
	{
	  MANAGER_ERROR_ON (READ_GROUP || READ_SITE);
	  READ_GROUP = TRUE;
	  this_group = SMAN_allocate_group_struct ();
	  continue;
	}

      if (strstr (this_line, "GRP}"))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) || READ_SITE)
	    READ_GROUP = FALSE;
	  SMAN_GRP_list = g_list_append (SMAN_GRP_list, (MANAGERgroup *) this_group);
	  continue;
	}

      if (strstr (this_line, "GRPINDEX="))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) || READ_SITE)
	    this_group->index = FIELD_INT;
	  continue;
	}

      if (strstr (this_line, "ISOPEN="))
	{
	  MANAGER_ERROR_ON ((!READ_GROUP) || READ_SITE)
	    this_group->is_open = FIELD_INT;
	  continue;
	}



      printf ("IglooFTP : Syntax error in %s\n", this_path);
      printf ("Line %i : %s\n", this_line_number, this_line);

    }

  fclose (in);
  return;

end_on_error:

  printf ("IglooFTP : Syntax error in %s\n", this_path);
  printf ("Line %i : %s\n", this_line_number, this_line);
  printf ("--- Stop reading bookmarks configuration file at line %i. ---\n", this_line_number);

  if (READ_GROUP)
    g_free (this_group);
  if (READ_SITE)
    g_free (this_site);
}



/* SAVE */

static void
SMAN_write_node_to_bookmarks_file (GtkCTree * ctree, GtkCTreeNode * node, gpointer data)
{

  if (node == sman_book_node)
    return;

  if (IS_BOOKMARK_GROUP (node))
    {
      MANAGERgroup *this_group = SMAN_return_MANAGERgroup_from_node (node);
      if (this_group != NULL)
	{
	  fprintf (bookmarks_file, "{GRP\nGRPINDEX=%i\nPARENT=%i\nNAME=%s\n", this_group->index, this_group->parent, this_group->name);
	  if (strlen (this_group->comment))
	    {
	      fprintf (bookmarks_file, "COMMENT=%s\n", strunlf (this_group->comment));
	      strlf (this_group->comment);
	    }
	  if (this_group->is_open)
	    fprintf (bookmarks_file, "ISOPEN=1\n");
	  fprintf (bookmarks_file, "GRP}\n\n");
	}
      return;
    }


  if (IS_BOOKMARK_SITE (node))
    {
      MANAGERsite *this_site = SMAN_return_MANAGERsite_from_node (node);

      if (this_site != NULL)
	{
	  fprintf (bookmarks_file, "\t{SITE\n\tPARENT=%i\n\tNAME=%s\n\tURL=%s\n", this_site->parent, this_site->name, this_site->session.hostname);
	  fprintf (bookmarks_file, "\tPORT=%i\n", this_site->session.port);
	  fprintf (bookmarks_file, "\tUSER=%s\n", this_site->session.username);

	  if (strcmp (this_site->session.userpass, SITE_DEFAULT_PASSWORD_TEXT))
	    {
	      fprintf (bookmarks_file, "\tPASS=%s\n", this_site->session.userpass);
	    }

	  if (!this_site->USE_DEFAULT)
	    {
	      fprintf (bookmarks_file, "\tSYST=%s\n", host_type_name[(int) this_site->session.host_type]);

	      switch (this_site->session.tmode)
		{
		case TYPE_ASCII:
		  fprintf (bookmarks_file, "\tTRANSFERT=ASCII\n");
		  break;
		case TYPE_BIN:
		  fprintf (bookmarks_file, "\tTRANSFERT=BIN\n");
		  break;
		case TYPE_LOCAL:
		  fprintf (bookmarks_file, "\tTRANSFERT=LOCAL\n");
		  break;
		}
	      fprintf (bookmarks_file, "\tREMOTEDIR=%s\n", this_site->session.start_dir);
	      if (strlen (this_site->session.local_dir))
		fprintf (bookmarks_file, "\tLOCALDIR=%s\n", this_site->session.local_dir);

	      fprintf (bookmarks_file, "\tRESOLVELINKS=%i\n", this_site->session.resolve_link ? 1 : 0);
	      fprintf (bookmarks_file, "\tRDC=%i\n", this_site->session.use_RDC ? 1 : 0);

	      if (this_site->session.dmode == SENDP_MODE)
		fprintf (bookmarks_file, "\tPASV=0\n");

	      fprintf (bookmarks_file, "\tUPLOADS_FILENAME_CASE=%i\n", this_site->session.uploads_filename);
	      fprintf (bookmarks_file, "\tUPLOADS_PRESERVE_PERM=%i\n", this_site->session.uploads_perm ? 1 : 0);
	      fprintf (bookmarks_file, "\tUPLOADS_PRESERVE_DATE=%i\n", this_site->session.uploads_date ? 1 : 0);

	      fprintf (bookmarks_file, "\tDOWNLOADS_FILENAME_CASE=%i\n", this_site->session.downloads_filename);
	      fprintf (bookmarks_file, "\tDOWNLOADS_PRESERVE_PERM=%i\n", this_site->session.downloads_perm ? 1 : 0);
	      fprintf (bookmarks_file, "\tDOWNLOADS_PRESERVE_DATE=%i\n", this_site->session.downloads_date ? 1 : 0);

	    }

	  if (strlen (this_site->comment))
	    {
	      fprintf (bookmarks_file, "\tCOMMENT=%s\n", strunlf (this_site->comment));
	      strlf (this_site->comment);
	    }
	  fprintf (bookmarks_file, "\tSITE}\n\n");
	}

      return;
    }

}




void
SMAN_save_bookmarks_file (void)
{
  char this_path[1024];
  GtkCTreeNode *node = sman_book_node;

  bookmarks_path (this_path);
  if ((bookmarks_file = fopen (this_path, "w")) == NULL)
    {
      alert_ok ("Error", "Can't save site manager configuration file !", "Ok");
      return;
    }

  fprintf (bookmarks_file, "# IglooFTP Bookmarks configuration file.\n\n\n");
  gtk_ctree_pre_recursive (sman_tree, node, SMAN_write_node_to_bookmarks_file, NULL);
  fprintf (bookmarks_file, "\n\n\n# END OF IglooFTP Bookmarks configuration file.");
  fflush (bookmarks_file);
  fclose (bookmarks_file);
}



/* EOF */
