/*
 * Copyright (C) 2005 Alex Murray <pragmatine@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include "sensors-applet.h"
#include "sensors-applet-gconf.h"

/* function to be called if an error occurs
   when loading values from gconf */
static void sensors_applet_gconf_error_occurred(void) {
	gchar *markup;
	GtkDialog *dialog;
	GtkHBox *hbox;
	GtkImage *icon;
	GtkLabel *label;

	dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_(PACKAGE_NAME " - Error Occurred"),
								   NULL,
								   GTK_DIALOG_NO_SEPARATOR,
								   GTK_STOCK_OK,
								   GTK_RESPONSE_ACCEPT,
								   NULL));
	gtk_dialog_set_default_response(dialog, GTK_RESPONSE_ACCEPT);
	g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
	hbox = g_object_new(GTK_TYPE_HBOX,
			    NULL);
	icon = g_object_new(GTK_TYPE_IMAGE,
			    "stock", GTK_STOCK_DIALOG_WARNING,
			    "icon-size", GTK_ICON_SIZE_DIALOG,
			    "xalign", 0.5,
			    "yalign", 1.0,
			    NULL);
	
	markup = g_markup_printf_escaped(_("<b>An error occurred trying to reload the sensors.</b>\n"
					   "Did you forget to load the correct module?  Once the problem\n"
					   "is resolved you will need to reload %s."), PACKAGE_NAME);

	label = g_object_new(GTK_TYPE_LABEL,
			     "wrap", TRUE,
			     "use-markup", TRUE,
			     "label", markup,
			     NULL);
	g_free(markup);

	gtk_box_pack_start_defaults(GTK_BOX(hbox), GTK_WIDGET(icon));
	gtk_box_pack_start_defaults(GTK_BOX(hbox), GTK_WIDGET(label));
	gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(hbox));
	gtk_widget_show_all(GTK_WIDGET(dialog));

}

/* gets called if are already setup so we don't have to manually go
   through and find sensors etc again */
gboolean sensors_applet_gconf_setup_sensors(SensorsApplet *sensors_applet) {
	/* everything gets stored except alarm timeout indexes, which
	   we set to -1, and visible which we set to false for all
	   parent nodes and true for all child nodes */

	GSList *paths = NULL, *ids = NULL, *labels = NULL, *interfaces = NULL, *enables = NULL, *alarm_values = NULL, *alarm_types = NULL, *alarm_enables = NULL, *alarm_commands = NULL, *alarm_timeouts = NULL, *sensor_types = NULL, *multipliers = NULL, *offsets = NULL, *icons = NULL;
	GSList *current_path, *current_id, *current_label, *current_interface, *current_enable, *current_alarm_value, *current_alarm_type, *current_alarm_command, *current_alarm_timeout, *current_alarm_enable, *current_sensor_type, *current_multiplier, *current_offset, *current_icon;

	GError *error = NULL;

	paths = panel_applet_gconf_get_list(sensors_applet->applet, PATHS, GCONF_VALUE_STRING, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	ids = panel_applet_gconf_get_list(sensors_applet->applet, IDS, GCONF_VALUE_STRING, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	labels = panel_applet_gconf_get_list(sensors_applet->applet, LABELS, GCONF_VALUE_STRING, &error);
	if (error) {	
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	interfaces = panel_applet_gconf_get_list(sensors_applet->applet, INTERFACES, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	sensor_types = panel_applet_gconf_get_list(sensors_applet->applet, SENSOR_TYPES, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	enables = panel_applet_gconf_get_list(sensors_applet->applet, ENABLES, GCONF_VALUE_BOOL, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	alarm_values = panel_applet_gconf_get_list(sensors_applet->applet, ALARM_VALUES, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	alarm_types = panel_applet_gconf_get_list(sensors_applet->applet, ALARM_TYPES, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	alarm_enables = panel_applet_gconf_get_list(sensors_applet->applet, ALARM_ENABLES, GCONF_VALUE_BOOL, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	alarm_commands = panel_applet_gconf_get_list(sensors_applet->applet, ALARM_COMMANDS, GCONF_VALUE_STRING, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	alarm_timeouts = panel_applet_gconf_get_list(sensors_applet->applet, ALARM_TIMEOUTS, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	multipliers = panel_applet_gconf_get_list(sensors_applet->applet, MULTIPLIERS, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	offsets = panel_applet_gconf_get_list(sensors_applet->applet, OFFSETS, GCONF_VALUE_INT, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	icons = panel_applet_gconf_get_list(sensors_applet->applet, ICONS, GCONF_VALUE_STRING, &error);
	if (error) {
		sensors_applet_gconf_error_occurred();
		g_error_free(error);
		return FALSE;
	}

	for (current_path = paths, current_id = ids, current_label = labels, current_interface = interfaces, current_enable = enables, current_alarm_value = alarm_values, current_alarm_type = alarm_types, current_alarm_enable = alarm_enables, current_alarm_command = alarm_commands, current_alarm_timeout = alarm_timeouts, current_sensor_type = sensor_types, current_multiplier = multipliers, current_offset = offsets, current_icon = icons; 
	     current_path != NULL && current_id != NULL && current_label != NULL && current_enable != NULL && current_interface != NULL && current_alarm_value != NULL && current_alarm_type != NULL && current_alarm_enable != NULL && current_alarm_command != NULL && current_alarm_timeout != NULL && current_sensor_type != NULL && current_multiplier != NULL && current_offset != NULL && current_icon != NULL;
	     current_path = g_slist_next(current_path), current_id = g_slist_next(current_id), current_label = g_slist_next(current_label), current_enable = g_slist_next(current_enable), current_interface = g_slist_next(current_interface), current_alarm_value = g_slist_next(current_alarm_value), current_alarm_type = g_slist_next(current_alarm_type), current_alarm_enable = g_slist_next(current_alarm_enable), current_alarm_command = g_slist_next(current_alarm_command), current_alarm_timeout = g_slist_next(current_alarm_timeout), current_sensor_type = g_slist_next(current_sensor_type), current_multiplier = g_slist_next(current_multiplier), current_offset = g_slist_next(current_offset), current_icon = g_slist_next(current_icon)) {

		g_debug("trying to add sensor from gconf data: %s\n", (gchar *)(current_id->data));
		sensors_applet_add_sensor_full_details(sensors_applet,
						       (gchar *)(current_path->data), 
						       (gchar *)(current_id->data), 
						       (gchar *)(current_label->data), 
						       GPOINTER_TO_UINT(current_interface->data),
						       GPOINTER_TO_UINT(current_sensor_type->data),
						       GPOINTER_TO_INT(current_enable->data),
						       (gdouble)(GPOINTER_TO_INT(current_alarm_value->data) / 1000.0),
						       GPOINTER_TO_UINT(current_alarm_type->data),
						       GPOINTER_TO_INT(current_alarm_enable->data),
						       (gchar *)(current_alarm_command->data),
						       GPOINTER_TO_INT(current_alarm_timeout->data),
						       (gdouble)(GPOINTER_TO_INT(current_multiplier->data) / 1000.0),
						       (gdouble)(GPOINTER_TO_INT(current_offset->data) / 1000.0),
						       (gchar *)(current_icon->data));

	}

       	g_slist_foreach(paths, (GFunc)g_free, NULL);
	g_slist_free(paths);
       	g_slist_foreach(ids, (GFunc)g_free, NULL);
	g_slist_free(ids);
       	g_slist_foreach(labels, (GFunc)g_free, NULL);
	g_slist_free(labels);
	g_slist_free(interfaces);
	g_slist_free(sensor_types);
	g_slist_free(enables);
	g_slist_free(alarm_values);
	g_slist_free(alarm_types);
	g_slist_free(alarm_enables);
       	g_slist_foreach(alarm_commands, (GFunc)g_free, NULL);
	g_slist_free(alarm_commands);
	g_slist_free(alarm_timeouts);
	g_slist_free(multipliers);
	g_slist_free(offsets);
       	g_slist_foreach(icons, (GFunc)g_free, NULL);
	g_slist_free(icons);

	return TRUE;
}


gboolean sensors_applet_gconf_save_sensors(SensorsApplet *sensors_applet) {
	/* write everything to gconf except VISIBLE and
	   ALARM_TIMEOUT_INDEX */
	/* for stepping through GtkTreeStore data structure */
	GtkTreeIter interfaces_iter, sensors_iter;
	gboolean not_end_of_interfaces = TRUE, not_end_of_sensors = TRUE;

	GSList *paths = NULL, *ids = NULL, *labels = NULL, *interfaces = NULL, *enables = NULL, *alarm_values = NULL, *alarm_types = NULL, *alarm_enables = NULL, *alarm_commands = NULL, *alarm_timeouts = NULL, *sensor_types = NULL, *multipliers = NULL, *offsets = NULL, *icons = NULL;
	gchar *current_path, *current_id, *current_label, *current_alarm_command, *current_icon;
	gboolean current_enable, current_alarm_enable;
	gdouble current_alarm_value, current_multiplier, current_offset;
	guint current_interface, current_alarm_timeout, current_sensor_type, current_alarm_type;
	
	GError *error = NULL;
	/* now step through the GtkTreeStore sensors to
	   find which sensors are enabled */
	for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); not_end_of_interfaces; not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) {
		// store a gconf key for this interface
		gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), 
				   &interfaces_iter,
				   ID_COLUMN, &current_id,
				   -1);

		panel_applet_gconf_set_bool(sensors_applet->applet, current_id, TRUE, NULL);
		g_free(current_id);
		
		/* reset sensors sentinel */
		not_end_of_sensors = TRUE;
		
		for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); not_end_of_sensors; not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) {
			gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), 
					   &sensors_iter,
					   PATH_COLUMN, &current_path,
					   ID_COLUMN, &current_id,
					   LABEL_COLUMN, &current_label,
					   INTERFACE_COLUMN, &current_interface,
					   SENSOR_TYPE_COLUMN, &current_sensor_type,
					   ENABLE_COLUMN, &current_enable,
					   ALARM_VALUE_COLUMN, &current_alarm_value,
					   ALARM_TYPE_COLUMN, &current_alarm_type,
					   ALARM_ENABLE_COLUMN, &current_alarm_enable,
					   ALARM_COMMAND_COLUMN, &current_alarm_command,
					   ALARM_TIMEOUT_COLUMN, &current_alarm_timeout,
					   MULTIPLIER_COLUMN, &current_multiplier,
					   OFFSET_COLUMN, &current_offset,
					   ICON_FILENAME_COLUMN, &current_icon,
					   -1);

			/* prepend values as this is faster then just
			   reverse list when finished */
			paths = g_slist_prepend(paths, current_path);
			ids = g_slist_prepend(ids, current_id);
			labels = g_slist_prepend(labels, current_label);
			interfaces = g_slist_prepend(interfaces, GUINT_TO_POINTER(current_interface));
			enables = g_slist_prepend(enables, GINT_TO_POINTER(current_enable));
			alarm_values = g_slist_prepend(alarm_values, GINT_TO_POINTER((gint)(current_alarm_value * 1000)));
			alarm_types = g_slist_prepend(alarm_types, GUINT_TO_POINTER(current_alarm_type));
			alarm_enables = g_slist_prepend(alarm_enables, GINT_TO_POINTER(current_alarm_enable));
			alarm_commands = g_slist_prepend(alarm_commands, current_alarm_command);
			alarm_timeouts = g_slist_prepend(alarm_timeouts, GINT_TO_POINTER(current_alarm_timeout));
			sensor_types = g_slist_prepend(sensor_types, GUINT_TO_POINTER(current_sensor_type));
			multipliers = g_slist_prepend(multipliers, GINT_TO_POINTER((gint)(current_multiplier * 1000)));
			offsets = g_slist_prepend(offsets, GINT_TO_POINTER((gint)(current_offset * 1000)));
			icons = g_slist_prepend(icons, current_icon);

		}
	}

	/* keep lists in original order */
	paths = g_slist_reverse(paths);
	ids = g_slist_reverse(ids);
	labels = g_slist_reverse(labels);
	interfaces = g_slist_reverse(interfaces);
	enables = g_slist_reverse(enables);
	alarm_values = g_slist_reverse(alarm_values);
	alarm_types = g_slist_reverse(alarm_types);
	alarm_enables = g_slist_reverse(alarm_enables);
	alarm_commands = g_slist_reverse(alarm_commands);
	alarm_timeouts = g_slist_reverse(alarm_timeouts);
	sensor_types = g_slist_reverse(sensor_types);
	multipliers = g_slist_reverse(multipliers);
	offsets = g_slist_reverse(offsets);
	icons = g_slist_reverse(icons);

	panel_applet_gconf_set_list(sensors_applet->applet, PATHS, GCONF_VALUE_STRING, paths, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}

	panel_applet_gconf_set_list(sensors_applet->applet, IDS, GCONF_VALUE_STRING, ids, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}

	panel_applet_gconf_set_list(sensors_applet->applet, LABELS, GCONF_VALUE_STRING, labels, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}

	panel_applet_gconf_set_list(sensors_applet->applet, INTERFACES, GCONF_VALUE_INT, interfaces, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, SENSOR_TYPES, GCONF_VALUE_INT, sensor_types, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ENABLES, GCONF_VALUE_BOOL, enables, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ALARM_VALUES, GCONF_VALUE_INT, alarm_values, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ALARM_TYPES, GCONF_VALUE_INT, alarm_types, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ALARM_ENABLES, GCONF_VALUE_BOOL, alarm_enables, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ALARM_COMMANDS, GCONF_VALUE_STRING, alarm_commands, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ALARM_TIMEOUTS, GCONF_VALUE_INT, alarm_timeouts, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, MULTIPLIERS, GCONF_VALUE_INT, multipliers, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, OFFSETS, GCONF_VALUE_INT, offsets, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}
	
	panel_applet_gconf_set_list(sensors_applet->applet, ICONS, GCONF_VALUE_STRING, icons, &error);
	if (error) {
		g_error_free(error);
		return FALSE;
	}

	/* need to free allocated strings */
	g_slist_foreach(paths, (GFunc)g_free, NULL);
	g_slist_free(paths);
	g_slist_foreach(ids, (GFunc)g_free, NULL);
	g_slist_free(ids);
	g_slist_foreach(labels, (GFunc)g_free, NULL);
	g_slist_free(labels);
	g_slist_free(interfaces);
	g_slist_free(enables);
	g_slist_free(alarm_values);
	g_slist_free(alarm_types);
	g_slist_free(alarm_enables);
	g_slist_foreach(alarm_commands, (GFunc)g_free, NULL);
	g_slist_free(alarm_commands);
	g_slist_free(alarm_timeouts);
	g_slist_free(sensor_types);
	g_slist_free(multipliers);
	g_slist_free(offsets);
	g_slist_foreach(icons, (GFunc)g_free, NULL);
	g_slist_free(icons);

	return TRUE;
}



syntax highlighted by Code2HTML, v. 0.9.1