/* ***********************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_Restore.h"
#include "Settings.h"
#include "Objet_Liste.h"
#include "Interface/Settings_Interface.h"
#include "Interface/Root_Interface.h"
#include "Com/Initialisation_Com.h"
#include "Debug.h"
#include "Declaration_Constante.h"
#include "Image.h"
#include "main.h"
#include "Animation.h"
#include "Execute.h"
#include "Reseau.h"
#include "Restoration_Agent.h"
#include "Com/Initialisation_Com.h"
#include "Com/Commun.h"
#include "Com/Communication.h"
#include "Interface/Demarrage_Interface.h"
#include "Interface/Maemo.h"
#include "Macro.h"

void Restoration_Liste_Fichier (void)
{
	struct Struct_Liste_Restore *Restore = NULL;
	struct Struct_Liste_Reseau *Reseau = NULL;
	struct struct_Active_Alerte_Intrus Message_Active;
	guint     Nb_Objet_Liste, i;
	int       Socket_Agent_Init;

	Nb_Objet_Liste = g_list_length (Settings->GList_Restore);
	if (Nb_Objet_Liste == 0)
		return;
	AutoRestore = TRUE;
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Restore = g_list_nth_data (Settings->GList_Restore, i);
		debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration : [%s]", Restore->Path);
		Fichier_En_Cours_Restoration = Restore->Path;
		if (Lecture_Fichier_Restoration_Agent (Fichier_En_Cours_Restoration)) {
#ifndef         __MAEMO
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0);
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Demarrage), "Connecting");
#else
			gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0);
			gtk_progress_bar_set_text_maemo (banner_maemo_Demarrage, "Connecting");
#endif
			refresh ();
			Agent_Initialiser = FALSE;
		
			debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Creation de la connection TCP avec l'agent");
			Socket_Agent_Init = Initialisation_TCP_Agent (Dns_Fichier_Xml, Port_Fichier_Xml);
			if (Socket_Agent_Init != -1) {
				debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Agent -------------------------");
#ifndef         __MAEMO
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0);
				gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Demarrage), Restore->Path);
#else
				gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0);
				gtk_progress_bar_set_text_maemo (banner_maemo_Demarrage, "Restore->Path");
#endif
				refresh ();
				while (!Agent_Initialiser) {
					debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Boucle attend fin init agent");
					while (gtk_events_pending ()) {
						gtk_main_iteration ();
					}
					sleep (1);
				}
				debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fin -------------------------");
#ifndef         __MAEMO
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.9);
#else
				gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.9);
#endif
				refresh ();
				Reseau = Creation_Nouveau_Reseau (g_strdup (Nom_Reseau_Restauration), g_strdup (Interface_Restauration), g_strdup ("x.x.x.x"), g_strdup (Communaute_Snmp_Restauration), g_strdup (Icon_Restauration), Socket_Agent_Init, g_strdup (Dns_Fichier_Xml), Port_Fichier_Xml);
				if (Reseau != NULL) {
					Copie_Subnet (Reseau, Subnet_Restauration);
					Reseau->Alert_Intrusion = Intrusion_Alert_Restauration;
				}
				if (Reseau != NULL) {
					Restoration_Interface (Fichier_En_Cours_Restoration, Reseau->Id_Reseau);
				}
				Pid_Agent_Initialisation = -1;
				if (Reseau != NULL) {
					gtk_widget_set_sensitive (toolbutton_View, TRUE);
					gtk_widget_set_sensitive (toolbutton_Save, TRUE);
					gtk_widget_set_sensitive (toolbutton_Search, TRUE);
					gtk_widget_set_sensitive (toggletoolbutton_Alert_Intrusion, TRUE);
					if ((Reseau_Selectionner == Reseau) && (Intrusion_Alert_Restauration)) {
					
						Modification_Toggle_En_Cours = TRUE;
						gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toggletoolbutton_Alert_Intrusion), Reseau_Selectionner->Alert_Intrusion);
						Modification_Toggle_En_Cours = FALSE;
						bzero (&Message_Active, sizeof (struct struct_Active_Alerte_Intrus));
						Message_Active.ID_Reseau = Reseau->Id_Reseau;
						Communication_Envoie_Donnee (Reseau->Pid_Agent, ACTIVE_ALERTE_INTRUS, (gpointer *) & Message_Active, sizeof (Message_Active), Reseau);
					}
				}
			}
		}
	}
}


void Liste_Restore_Efface_Champs (void)
{
	Liste_Restore_Modification_Interface = TRUE;
	gtk_entry_set_text (GTK_ENTRY (entry_Liste_Restore), "");
	Liste_Restore_Modification_Interface = FALSE;
}


void Liste_Restore_Sensible (gboolean bool)
{
	gtk_widget_set_sensitive (button_Liste_Restore, bool);
}


void Initialisation_Liste_Restore (void)
{
	Liste_Restore_Modification_Interface = TRUE;
	Liste_Restore_Sensible (FALSE);
	gtk_widget_set_sensitive (button_Liste_Restore_Add, TRUE);
	gtk_widget_set_sensitive (button_Liste_Restore_Delete, FALSE);
	gtk_widget_set_sensitive (button_Liste_Restore_Ok, FALSE);
	gtk_widget_set_sensitive (button_Liste_Restore_Cancel, FALSE);
	Restore_Modification = NULL;
	Restore_Selectionner = NULL;
	Liste_Restore_Modification_Interface = FALSE;
}


void Affiche_Restore (struct Struct_Liste_Restore *Restore)
{
	GtkTreeModel *model = NULL;
	GtkTreeIter Ligne;

	ERROR_if (Restore == NULL);
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Restore));
	gtk_tree_store_append (GTK_TREE_STORE (model), &Ligne, NULL);
	Restore->ID_Arbre_Ligne = Ligne;
	gtk_tree_store_set (GTK_TREE_STORE (model), &Ligne, COL_PATH_RESTORE, Restore->Path, POINTER_RESTORE, Restore, -1);
}


void Afficher_Liste_Restore (void)
{
	struct Struct_Liste_Restore *Restore = NULL;
	guint     Nb_Objet_Liste, i;

	Nb_Objet_Liste = g_list_length (Settings->GList_Restore);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Restore = g_list_nth_data (Settings->GList_Restore, i);
		Affiche_Restore (Restore);
	}
}


void Supprime_Restore_liste (struct Struct_Liste_Restore *Restore)
{
	GtkTreeModel *model = NULL;

	ERROR_if (Restore == NULL);
	G_LIST_REMOVE (Settings->GList_Restore, Restore);
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Restore));
	gtk_tree_store_remove (GTK_TREE_STORE (model), &Restore->ID_Arbre_Ligne);
	MYFREE (Restore->Path);
	MYFREE (Restore);	
}


struct Struct_Liste_Restore *Modifie_Ajouter_Restore_Dans_Glist (void)
{
	struct Struct_Liste_Restore *Restore = NULL;

	if (Restore_Modification == NULL) {
	
		MALLOC (Restore, sizeof (struct Struct_Liste_Restore));
	}
	else
		Restore = Restore_Modification;

	free_gchar_if_no_null (Restore->Path);
	Restore->Path = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_Liste_Restore)));
	if (Restore_Modification == NULL)
		G_LIST_APPEND (Settings->GList_Restore, Restore);
	return Restore;	
}


void Modifie_Ajoute_Nouveau_Restore (void)
{
	struct Struct_Liste_Restore *Restore = NULL;
	GtkTreeModel *model = NULL;

	if (Restore_Modification != NULL) {
		Modifie_Ajouter_Restore_Dans_Glist ();
		model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_Liste_Restore));
		gtk_tree_store_set (GTK_TREE_STORE (model), &Restore_Modification->ID_Arbre_Ligne, COL_PATH_RESTORE, Restore_Modification->Path, -1);
		return;
	}
	else {
	
		Restore = Modifie_Ajouter_Restore_Dans_Glist ();
		if (Restore != NULL)
			Affiche_Restore (Restore);
		else
			debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nom du Restore Vide");
		return;	
	}
}


static void Write_Restore_to_xml (xmlNodePtr xmlnode, struct Struct_Liste_Restore *Restore)
{
	xmlNodePtr newxml = NULL;

	ERROR_if (xmlnode == NULL);
	ERROR_if (Restore == NULL);
	newxml = xmlNewChild (xmlnode, NULL, "Restore", NULL);
	xmlSetProp (newxml, "Path", Restore->Path);
}


static gboolean write_xml_file_Restore (char *fname)
{
	struct Struct_Liste_Restore *Restore = 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 "Restore_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"));
	Nb_Objet_Liste = g_list_length (Settings->GList_Restore);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Restore = g_list_nth_data (Settings->GList_Restore, i);
		Write_Restore_to_xml (root_element, Restore);
	}
	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_Restore (void)
{
	gchar    *Chemin = NULL;

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


void Lit_Donnee_Xml_Restore (xmlNodePtr xmlnode)
{
	struct Struct_Liste_Restore *Restore = NULL;

	ERROR_if (xmlnode == NULL);

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

	MALLOC (Restore, sizeof (struct Struct_Liste_Restore));

	Restore->Path = xmlGetProp (xmlnode, "Path");
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Chargement Restore : %s", Restore->Path);
	G_LIST_APPEND (Settings->GList_Restore, Restore);
}



void Lit_Xml_Restore (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_Restore (node);
	}
}


gboolean Lit_Xml_Restore_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_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error loading file : [%s]", fname);
		return FALSE;
	}

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

	if (!root_element || !root_element->name || g_strcasecmp (root_element->name, "Restore_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;
	}

	Lit_Xml_Restore (doc);

	xmlFreeDoc (doc);
	return TRUE;
}


gboolean Selectionne_Restore (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
	struct Struct_Liste_Restore *Restore = 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_RESTORE, &Restore, -1);
		switch (bev->button) {
		    case 1:
			    Restore_Selectionner = Restore;
			    Liste_Restore_Efface_Champs ();
			    Liste_Restore_Sensible (TRUE);
			    Liste_Restore_Modification_Interface = TRUE;
			    gtk_entry_set_text (GTK_ENTRY (entry_Liste_Restore), Restore->Path);
			    Liste_Restore_Modification_Interface = FALSE;
			    gtk_widget_set_sensitive (button_Liste_Restore_Add, TRUE);
			    gtk_widget_set_sensitive (button_Liste_Restore_Delete, TRUE);
			    gtk_widget_set_sensitive (button_Liste_Restore_Ok, FALSE);
			    gtk_widget_set_sensitive (button_Liste_Restore_Cancel, FALSE);
			    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_Restore (void)
{
	GtkTreeModel *model = NULL;
	GtkTreeViewColumn *col = NULL;
	GtkCellRenderer *texte = NULL;
	GtkTreeSelection *selection = NULL;
	GtkTreeStore *store = NULL;

	store = gtk_tree_store_new (NUM_COLS_RESTORE, G_TYPE_STRING, G_TYPE_POINTER);
	model = GTK_TREE_MODEL (store);
	treeview_Liste_Restore = gtk_tree_view_new_with_model (model);
	gtk_widget_show (treeview_Liste_Restore);
	g_object_unref (model);
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_Liste_Restore), TRUE);
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview_Liste_Restore), TRUE);
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_Liste_Restore));
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
	col = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (col, "Path");
	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_PATH_RESTORE, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_Liste_Restore), col);
	g_signal_connect ((gpointer) treeview_Liste_Restore, "button-press-event", G_CALLBACK (Selectionne_Restore), treeview_Liste_Restore);
}
