/*
 * 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 <gnome.h>
#include "sensor-config-dialog.h"
#include "sensors-applet.h"

#define SPINBUTTON_WIDTH_CHARS 7
#define VALUE_DECIMAL_PLACES 3

static void sensor_config_dialog_icon_changed(GnomeIconEntry *icon_entry, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	GdkPixbuf *new_icon;
	gchar *new_filename;
	GError *error = NULL;

	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);

	new_filename = gnome_icon_entry_get_filename(icon_entry);
	new_icon = gdk_pixbuf_new_from_file_at_size(new_filename, DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE, &error);
	if (error) {
		 g_warning("Could not load new icon: %s\n", error->message);
		 g_error_free(error);
		 error = NULL;
		 
		 /* reset to old icon */
		 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
				    &iter,
				    ICON_FILENAME_COLUMN, new_filename,
				    -1);
		 gnome_icon_entry_set_filename(icon_entry, new_filename);
		 g_free(new_filename);
		 return;
	}

	gtk_tree_store_set(sensors_applet->sensors,
			   &iter,
			   ICON_FILENAME_COLUMN, new_filename,
			   ICON_PIXBUF_COLUMN, new_icon,
			   -1);

	/* tree now holds ref */
	g_object_unref(new_icon);
	g_free(new_filename);
	
	sensors_applet_icon_changed(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_multiplier_changed(GtkSpinButton *spinbutton, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	gdouble value;

	value = gtk_spin_button_get_value(spinbutton);
	
	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);

	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);
	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    MULTIPLIER_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_offset_changed(GtkSpinButton *spinbutton, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	gdouble value;

	value = gtk_spin_button_get_value(spinbutton);
	
	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);
	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    OFFSET_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_alarm_type_changed(GtkComboBox *alarm_type_combo_box, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	guint value;

	value = gtk_combo_box_get_active(alarm_type_combo_box);
	
	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);
	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    ALARM_TYPE_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);

}
static void sensor_config_dialog_alarm_value_changed(GtkSpinButton *spinbutton, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	gdouble value;

	value = gtk_spin_button_get_value(spinbutton);
	
	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);

	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    ALARM_VALUE_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_alarm_toggled(GtkToggleButton *button, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;

	gboolean value;
	value = gtk_toggle_button_get_active(button);

	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);

	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    ALARM_ENABLE_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_alarm_timeout_changed(GtkSpinButton *spinbutton, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	gint value;

	value = gtk_spin_button_get_value_as_int(spinbutton);
	
	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);

	sensors_applet_alarm_off(sensors_applet, path);
	gtk_tree_store_set(sensors_applet->sensors,
			    &iter,
			    ALARM_TIMEOUT_COLUMN, value,
			   -1);

	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void sensor_config_dialog_alarm_command_edited(GtkEntry *command_entry, SensorsApplet *sensors_applet) {
	GtkTreeModel *model;
	GtkTreePath *path;
	GtkTreeIter iter;
	
	gchar *value;
	g_object_get(command_entry, "text", &value, NULL);

	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
	path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
				       &iter);

	sensors_applet_alarm_off(sensors_applet, path);

	gtk_tree_store_set(sensors_applet->sensors,
			   &iter,
			   ALARM_COMMAND_COLUMN, value,
			   -1);
	g_free(value);
	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

void sensor_config_dialog_create(GtkButton *button, SensorsApplet *sensors_applet) {
	GtkWidget *dialog;
	GtkTreeModel *model;
	GtkTreeIter iter;

	/* icon entry */
	GnomeIconEntry *icon_entry;

	/* multiplier and offset widgets */
	GtkLabel *icon_label, *multiplier_label, *offset_label;
	GtkAlignment *multiplier_spinbutton_aligner, *offset_spinbutton_aligner;
	GtkAdjustment *multiplier_adjust, *offset_adjust;
	GtkSpinButton *multiplier_spinbutton, *offset_spinbutton;

	GtkHSeparator *separator;

	/* alarm widgets */
	GtkLabel *alarm_value_label, *alarm_type_pre_label, *alarm_type_post_label, *alarm_command_label, *alarm_timeout_label;
	GtkComboBox *alarm_type_combo_box;
	GtkAlignment *alarm_value_spinbutton_aligner, *alarm_timeout_spinbutton_aligner;
	GtkAdjustment *alarm_value_adjust, *alarm_timeout_adjust;
	GtkSpinButton *alarm_value_spinbutton, *alarm_timeout_spinbutton;
	GtkTable *table;
	GtkAlignment *alarm_enable_aligner;
	GtkCheckButton *alarm_enable_checkbutton;
	GtkEntry *alarm_command_entry;

	/* instance variables for data */
	gdouble alarm_value, multiplier, offset;
	gboolean alarm_enable;
	gchar *alarm_command;
	gint alarm_timeout;
	guint alarm_type;
	gchar *icon_filename;

	gtk_tree_selection_get_selected(sensors_applet->selection,
					&model,
					&iter);
		
	dialog = gtk_dialog_new_with_buttons(_("Configure Sensor"),
					     NULL,
					     GTK_DIALOG_NO_SEPARATOR,
					     GTK_STOCK_CLOSE,
					     GTK_RESPONSE_CLOSE,
					     NULL);
	g_object_set(dialog,
		     "modal", TRUE,
		     "border-width", 12,
		     NULL);
	
	g_signal_connect_swapped(dialog,
				 "response",
				 G_CALLBACK(gtk_widget_destroy),
				 dialog);
	
	/* get current values of alarm and its enable */
	gtk_tree_model_get(model, &iter,
			   ALARM_VALUE_COLUMN, &alarm_value,
			   ALARM_TYPE_COLUMN, &alarm_type,
			   ALARM_ENABLE_COLUMN, &alarm_enable,
			   ALARM_COMMAND_COLUMN, &alarm_command,
			   ALARM_TIMEOUT_COLUMN, &alarm_timeout,
			   MULTIPLIER_COLUMN, &multiplier,
			   OFFSET_COLUMN, &offset,
			   ICON_FILENAME_COLUMN, &icon_filename,
			   -1);
	
	/* do multiplier and offset widgets */
	multiplier_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
			      "value", 1.0,
			      "lower", 0.001,
			      "upper", 1000.0,
			      "step-increment", 0.1,
			      "page-increment", 1.0,
			      "page-size", 1.0,
			      NULL);

	
	multiplier_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
					     "adjustment", multiplier_adjust,
					     "digits", VALUE_DECIMAL_PLACES,
					     "value", multiplier,
					     "width-chars", SPINBUTTON_WIDTH_CHARS,
					     NULL);

	multiplier_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
						     "child", multiplier_spinbutton,
						     "xalign", 0.0,
						     "xscale", 0.0,
						     NULL);

	multiplier_label = g_object_new(GTK_TYPE_LABEL,
					"label", _("Sensor value _multiplier"),
					"mnemonic-widget", multiplier_spinbutton,
					"use-underline", TRUE,
					"xalign", 0.0,
					NULL);
	
	
	g_signal_connect(multiplier_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_multiplier_changed), sensors_applet);
	

	offset_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
				     "value", 0.0,
				     "lower", -1000.000,
				     "upper", 1000.000,
				     "step-increment", 0.01,
				     "page-increment", 1.0,
				     "page-size", 1.0,
				     NULL);

	offset_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
					 "adjustment", offset_adjust,
					 "digits", VALUE_DECIMAL_PLACES,
					 "value", (gdouble)offset,
					 "width-chars", SPINBUTTON_WIDTH_CHARS,
					 NULL);
	
	offset_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
						 "child", offset_spinbutton,
						 "xalign", 0.0,
						 "xscale", 0.0,
						 NULL);

	offset_label = g_object_new(GTK_TYPE_LABEL,
				    "label", _("Sensor value _offset"),
				    "mnemonic-widget", offset_spinbutton,
				    "use-underline", TRUE,
				    "xalign", 0.0,
				    NULL);

	g_signal_connect(offset_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_offset_changed), sensors_applet);


	/* The separator */
	separator = GTK_HSEPARATOR(gtk_hseparator_new());


	/* now do alarm widgets */
	alarm_type_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());
	gtk_combo_box_append_text(alarm_type_combo_box, _("greater than"));
	gtk_combo_box_append_text(alarm_type_combo_box, _("less than"));
	gtk_combo_box_set_active(alarm_type_combo_box, alarm_type);

	g_signal_connect(alarm_type_combo_box,
			 "changed",
			 G_CALLBACK(sensor_config_dialog_alarm_type_changed),
			 sensors_applet);

	alarm_type_pre_label = g_object_new(GTK_TYPE_LABEL,
					 "label", _("Execute alarm when _sensor is"),
					 "mnemonic-widget", alarm_type_combo_box,
					 "use-underline", TRUE,
					 "xalign", 0.0,
					 NULL);

	alarm_type_post_label = g_object_new(GTK_TYPE_LABEL,
					 "label", _("alarm threshold"),
					 "xalign", 0.0,
					 NULL);

	alarm_value_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
			      "value", 0.0,
			      "lower", -100000.0,
			      "upper", 100000.0,
			      "step-increment", 1.0,
			      "page-increment", 10.0,
			      "page-size", 100.0,
			      NULL);

	
	alarm_value_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
					      "adjustment", alarm_value_adjust,
					      "digits", VALUE_DECIMAL_PLACES,
					      "value", alarm_value,
					      "width-chars", SPINBUTTON_WIDTH_CHARS,
					      NULL);
	
	alarm_value_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
					  "child", alarm_value_spinbutton,
					  "xalign", 0.0,
					  "xscale", 0.0,
					  NULL);

	alarm_value_label = g_object_new(GTK_TYPE_LABEL,
					 "label", _("Alarm _threshold"),
					 "mnemonic-widget", alarm_value_spinbutton,
					 "use-underline", TRUE,
					 "xalign", 0.0,
					 NULL);

	
	g_signal_connect(alarm_value_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_alarm_value_changed), sensors_applet);
	
	alarm_timeout_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
					    "value", 0.0,
					    "lower", 0.0,
					    "upper", 10000.0,
					    "step-increment", 1.0,
					    "page-increment", 10.0,
					    "page-size", 100.0,
					    NULL);

	alarm_timeout_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
						"adjustment", alarm_timeout_adjust,
						"digits", 0,
						"value", (gdouble)alarm_timeout,
						"width-chars", SPINBUTTON_WIDTH_CHARS,
						NULL);
	alarm_timeout_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
							"child", alarm_timeout_spinbutton,
							"xalign", 0.0,
							"xscale", 0.0,
							NULL);
	
	alarm_timeout_label = g_object_new(GTK_TYPE_LABEL,
					   "label", _("_Repeat interval (secs)"),
					   "mnemonic-widget", alarm_timeout_spinbutton,
					   
					   "use-underline", TRUE,
					   "xalign", 0.0,
					   NULL);

	g_signal_connect(alarm_timeout_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_alarm_timeout_changed), sensors_applet);

	alarm_command_entry = g_object_new(GTK_TYPE_ENTRY,
					   "text", alarm_command,
					   "width-chars", 25,
					   NULL);

	g_free(alarm_command);

	alarm_command_label = g_object_new(GTK_TYPE_LABEL,
					   "use-underline", TRUE,
					   "label", _("_Alarm command"),
					   "mnemonic-widget", alarm_command_entry,
					   "xalign", 0.0,
					   NULL);

	g_signal_connect(alarm_command_entry,
			 "changed",
			 G_CALLBACK(sensor_config_dialog_alarm_command_edited),
			 sensors_applet);

	alarm_enable_checkbutton = g_object_new(GTK_TYPE_CHECK_BUTTON,
						"use-underline", TRUE,
						"label", _("_Enable alarm"),
						"active", alarm_enable,
						"xalign", 0.0,
						NULL);
	
	alarm_enable_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
					    "child", alarm_enable_checkbutton,
					    "xalign", 0.0,
					    "xscale", 0.0,
					    NULL);

	g_signal_connect(alarm_enable_checkbutton, "toggled", G_CALLBACK(sensor_config_dialog_alarm_toggled), sensors_applet);
	


	/* icon at bottom of dialog */
	icon_entry = g_object_new(GNOME_TYPE_ICON_ENTRY,
				  "filename", icon_filename,
				  "browse-dialog-title", _("Sensor Icon"),
				  NULL);

	g_free(icon_filename);

	icon_label = g_object_new(GTK_TYPE_LABEL,
				  "label", _("Sensor _icon"),
				  "mnemonic-widget", icon_entry,
				  "use-underline", TRUE,
				  "xalign", 0.0,
				  NULL);

	g_signal_connect(icon_entry, "changed", G_CALLBACK(sensor_config_dialog_icon_changed), sensors_applet);


	table = g_object_new(GTK_TYPE_TABLE,
			     "column-spacing", 5,
			     "homogeneous", FALSE,
			     "n-columns", 3,
			     "n-rows", 9,
			     "row-spacing", 5,
			     NULL);


	gtk_table_attach_defaults(table,
				  GTK_WIDGET(multiplier_label),
				  0, 1,
				  0, 1);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(multiplier_spinbutton_aligner),
				  1, 3,
				  0, 1);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(offset_label),
				  0, 1,
				  1, 2);

	gtk_table_attach_defaults(table,
				  GTK_WIDGET(offset_spinbutton_aligner),
				  1, 3,
				  1, 2);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(separator),
				  0, 3,
				  2, 3);

	/* now pack alarm widgets */
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_type_pre_label),
				  0, 1,
				  3, 4);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_type_combo_box),
				  1, 2,
				  3, 4);

	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_type_post_label),
				  2, 3,
				  3, 4);

	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_value_label),
				  0, 1,
				  4, 5);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_value_spinbutton_aligner),
				  1, 3,
				  4, 5);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_timeout_label),
				  0, 1,
				  5, 6);

	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_timeout_spinbutton_aligner),
				  1, 3,
				  5, 6);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_command_label),
				  0, 1,
				  6, 7);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_command_entry),
				  1, 3,
				  6, 7);
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(alarm_enable_aligner),
				  1, 3,
				  7, 8);	

	gtk_table_attach_defaults(table,
				  GTK_WIDGET(icon_label),
				  0, 1,
				  8, 9);
	
	gtk_table_attach_defaults(table,
				  GTK_WIDGET(icon_entry),
				  1, 3,
				  8, 9);

	gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(table));
	gtk_widget_show_all(dialog);

}		


syntax highlighted by Code2HTML, v. 0.9.1