/* ***********************IMPORTANT *********************************************
 *  Copyright (C) 2004-2007 Thierry Lagarde <tlagarde@users.sourceforge.net>
 *  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.
 *
 *
 *                      ********************
 *
 *
 *  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 Library General Public License for more details.
 *
 *
 *                      ********************
 *
 *
 * You are highly encouraged to send your changes to <tlagarde@users.sourceforge.net>
 * for possible incorporation into the main distribution.
 * By sending these changes to <tlagarde@users.sourceforge.net>,
 * it is assumed that you are offering <tlagarde@users.sourceforge.net>
 * the unlimited, non-exclusive right to reuse, modify, and relicense the code.
 *
 *
 *                      ********************
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **************************************************************************************/
#include <gtk/gtk.h>
#include "Settings_Port.h"
#include "Settings.h"
#include "Interface/Settings_Interface.h"
#include "Debug.h"
#include "Interface/Bulle_Port_Interface.h"
#include "Declaration_Constante.h"
#include "Objet_Bulle.h"
#include "Interface/Bulle_Port_Callbacks.h"
#include "Image.h"
#include "main.h"
#include "Macro.h"


void Afficher_Icone_Program_Associe (gint Num_Port)
{
#ifdef         __BULLE_PORT_ENABLE
	struct Struct_Liste_Port *Port = NULL;
	GtkWidget *Bouton = NULL;
	GList    *GList_Enfant = NULL;
	guint     Nb_Objet_Liste, i;


	GList_Enfant = gtk_container_children (GTK_CONTAINER (toolbar_Bulle_Port));
	Nb_Objet_Liste = g_list_length (GList_Enfant);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Bouton = g_list_nth_data (GList_Enfant, i);
	
		gtk_container_remove (GTK_CONTAINER (toolbar_Bulle_Port), Bouton);
	}

	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if ((Port->Port_Pere != NULL) && (Port->Nb_Fils == 0) && (Port->Num_Port == Num_Port)) {
			if (Port->toolbutton != NULL) {
				gtk_container_add (GTK_CONTAINER (toolbar_Bulle_Port), Port->toolbutton);
				gtk_widget_show (Port->toolbutton);
			}
			else
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Pas de toolbutton pour le programme associé [%s] pour le port [%d]", Port->Name, Port->Num_Port);
		}
	}
#endif
}


gboolean Port_Avec_Program_Associe (gint Num_Port)
{
	struct Struct_Liste_Port *Port = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if ((Port->Port_Pere == NULL) && (Port->Num_Port == Num_Port))
			return (Port->Nb_Fils != 0);
	}
	return FALSE;
}


gint Num_Du_Port (gchar * Nom_Port)
{
	struct Struct_Liste_Port *Port = NULL;
	guint     Nb_Objet_Liste, i;

	ERROR_if (Nom_Port == NULL);
	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if ((Port->Port_Pere == NULL) && (strcmp (Port->Service, Nom_Port) == 0))
			return Port->Num_Port;
	}
	return -1;
}


struct Struct_Liste_Port *Pointeur_Du_Port (gint Num_Port)
{
	struct Struct_Liste_Port *Port = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if ((Port->Port_Pere == NULL) && (Port->Num_Port == Num_Port))
			return Port;
	}
	return NULL;
}


gchar    *Nom_Du_Port (gint Num_Port)
{
	struct Struct_Liste_Port *Port = NULL;

	Port = Pointeur_Du_Port (Num_Port);
	if (Port != NULL)
		return Port->Service;
	else
		return NULL;
}

void Liste_Port_Efface_Champs (void)
{
	Liste_Port_Modification_Interface = TRUE;
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Info_Service), "");
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Info_Description), "");
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_Liste_Ports_Info_Port), -1);
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Info_Type), -1);
/*#ifdef  __GNOME_ENABLE
	gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Info), NULL);
	gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Program), NULL);
#else
#endif*/
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Info), -1);
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Program), -1);
	
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Name), "");
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Path), "");
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Param), "");
	Liste_Port_Modification_Interface = FALSE;
}


void Liste_Port_Sensible (gboolean bool)
{
	gtk_widget_set_sensitive (spinbutton_Liste_Ports_Info_Port, bool);
	gtk_widget_set_sensitive (entry_Liste_Ports_Info_Service, bool);
	gtk_widget_set_sensitive (entry_Liste_Ports_Info_Description, bool);
	gtk_widget_set_sensitive (combobox_Liste_Ports_Info_Type, bool);
	gtk_widget_set_sensitive (combobox_Liste_Ports_Info, bool);
}


void Liste_Port_Program_Sensible (gboolean bool)
{
	gtk_widget_set_sensitive (entry_Liste_Ports_Program_Name, bool);
	gtk_widget_set_sensitive (button_Liste_Ports_Program_Path, bool);
	gtk_widget_set_sensitive (entry_Liste_Ports_Program_Path, bool);
	gtk_widget_set_sensitive (entry_Liste_Ports_Program_Param, bool);
	gtk_widget_set_sensitive (combobox_Liste_Ports_Program, bool);
}

void Initialisation_Liste_Port (void)
{	
	Liste_Port_Modification_Interface = TRUE;
	Port_Modification = NULL;
	Port_Selectionner = NULL;
	Liste_Port_Sensible (FALSE);
	Liste_Port_Program_Sensible (FALSE);
	gtk_widget_set_sensitive (button_Liste_Ports_Ok, FALSE);
	gtk_widget_set_sensitive (button_Liste_Ports_Add, TRUE);
	gtk_widget_set_sensitive (button_Liste_Ports_Delete, FALSE);
	gtk_widget_set_sensitive (button_Liste_Ports_Cancel, FALSE);
	gtk_widget_set_sensitive (button_Liste_Ports_Program_Add, FALSE);
	gtk_widget_set_sensitive (button_Liste_Ports_Program_Delete, FALSE);
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Info), -1);
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Program), -1);
	Liste_Port_Modification_Interface = FALSE;

/*#ifdef  __GNOME_ENABLE
	gnome_icon_entry_set_pixmap_subdir (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Info), PATH_ICONE "Port/");
	gnome_icon_entry_set_pixmap_subdir (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Program), PATH_ICONE "Port/");
#else
#endif*/
}

void Affiche_Port (struct Struct_Liste_Port *Port, struct Struct_Liste_Port *Port_Pere)
{
	GtkTreeModel *model = NULL;
	gchar    *Port_Char = NULL;
	GtkTreeIter Ligne;

	ERROR_if (Port == NULL);
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Ports));
	if (Port_Pere != NULL)
		gtk_tree_store_append (GTK_TREE_STORE (model), &Ligne, &Port_Pere->ID_Arbre_Ligne);
	else
		gtk_tree_store_append (GTK_TREE_STORE (model), &Ligne, NULL);
	Port->ID_Arbre_Ligne = Ligne;
	if (Port_Pere != NULL) {
		Port_Char = g_strdup_printf ("%d", Port_Pere->Num_Port);
		gtk_tree_store_set (GTK_TREE_STORE (model), &Ligne, COL_PORT, Port_Char, COL_SERVICE, Port->Name, COL_DESCRIPTION, Port->Param, POINTER_PORTS, Port, -1);
	
		Port->Port_Pere = (gpointer *) Port_Pere;
		MYFREE (Port_Char);
	}
	else {
		Port_Char = g_strdup_printf ("%d", Port->Num_Port);
		gtk_tree_store_set (GTK_TREE_STORE (model), &Ligne, COL_PORT, Port_Char, COL_SERVICE, Port->Service, COL_DESCRIPTION, Port->Description, POINTER_PORTS, Port, -1);
		MYFREE (Port_Char);
	}
}


void Afficher_Liste_Port (void)
{
	struct Struct_Liste_Port *Port = NULL, *Port_Pere = NULL;
	guint     Nb_Objet_Liste, i, rangPere;

	Nb_Objet_Liste = g_list_length (Settings->GList_Port);

	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		Port_Pere = (struct Struct_Liste_Port *) Port->Port_Pere;
		rangPere = g_list_position (Settings->GList_Port, g_list_find (Settings->GList_Port, Port_Pere));
	
		Affiche_Port (Port, Port_Pere);
	}

}

struct Struct_Liste_Port *Liste_Port_Recherche (gint Num_Port)
{
	struct Struct_Liste_Port *Port = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if ((Port->Port_Pere == NULL) && (Port->Num_Port == Num_Port))
			return Port;
	}
	return NULL;
}

void Supprime_Port_liste (struct Struct_Liste_Port *Port)
{
	struct Struct_Liste_Port *Port_Pere = NULL;
	GtkTreeModel *model = NULL;

	G_LIST_REMOVE (Settings->GList_Port, Port);
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Ports));
	gtk_tree_store_remove (GTK_TREE_STORE (model), &Port->ID_Arbre_Ligne);
	Port_Pere = (struct Struct_Liste_Port *) Port->Port_Pere;
	MYFREE (Port->Service);
	MYFREE (Port->Description);
	MYFREE (Port->Icon);

	MYFREE (Port->Name);
	MYFREE (Port->Path);
	MYFREE (Port->Param);
	MYFREE (Port->Icon_Program);
	MYFREE (Port);	
	if (Port_Pere != NULL) {
		Port_Pere->Nb_Fils--;
	}
}

struct Struct_Liste_Port *Modifie_Ajouter_Port_Dans_Glist (struct Struct_Liste_Port *Pere)
{
	struct Struct_Liste_Port *Port = NULL;

	if ((Port_Modification == NULL) || ((Modification_Port_Program) && (Port_Selectionner->Port_Pere == NULL))) {
	
		MALLOC (Port, sizeof (struct Struct_Liste_Port));
	}
	else
		Port = Port_Modification;

	free_gchar_if_no_null (Port->Service);
	Port->Service = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Ports_Info_Service)));
	free_gchar_if_no_null (Port->Name);
	Port->Name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Ports_Program_Name)));
	if ((strlen (Port->Service) != 0) || (strlen (Port->Name) != 0)) {
		free_gchar_if_no_null (Port->Description);
		Port->Description = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Ports_Info_Description)));
		free_gchar_if_no_null (Port->Icon);
/*#ifdef  __GNOME_ENABLE
		Port->Icon = gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Info));
#else
#endif*/
		Port->Icon = g_strdup_printf ("%sPort/%s",PATH_ICONE_UNIV,Recuperation_Texte_Combo(combobox_Liste_Ports_Info));
	
	
		Port->icone = NULL;
		Port->icone_griser = NULL;
	
		
	
	
	
		Port->Num_Port = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton_Liste_Ports_Info_Port));
		Port->Type = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox_Liste_Ports_Info_Type));
		free_gchar_if_no_null (Port->Path);
		Port->Path = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Ports_Program_Path)));
		free_gchar_if_no_null (Port->Param);
		Port->Param = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Ports_Program_Param)));
		free_gchar_if_no_null (Port->Icon_Program);
/*#ifdef  __GNOME_ENABLE		
		Port->Icon_Program = gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Program));
#else
#endif*/
		Port->Icon_Program = g_strdup_printf ("Port/%s",Recuperation_Texte_Combo(combobox_Liste_Ports_Program));
	
		Port->Nb_Fils = 0;
		if ((Port_Modification == NULL) || ((Modification_Port_Program) && (Port_Selectionner->Port_Pere == NULL))) {
			G_LIST_APPEND (Settings->GList_Port, Port);
			Port->Port_Pere = (gpointer *) Pere;
			if (Pere != NULL)
				Pere->Nb_Fils++;
		}
	}
	else
		return NULL;
	return Port;	
}

void Modifie_Ajoute_Nouveau_Port (void)
{
	struct Struct_Liste_Port *Port = NULL, *Port_Identique = NULL;
	GtkTreeModel *model = NULL;
	gchar    *Port_Char = NULL,*Chemin_Icone = NULL;

	if (!Modification_Port_Program) {
		if (Port_Modification != NULL) {
			Modifie_Ajouter_Port_Dans_Glist (NULL);
			model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Ports));
			Port_Char = g_strdup_printf ("%d", Port_Modification->Num_Port);
			gtk_tree_store_set (GTK_TREE_STORE (model), &Port_Modification->ID_Arbre_Ligne, COL_PORT, Port_Char, COL_SERVICE, Port_Modification->Service, COL_DESCRIPTION, Port_Modification->Description, -1);
			MYFREE (Port_Char);
			return;
		}
		else {
		
			Port_Identique = Liste_Port_Recherche (gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton_Liste_Ports_Info_Port)));
			if (Port_Identique == NULL) {
			
				Port = Modifie_Ajouter_Port_Dans_Glist (NULL);
				if (Port != NULL)
					Affiche_Port (Port, NULL);
				else
					debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nom du port Vide");
				return;
			}
		}
	}
	else {
		if (Port_Selectionner->Port_Pere != NULL) {
		
			Modifie_Ajouter_Port_Dans_Glist (NULL);
			model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Ports));
			gtk_tree_store_set (GTK_TREE_STORE (model), &Port_Selectionner->ID_Arbre_Ligne, COL_SERVICE, Port_Selectionner->Name, COL_DESCRIPTION, Port_Selectionner->Param, POINTER_PORTS, Port_Selectionner, -1);
			Port = Port_Selectionner;
			gtk_widget_destroy (Port->toolbutton);
		}
		else {
		
			Port = Modifie_Ajouter_Port_Dans_Glist (Port_Selectionner);
			Affiche_Port (Port, Port_Selectionner);
			Modification_Port_Program = FALSE;
		}
	
#ifdef         __BULLE_PORT_ENABLE
	
		Chemin_Icone = g_strdup_printf ("%s/%s",PATH_ICONE,Port->Icon_Program);
	
		Port->Image_Button = gtk_image_new_from_file (Chemin_Icone);
		MYFREE (Chemin_Icone);
		gtk_widget_show (Port->Image_Button);
		Port->toolbutton = (GtkWidget *) gtk_tool_button_new (Port->Image_Button, Port->Name);
		gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (Port->toolbutton), FALSE);
	
		g_signal_connect ((gpointer) Port->toolbutton, "clicked", G_CALLBACK (clicked_Bouton_Bulle), Port);
		g_object_ref (Port->toolbutton);
#endif
		return;	
	}
}


static void Write_Port_to_xml (xmlNodePtr xmlnode, struct Struct_Liste_Port *Port)
{
	struct Struct_Liste_Port *Port_Fils = NULL;
	xmlNodePtr newxml = NULL;
	gchar    *Port_Char = NULL;
	guint     Nb_Objet_Liste, i;

	ERROR_if (xmlnode == NULL);
	ERROR_if (Port == NULL);
	newxml = xmlNewChild (xmlnode, NULL, "Ports", NULL);
	xmlSetProp (newxml, "Service", Port->Service);
	xmlSetProp (newxml, "Description", Port->Description);
	xmlSetProp (newxml, "Icon", Port->Icon);
	Port_Char = g_strdup_printf ("%d", Port->Num_Port);
	xmlSetProp (newxml, "Port", Port_Char);
	MYFREE (Port_Char);
	Port_Char = g_strdup_printf ("%d", Port->Type);
	xmlSetProp (newxml, "Type", Port_Char);
	MYFREE (Port_Char);
	xmlSetProp (newxml, "Program_Name", Port->Name);
	xmlSetProp (newxml, "Program_Path", Port->Path);
	xmlSetProp (newxml, "Program_Param", Port->Param);
	xmlSetProp (newxml, "Program_Icon", Port->Icon_Program);
	if (Port->Nb_Fils != 0) {
		Nb_Objet_Liste = g_list_length (Settings->GList_Port);
		for (i = 0; i < Nb_Objet_Liste; i++) {
			Port_Fils = g_list_nth_data (Settings->GList_Port, i);
			if (Port_Fils->Port_Pere == (gpointer *) Port)
				Write_Port_to_xml (newxml, Port_Fils);
		}
	}
}


static gboolean write_xml_file_Port (char *fname)
{
	struct Struct_Liste_Port *Port = NULL;
	xmlDocPtr doc = NULL;
	guint     Nb_Objet_Liste, i;
	xmlNode *root_element = NULL;
	
	ERROR_if (fname == NULL);


	doc = xmlNewDoc(BAD_CAST "1.0");
    root_element = xmlNewNode(NULL, BAD_CAST "Port_AutoScan");
    xmlDocSetRootElement(doc, root_element);
	
	xmlAddChild (root_element, xmlNewDocComment (doc, "Copyright (c) Lagarde thierry. \nThis Database is available for free use by open source software under the terms of the GNU General Public License.\nContact <tlagarde@users.sourceforge.net>  for more information"));

	/*doc->root = xmlNewDocNode (doc, NULL, "Port_AutoScan", NULL);
	xmlAddChild (doc->root, xmlNewDocComment (doc, "Copyright (c) Lagarde thierry. \nThis Database is available for free use by open source software under the terms of the GNU General Public License.\nContact <tlagarde@user.sourceforge.net>  for more information"));*/
	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
		if (Port->Port_Pere == NULL)
			Write_Port_to_xml (root_element, Port);
	}
	if (xmlSaveFile (fname, doc) == -1) {
		xmlFreeDoc (doc);
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "impossible d'enregistrer le fichier xml");
		return FALSE;
	}
	xmlFreeDoc (doc);
	return TRUE;
}


void Enregistrement_Donnee_Xml_Port (void)
{
	gchar    *Chemin = NULL;

	Chemin = g_strdup_printf ("%s/.autoscan-network/config/Port.xml", Info_User->pw_dir);
	write_xml_file_Port (Chemin);
	MYFREE (Chemin);
}


void Lit_Donnee_Xml_Port (xmlNodePtr xmlnode, struct Struct_Liste_Port *Port_Pere)
{
	struct Struct_Liste_Port *Port = NULL;
	gchar    *NumPort = NULL, *Type = NULL,*Chemin_Icone = NULL;
	gint      Nb_Fils;

	ERROR_if (xmlnode == NULL);

	if (!xmlnode->name || g_strcasecmp (xmlnode->name, "Ports") != 0)
		return;

	MALLOC (Port, sizeof (struct Struct_Liste_Port));

	Nb_Fils = 0;
	Port->Service = xmlGetProp (xmlnode, "Service");
	if (Port->Service) {
		Port->Description = xmlGetProp (xmlnode, "Description");
		Port->Icon = xmlGetProp (xmlnode, "Icon");
	
		/*if ((Port->Icon != NULL) && (strlen (Port->Icon) != 0)) {    
		 * debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Chargement Icone [%s]", Port->Icon);
		 * Port->icone = Chargement_Image (Port->Icon, COULEUR);
		 * Port->icone_griser = Chargement_Image (Port->Icon, NOIR_ET_BLANC);
		 * } */
		NumPort = xmlGetProp (xmlnode, "Port");
		if (sscanf (NumPort, "%d", &Port->Num_Port) != 1)
			Port->Num_Port = 0;
		MYFREE (NumPort);
		Type = xmlGetProp (xmlnode, "Type");
		if (sscanf (Type, "%d", &Port->Type) != 1)
			Port->Type = OTHER;
		MYFREE (Type);
		Port->Name = xmlGetProp (xmlnode, "Program_Name");
		Port->Path = xmlGetProp (xmlnode, "Program_Path");
		Port->Param = xmlGetProp (xmlnode, "Program_Param");
		Port->Icon_Program = xmlGetProp (xmlnode, "Program_Icon");
		if (Port_Pere != NULL) {
#ifdef         __BULLE_PORT_ENABLE
		
			Chemin_Icone = g_strdup_printf ("%s%s",PATH_ICONE,Port->Icon_Program);
		
			Port->Image_Button = gtk_image_new_from_file (Chemin_Icone);
			MYFREE (Chemin_Icone);
			gtk_widget_show (Port->Image_Button);
			Port->toolbutton = (GtkWidget *) gtk_tool_button_new (Port->Image_Button, Port->Name);
			gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (Port->toolbutton), FALSE);
		
			g_signal_connect ((gpointer) Port->toolbutton, "clicked", G_CALLBACK (clicked_Bouton_Bulle), Port);
			g_object_ref (Port->toolbutton);
#endif
		}
		G_LIST_APPEND (Settings->GList_Port, Port);
		Port->Port_Pere = (gpointer *) Port_Pere;
	}
	else {
	
	
		MYFREE (Port);
	
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nom du Service Vide pendant la lecture du fichier xml");
		return;
	}
	xmlnode = xmlnode->children;
	while (xmlnode) {
		if (xmlnode->type == XML_ELEMENT_NODE) {
		
			Lit_Donnee_Xml_Port (xmlnode, Port);
			Nb_Fils++;
		}
		xmlnode = xmlnode->next;
	}
	/*xmlnode = xmlnode->childs;   
	 * while (xmlnode) {
	 * Lit_Donnee_Xml_Port (xmlnode, Port);
	 * xmlnode = xmlnode->next;    
	 * Nb_Fils++;
	 * } */
	Port->Nb_Fils = Nb_Fils;
}


void Lit_Xml_Port (xmlDocPtr doc)
{
	xmlNodePtr node = NULL;
	xmlNode  *root_element = NULL;

	ERROR_if (doc == NULL);

	root_element = xmlDocGetRootElement (doc);
	for (node = root_element->children; node != NULL; node = node->next) {
		if (node->type == XML_ELEMENT_NODE)
			Lit_Donnee_Xml_Port (node, NULL);
	}
	/*for (node = doc->root->childs; node != NULL; node = node->next) {
	 * Lit_Donnee_Xml_Port (node, NULL);
	 * } */
}


gboolean Lit_Xml_Port_Fichier (char *fname)
{
	xmlDocPtr doc = NULL;
	xmlNode  *root_element = NULL;

	ERROR_if (fname == NULL);

	if (!g_file_test(fname,G_FILE_TEST_EXISTS))
		debug_printf (INTERFACE, D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error loading file : [%s]", fname);

	doc = xmlParseFile (fname);
	if (!doc) {
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML Port : [%s]", fname);
		return FALSE;
	}
	root_element = xmlDocGetRootElement (doc);

	if (!root_element || !root_element->name || g_strcasecmp (root_element->name, "Port_AutoScan") != 0) {
		if (!root_element)
			debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "l'element n'est pas root");
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML Port mal formaté : [%s]", fname);
		xmlFreeDoc (doc);
		return FALSE;
	}
	/*if (!doc->root || !doc->root->name || g_strcasecmp (doc->root->name, "Port_AutoScan") != 0) {
	 * if (!doc->root)
	 * debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "l'element n'est pas root");
	 * debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML Port mal formaté : [%s]", fname);
	 * xmlFreeDoc (doc);
	 * return FALSE;
	 * } */

	Lit_Xml_Port (doc);

	xmlFreeDoc (doc);
	return TRUE;
}


gint sort_func_Croissant_Port (GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data)
{
	gchar    *port_a = NULL, *port_b = NULL;
	int       ret, Porta, Portb;

	gtk_tree_model_get (model, a, COL_PORT, &port_a, -1);
	gtk_tree_model_get (model, b, COL_PORT, &port_b, -1);
	if (sscanf (port_a, "%d", &Porta) != 1)
		Porta = 0;
	if (sscanf (port_b, "%d", &Portb) != 1)
		Portb = 0;
	if (Porta < Portb)
		ret = -1;
	else
		ret = 1;
	MYFREE (port_a);
	MYFREE (port_b);
	return ret;
}


gboolean Selectionne_Ports (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
	struct Struct_Liste_Port *Port = NULL;
	GtkTreeModel *model = NULL;
	GtkTreePath *path = NULL;
	GtkTreeIter iter;
	gint      x, y;

	if (event->type == GDK_BUTTON_PRESS) {
		GdkEventButton *bev = (GdkEventButton *) event;

		model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
		gdk_window_get_pointer (event->window, &x, &y, NULL);
		if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, &path, NULL, NULL, NULL)) {
			return FALSE;
		}
		gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
		gtk_tree_model_get (model, &iter, POINTER_PORTS, &Port, -1);
		switch (bev->button) {
		    case 1:
			    Port_Selectionner = Port;
			    if (Port->Port_Pere == NULL) {
				    debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Selectionne un port :  program[%d]", Port->Nb_Fils);
				    Liste_Port_Efface_Champs ();
				    Liste_Port_Sensible (TRUE);
				    Liste_Port_Program_Sensible (FALSE);
				    Liste_Port_Modification_Interface = TRUE;
				    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Info_Service), Port->Service);
				    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Info_Description), Port->Description);
				    gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_Liste_Ports_Info_Port), (gfloat) Port->Num_Port);
				    gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Liste_Ports_Info_Type), Port->Type);
				    Active_Combo_Correspondant(combobox_Liste_Ports_Info,Port->Icon);
				    Liste_Port_Modification_Interface = FALSE;
				    gtk_widget_set_sensitive (button_Liste_Ports_Ok, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Add, TRUE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Cancel, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Delete, TRUE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Program_Add, TRUE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Program_Delete, FALSE);
			    }
			    else {
				   
				    Liste_Port_Efface_Champs ();
				    Liste_Port_Sensible (FALSE);
				    Liste_Port_Program_Sensible (TRUE);
				    Liste_Port_Modification_Interface = TRUE;
				    gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_Liste_Ports_Info_Port), (gfloat) Port->Num_Port);
				    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Name), Port->Name);
				    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Path), Port->Path);
				    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Ports_Program_Param), Port->Param);
/*#ifdef  __GNOME_ENABLE	
				    gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (iconentry_Liste_Ports_Program), Port->Icon_Program);
#else
#endif*/
				    Active_Combo_Correspondant(combobox_Liste_Ports_Program,Port->Icon_Program);
				    Liste_Port_Modification_Interface = FALSE;
				    gtk_widget_set_sensitive (button_Liste_Ports_Ok, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Add, TRUE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Cancel, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Delete, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Program_Add, FALSE);
				    gtk_widget_set_sensitive (button_Liste_Ports_Program_Delete, TRUE);
			    }
			    break;
		    default:
			    debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Pas d'actions pour cette combinaison  (%d)", bev->button);
		}
	}
	return FALSE;
}


void Create_Liste_Port (void)
{
	GtkTreeModel *model = NULL;
	GtkTreeViewColumn *col = NULL;
	GtkCellRenderer *texte = NULL;
	GtkTreeSelection *selection = NULL;
	GtkTreeStore *store = NULL;

	store = gtk_tree_store_new (NUM_COLS_PORTS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
	gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), sort_func_Croissant_Port, NULL, NULL);
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
	model = GTK_TREE_MODEL (store);

	treeview_Liste_Ports = gtk_tree_view_new_with_model (model);
	gtk_widget_show (treeview_Liste_Ports);
	g_object_unref (model);
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_Liste_Ports), TRUE);
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview_Liste_Ports), TRUE);
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_Liste_Ports));
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);


	col = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (col, "Port");
	texte = gtk_cell_renderer_text_new ();
	gtk_tree_view_column_pack_start (col, texte, FALSE);
	gtk_tree_view_column_set_attributes (col, texte, "text", COL_PORT, NULL);

	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_Liste_Ports), col);

	col = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (col, "Service");
	texte = gtk_cell_renderer_text_new ();
	gtk_tree_view_column_pack_start (col, texte, FALSE);
	gtk_tree_view_column_set_attributes (col, texte, "text", COL_SERVICE, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_Liste_Ports), col);

	col = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (col, "Description");
	texte = gtk_cell_renderer_text_new ();
	gtk_tree_view_column_pack_start (col, texte, FALSE);
	gtk_tree_view_column_set_attributes (col, texte, "text", COL_DESCRIPTION, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_Liste_Ports), col);

	g_signal_connect ((gpointer) treeview_Liste_Ports, "button-press-event", G_CALLBACK (Selectionne_Ports), treeview_Liste_Ports);
}
