/* ***********************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 <sys/socket.h>

#include "Reseau.h"
#include "Interface/Root_Interface.h"
#include "Interface/Bulle_Network_Interface.h"
#include "Com/Initialisation_Com.h"
#include "Add_Network_Subnet.h"
#include "Declaration_Constante.h"
#include "Objet_Liste.h"
#include "Modules.h"
#include "Debug.h"
#include "Execute.h"
#include "Objet_Bulle.h"
#include "Image.h"
#include "Gconf.h"
#include "Macro.h"
#include "Log.h"


void Affiche_Info_Reseau (struct Struct_Liste_Reseau *Reseau)
{
	gchar    *Text = NULL;
	gdouble   Total, A_Faire;

	if (Reseau == Reseau_Selectionner) {
		Reseau->Compteur_Activite_Agent = 0; 
		if (Reseau->Octet_Recu > 1024)
			Text = g_strdup_printf ("R : %.1f Ko/s", (((double) Reseau->Octet_Recu) / 1024));
		else
			Text = g_strdup_printf ("R : %d o/s", Reseau->Octet_Recu);
		gtk_label_set_text (GTK_LABEL (label_Utilisation_Reseau_Reception), Text);
		MYFREE (Text);
		if (Reseau->Octet_Envoyer > 1024)
			Text = g_strdup_printf ("S : %.1f Ko/s", (((double) Reseau->Octet_Envoyer) / 1024));
		else
			Text = g_strdup_printf ("S : %d o/s", Reseau->Octet_Envoyer);
		gtk_label_set_text (GTK_LABEL (label_Utilisation_Reseau_Emission), Text);
		MYFREE (Text);
		if (Reseau->Nb_Equipement != 0) {
			Total = Reseau->Nb_Equipement - Reseau->Nb_Equipement_Erase;
			A_Faire = Reseau->Nb_Equipement_En_Cours_De_Scan + Reseau->Nb_Equipement_En_Attente_De_Scan;
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar), (Total - A_Faire) / Total);
			Text = g_strdup_printf ("Total : %d (%d/%d)   %%%d", Reseau->Nb_Equipement - Reseau->Nb_Equipement_Erase, Reseau->Nb_Equipement_En_Cours_De_Scan, Reseau->Nb_Equipement_En_Attente_De_Scan, (int) (((Total - A_Faire) / Total) * 100));
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar), Text);
			MYFREE (Text);
		}
	}
}



void Arreter_Tous_Les_Agents (void)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (GList_Liste_Reseau);
	Log_free(Donnee_Cle_Main,g_strdup_printf( "Arret des agents (%d)******************\n", Nb_Objet_Liste));
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Reseau = g_list_nth_data (GList_Liste_Reseau, i);
		if (!Reseau->Connection_Failed){
			Log_free(Donnee_Cle_Main,g_strdup_printf( "Arret agent %d : [%d][%s]\n", i, Reseau->Id_Reseau, Reseau->Nom_Complet_Reseau));
			Demande_Arret_Agent (Reseau);
		
			Log_free(Donnee_Cle_Main,g_strdup_printf("Arret Connection tcp : %s    socket : %d\n",Reseau->Nom_Complet_Reseau,Reseau->Socket_Agent));
			shutdown(Reseau->Socket_Agent,0);
			close(Reseau->Socket_Agent);
		}
		else{
				Log_free(Donnee_Cle_Main,g_strdup_printf( "Arret agent FAILED %d : [%d][%s]\n", i, Reseau->Id_Reseau, Reseau->Nom_Complet_Reseau));
		}
	}
	Log_free(Donnee_Cle_Main,g_strdup_printf("Fin Arret des agents ****************\n"));
}

void Afficher_Liste_Reseau (void)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (GList_Liste_Reseau);
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Affiche Les reseaux (%d)******************", Nb_Objet_Liste);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Reseau = g_list_nth_data (GList_Liste_Reseau, i);
		debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%d : [%d][%s]", i, Reseau->Id_Reseau, Reseau->Nom_Complet_Reseau);
	}
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fin Reseau *****************");
}


struct Struct_Liste_Reseau *Recupere_Pointeur_Structure_Reseau (gint ID_Reseau)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	guint     Nb_Objet_Liste, i;



	Nb_Objet_Liste = g_list_length (GList_Liste_Reseau);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Reseau = g_list_nth_data (GList_Liste_Reseau, i);
		if (Reseau->Id_Reseau == ID_Reseau)
			return Reseau;
	}
	return NULL;
}

struct Struct_Liste_Reseau *Recupere_Pointeur_Reseau_Selectionner (GtkWidget * scrollwin)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (GList_Liste_Reseau);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Reseau = g_list_nth_data (GList_Liste_Reseau, i);
		if (Reseau->scrollwin == scrollwin)
			return Reseau;
	}
	debug_printf (INTERFACE, D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Reseau Inconnu");
	return NULL;
}

gboolean Recherche_Si_Reseau_Existe_Deja (gchar * Nom_Complet_Reseau)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	guint     Nb_Objet_Liste, i;

	ERROR_if (Nom_Complet_Reseau == NULL);

	Nb_Objet_Liste = g_list_length (GList_Liste_Reseau);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Reseau = g_list_nth_data (GList_Liste_Reseau, i);
	
		if (strcmp (Reseau->Nom_Reseau, Nom_Complet_Reseau) == 0)
			return TRUE;
	}
	return FALSE;
}


struct Struct_Liste_Reseau *Creation_Structure_Nouveau_Reseau (gchar * Nom_Complet_Reseau, gchar * Nom_Reseau, gchar * Interface, gchar * Ip, gchar * Communaute_Snmp,gchar *Ip_Agent,gint Port_Agent)
{
	struct Struct_Liste_Reseau *Reseau = NULL;

	ERROR_if (Nom_Reseau == NULL);
	MALLOC(Reseau,sizeof (struct Struct_Liste_Reseau));
	Reseau->Nom_Complet_Reseau = Nom_Complet_Reseau;
	Reseau->Nom_Reseau = Nom_Reseau;
	Reseau->Interface = Interface;
	Reseau->Ip = Ip;
	Reseau->Ip_Agent = Ip_Agent;
	Reseau->Port_Agent = Port_Agent;
	Reseau->Communaute_Snmp = Communaute_Snmp;
	Reseau->Id_Reseau = Genere_ID_Reseau;
	Reseau->Pid_Agent = Pid_Agent_Initialisation;
	Reseau->Mode_Liste_Detaille = FALSE;
	Reseau->Ip_Dynamic = Lecture_Gconf_Boolean(BOOL_IP_DYNAMIC);
	Reseau->Compteur_Activite_Agent = 0;
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Ajouter Nouveau Reseau  Nom[%s]  ID[%d]", Reseau->Nom_Complet_Reseau, Reseau->Id_Reseau);
	return Reseau;
}


static gboolean expose_event (GtkWidget * widget, GdkEventExpose * event, gpointer data)
{
	struct Struct_Liste_Reseau *Reseau = (struct Struct_Liste_Reseau *) data;

	gdk_draw_drawable (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], Reseau->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height);
	return TRUE;
}

gboolean Network_leave_notify_event (GtkWidget * widget, GdkEventCrossing * event, gpointer user_data)
{
#ifdef         __BULLE_NETWORK_ENABLE
	gtk_widget_hide (Bulle_Reseau);
#endif
	return FALSE;
}


gboolean Network_notebook_click (GtkWidget * widget, GdkEventCrossing * event, gpointer data)
{
	struct Struct_Liste_Reseau *Reseau = (struct Struct_Liste_Reseau *) data;

	gtk_notebook_set_page (GTK_NOTEBOOK (notebook_reseau), Reseau->Id_Reseau); 
	return FALSE;
}


void Copie_Subnet (struct Struct_Liste_Reseau *Reseau, GList * Glist)
{
	struct Struct_Subnet *Subnet = NULL, *Subnet_Copie = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (Glist);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Subnet = g_list_nth_data (Glist, i);
		Subnet_Copie = NULL;
		MALLOC (Subnet_Copie, sizeof (struct Struct_Subnet));
	
		Subnet_Copie->Masque = Subnet->Masque;
		Subnet_Copie->A = Subnet->A;
		Subnet_Copie->B = Subnet->B;
		Subnet_Copie->C = Subnet->C;
		G_LIST_APPEND (Reseau->Glist_Subnet_Equipement, Subnet_Copie);
	}
}


/*
Attention : Toute les pointeurs de chaine seront stockés dans la structure donc il faut copie les chaines avant d'appeler cette fonction
*/
struct Struct_Liste_Reseau *Creation_Nouveau_Reseau (gchar * Nom_Reseau, gchar * Interface, gchar * Ip, gchar * Communaute_Snmp, gchar * Icon,int Socket_Agent_Init,gchar *Ip_Agent,gint Port_Agent)
{
	struct Struct_Liste_Reseau *Reseau = NULL;
	GdkPixbuf *pixbuf = NULL;
	GdkBitmap *mask = NULL;
	gchar    *Nom_Complet_Reseau = NULL;

	ERROR_if (Nom_Reseau == NULL);
	ERROR_if (Interface == NULL);
	ERROR_if (Ip == NULL);
	ERROR_if (Icon == NULL);
	ERROR_if (Ip_Agent == NULL);
	Nom_Complet_Reseau = g_strdup_printf ("%s - %s:%s", Nom_Reseau, Interface, Ip);
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nom_Complet_Reseau : [%s]   %s:%d",Nom_Complet_Reseau,Ip_Agent,Port_Agent);
	if (!Recherche_Si_Reseau_Existe_Deja (Nom_Reseau)) {
		Reseau = Creation_Structure_Nouveau_Reseau (Nom_Complet_Reseau, Nom_Reseau, Interface, Ip, Communaute_Snmp,Ip_Agent,Port_Agent);
		G_LIST_APPEND (GList_Liste_Reseau, Reseau);
	
#ifdef __DEBUG_COM
		Reseau->Log_Send = Create_Log(CATEG_COMM_SEND,Nom_Reseau,NULL,FALSE);
		Reseau->Log_Recv = Create_Log(CATEG_COMM_RECV,Nom_Reseau,NULL,FALSE);
#endif
	
		Demande_Demarrage_Agent (Genere_ID_Reseau,Nom_Reseau, Interface, Communaute_Snmp, TRUE);
		Genere_ID_Reseau++;
	
		Reseau->scrollwin = gtk_scrolled_window_new (NULL, NULL);
		gtk_widget_show (Reseau->scrollwin);
		gtk_container_add (GTK_CONTAINER (notebook_reseau), Reseau->scrollwin);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (Reseau->scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	
		Reseau->Liste_Equipement_Type = Create_Liste_Equipement (FALSE);
		gtk_container_add (GTK_CONTAINER (Reseau->scrollwin), Reseau->Liste_Equipement_Type);
		gtk_widget_show (Reseau->Liste_Equipement_Type);
	
		Reseau->Liste_Equipement_IP = Create_Liste_Equipement (TRUE);
	
		Reseau->Socket_Agent = Socket_Agent_Init;
	
		Reseau->Icone_Reseau = Icon;
		pixbuf = Chargement_Image (Reseau->Icone_Reseau, COULEUR);
		gdk_pixbuf_render_pixmap_and_mask (pixbuf, &Reseau->pixmap, &mask, 127);
		Reseau->drawingarea1 = gtk_drawing_area_new ();
		gtk_widget_ref (Reseau->drawingarea1);
		gtk_widget_shape_combine_mask (Reseau->drawingarea1, mask, 0, 0);
		gtk_widget_set_size_request (Reseau->drawingarea1, 16, 16);
		g_signal_connect (Reseau->drawingarea1, "expose_event", G_CALLBACK (expose_event), (gpointer *) Reseau);
		gtk_widget_set_events (Reseau->drawingarea1, gtk_widget_get_events (Reseau->drawingarea1) | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_LEAVE_NOTIFY);
		g_signal_connect (Reseau->drawingarea1, "motion_notify_event", G_CALLBACK (show_win_bulle_Reseau), (gpointer *) Reseau);
		g_signal_connect ((gpointer) Reseau->drawingarea1, "leave_notify_event", G_CALLBACK (Network_leave_notify_event), (gpointer *) Reseau);
		g_signal_connect ((gpointer) Reseau->drawingarea1, "button_press_event", G_CALLBACK (Network_notebook_click), (gpointer *) Reseau);
		gtk_widget_show (Reseau->drawingarea1);
		gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook_reseau), Reseau->scrollwin, Reseau->drawingarea1);
	
		if (Reseau->Id_Reseau == 0)
			Reseau_Selectionner = Reseau;
	
		Afficher_Liste_Reseau ();
		return Reseau;
	}
	else {
		debug_printf (INTERFACE, D_INFO_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s] : already exist", Nom_Complet_Reseau);
		MYFREE (Nom_Complet_Reseau);
		MYFREE (Nom_Reseau);
		MYFREE (Interface);
		MYFREE (Ip);
		MYFREE (Communaute_Snmp);
		MYFREE (Icon);
		MYFREE (Ip_Agent);
	
		return NULL;
	}
	return NULL;
}


void Initialisation_Variable_Reseau (void)
{
	ID_Reseau_En_Cours = 0;
	GList_Liste_Reseau = NULL;
	Genere_ID_Reseau = 0;
	Reseau_Selectionner = NULL;
}
