/*
 * 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-gconf.h"
#include "prefs-dialog.h"


/* when a user closes the prefs-dialog we assume that applet is now
   setup, so store all values in gconf */
static void prefs_dialog_close(SensorsApplet *sensors_applet) {
	if (sensors_applet->sensors != NULL) {
		if (sensors_applet_gconf_save_sensors(sensors_applet))
			panel_applet_gconf_set_bool(sensors_applet->applet, IS_SETUP, TRUE, NULL);
	}
	if (sensors_applet->prefs_dialog != NULL) {
		gtk_widget_destroy(GTK_WIDGET(sensors_applet->prefs_dialog));

		sensors_applet->prefs_dialog = NULL;
	}
	if (sensors_applet->timeout_id == 0) {
		sensors_applet->timeout_id = g_timeout_add(panel_applet_gconf_get_int(sensors_applet->applet, TIMEOUT, NULL), (GSourceFunc)sensors_applet_update_active_sensors, sensors_applet);
	}

}

static void prefs_dialog_Fahrenheit_toggled(GtkToggleButton *button, SensorsApplet *sensors_applet) {
	gboolean value;
	g_object_get(button, "active", &value, NULL);
	panel_applet_gconf_set_bool(sensors_applet->applet, FARENHEIT, value, NULL);
	sensors_applet_update_active_sensors(sensors_applet);
}
		
static void prefs_dialog_labels_inline_toggled(GtkToggleButton *button, SensorsApplet *sensors_applet) {
	gboolean value;
	g_object_get(button, "active", &value, NULL);
	panel_applet_gconf_set_bool(sensors_applet->applet, LABELS_INLINE, value, NULL);
	sensors_applet_display_layout_changed(sensors_applet);
}

static void prefs_dialog_show_units_toggled(GtkToggleButton *button, SensorsApplet *sensors_applet) {
	gboolean value;
	g_object_get(button, "active", &value, NULL);
	panel_applet_gconf_set_bool(sensors_applet->applet, SHOW_UNITS, value, NULL);
	sensors_applet_update_active_sensors(sensors_applet);
}

static void prefs_dialog_num_sensors_changed(GtkSpinButton *button, SensorsApplet *sensors_applet) {
	gint value;
	value = gtk_spin_button_get_value_as_int(button);
	panel_applet_gconf_set_int(sensors_applet->applet, NUM_SENSORS, value, NULL);
	sensors_applet_display_layout_changed(sensors_applet);
}

static void prefs_dialog_timeout_changed(GtkSpinButton *button, SensorsApplet *sensors_applet) {
	gint value;
	value = (gint)(gtk_spin_button_get_value(button) * 1000);
	panel_applet_gconf_set_int(sensors_applet->applet, TIMEOUT, value, NULL);
}

static void prefs_dialog_display_mode_changed(GtkComboBox *display_mode_combo_box,
					      SensorsApplet *sensors_applet) {
	panel_applet_gconf_set_int(sensors_applet->applet,
				   DISPLAY_MODE,
				   gtk_combo_box_get_active(display_mode_combo_box),
				   NULL);
	
	sensors_applet_display_layout_changed(sensors_applet);
}

static void prefs_dialog_font_size_changed(GtkComboBox *font_size_combo_box,
					   SensorsApplet *sensors_applet) {
	panel_applet_gconf_set_int(sensors_applet->applet,
				   FONT_SIZE,
				   gtk_combo_box_get_active(font_size_combo_box),
				   NULL);
	
	sensors_applet_update_active_sensors(sensors_applet);
}

/* callbacks for the tree of sensors */
static void prefs_dialog_sensor_toggled(GtkCellRenderer *renderer, gchar *path_str, SensorsApplet *sensors_applet) {
	GtkTreeIter iter;
	GtkTreePath *path;

	gboolean old_value;

	path = gtk_tree_path_new_from_string(path_str);
	
	gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors), &iter, path);
	gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), 
			   &iter, 
			   ENABLE_COLUMN, &old_value, 
			   -1);

	if (old_value) {
		sensors_applet_sensor_disabled(sensors_applet,
					       path);
	} else {
		sensors_applet_sensor_enabled(sensors_applet,
					      path);
	}
	
	gtk_tree_store_set(sensors_applet->sensors, &iter, 
			   ENABLE_COLUMN, !old_value, 
			   -1);

	gtk_tree_path_free(path);
}

static void prefs_dialog_sensor_name_changed(GtkCellRenderer *renderer, gchar *path_str, gchar *new_text, SensorsApplet *sensors_applet) {
	GtkTreeIter iter;
	GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
	
	gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors), &iter, path);

	gtk_tree_store_set(sensors_applet->sensors, &iter, LABEL_COLUMN, new_text, -1);
		
	sensors_applet_update_sensor(sensors_applet, path);
	gtk_tree_path_free(path);
}

static void prefs_dialog_sensor_config_button_clicked(GtkButton *button, SensorsApplet *sensors_applet) {
	sensor_config_dialog_create(button, sensors_applet);
}

/* if a sensor is selected, make sure button is able to be clicked */
static void prefs_dialog_selection_changed(GtkTreeSelection *selection, GtkButton *sensor_config_button) {
	GtkTreeIter iter;
	GtkTreeModel *model;
	/* if there is a selection with no children make sensitive */
	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
		if (!gtk_tree_model_iter_has_child(model, &iter)) {
			gtk_widget_set_sensitive(GTK_WIDGET(sensor_config_button), TRUE);
			return;
		}
	}
	/* otherwise make insensitive */
	gtk_widget_set_sensitive(GTK_WIDGET(sensor_config_button), FALSE);
	
}

void prefs_dialog_open(SensorsApplet *sensors_applet) {
	GtkDialog *dialog;
	GtkNotebook *notebook;

	/* widgets for global prefs */
	GtkSpinButton *num_sensors_spinbutton, *timeout_spinbutton;
	GtkTable *globals_table;
	GtkHSeparator *globals_separator;
	GtkComboBox *font_size_combo_box, *display_mode_combo_box;
	GtkLabel *num_sensors_label, *timeout_label, *font_size_label, *display_mode_label;
	GtkCheckButton *Fahrenheit_checkbutton, *labels_inline_checkbutton, *show_units_checkbutton;
	GtkAdjustment *num_sensors_adjust, *timeout_adjust; 

	/* widgets for sensors tree */
	GtkTreeView *view; 
	GtkTooltips *view_tooltips;
	GtkTreeViewColumn *id_column, *label_column, *enable_column, *icon_column;
	GtkCellRenderer *id_renderer, *label_renderer, *enable_renderer, *icon_renderer;
	GtkScrolledWindow *scrolled_window;
	GtkAlignment *globals_alignment;
	GtkBox *sensors_vbox; /* holds scrolled_window and hbox */
	GtkBox *sensors_hbox; /* holds alarm button */
	GtkButton *sensor_config_button;

	GtkSizeGroup *size_group; /* so comboboxes all
				   * request the same size */
	g_assert(sensors_applet->prefs_dialog == NULL);
	
	/* while prefs dialog is open, stop the updating of sensors so
	 * we don't get any race conditions due to concurrent updates
	 * of the labels, values and icons linked lists etc. */
	if (sensors_applet->timeout_id != 0) {
		if (g_source_remove(sensors_applet->timeout_id)) {
			sensors_applet->timeout_id = 0;
		}
	}

	sensors_applet->prefs_dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Sensors Applet Preferences"),
										      NULL,
										      GTK_DIALOG_NO_SEPARATOR,
										      GTK_STOCK_CLOSE,
										      GTK_RESPONSE_CLOSE,
										      NULL));
	g_object_set(sensors_applet->prefs_dialog, 
		     "border-width", 12,
		     "default-width", 380,
		     "default-height", 350,
		     NULL);
	
	gtk_box_set_homogeneous(GTK_BOX(sensors_applet->prefs_dialog->vbox), FALSE);
	
	gtk_box_set_spacing(GTK_BOX(sensors_applet->prefs_dialog->vbox), 5);
	
	
	g_signal_connect_swapped(sensors_applet->prefs_dialog,
				 "response", G_CALLBACK(prefs_dialog_close), 
				 sensors_applet);
	
	g_signal_connect_swapped(sensors_applet->prefs_dialog,
				 "delete-event", G_CALLBACK(prefs_dialog_close),
				 sensors_applet);

	g_signal_connect_swapped(sensors_applet->prefs_dialog,
				 "destroy", G_CALLBACK(prefs_dialog_close),
				 sensors_applet);
	
	/* if no SensorsList's have been created, this is because
	   we haven't been able to access any sensors */
	if (sensors_applet->sensors == NULL) {
		GtkWidget *label;
		label = gtk_label_new(_("No sensors found!"));
		gtk_box_pack_start_defaults(GTK_BOX(sensors_applet->prefs_dialog->vbox), label);
		return;
	}
	

	labels_inline_checkbutton = g_object_new(GTK_TYPE_CHECK_BUTTON,
							       "use-underline", TRUE,
							       "label", _("Display labels _inline with sensor values"),
							       "active", panel_applet_gconf_get_bool(sensors_applet->applet, LABELS_INLINE, NULL),
							       NULL);
	
	g_signal_connect(labels_inline_checkbutton, "toggled", G_CALLBACK(prefs_dialog_labels_inline_toggled), sensors_applet);

	
	show_units_checkbutton = g_object_new(GTK_TYPE_CHECK_BUTTON,
							    "use-underline", TRUE,
							    "label", _("Display _units with sensor values"),
							    "active", panel_applet_gconf_get_bool(sensors_applet->applet, SHOW_UNITS, NULL),
							    NULL);
	
	g_signal_connect(show_units_checkbutton, "toggled", G_CALLBACK(prefs_dialog_show_units_toggled), sensors_applet);
	
	
	Fahrenheit_checkbutton = g_object_new(GTK_TYPE_CHECK_BUTTON,
					     "use-underline", TRUE,
					     "label", _("Use _Fahrenheit for temperature sensors"),
					     "active", panel_applet_gconf_get_bool(sensors_applet->applet, FARENHEIT, NULL),
					     NULL);
	
	g_signal_connect(Fahrenheit_checkbutton, "toggled", G_CALLBACK(prefs_dialog_Fahrenheit_toggled), sensors_applet);
	

	num_sensors_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
					  "value", 1.0,
					  "lower", 1.0,
					  "upper", 10.0,
					  "step-increment", 1.0,
					  "page-increment", 1.0,
					  "page-size", 0.0,
					  NULL);
	
	num_sensors_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
					      "adjustment", num_sensors_adjust,
					      "climb-rate", 1.0,
					      "digits", 0,
					      "value", (gdouble) panel_applet_gconf_get_int(sensors_applet->applet, NUM_SENSORS, NULL),
					      "width-chars", 4,
					      NULL);

	num_sensors_label = g_object_new(GTK_TYPE_LABEL,
					 "use-underline", TRUE,
					 "label", _("_Number of sensors per column / row"),
					 "mnemonic-widget", num_sensors_spinbutton,
					 "xalign", 0.0,
					 NULL);
	

	g_signal_connect(num_sensors_spinbutton, "value-changed", G_CALLBACK(prefs_dialog_num_sensors_changed), sensors_applet);
			

	timeout_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
				      "value", 2.0,
				      "lower", 1.5,
				      "upper", 10.0,
				      "step-increment", 0.5,
				      "page-increment", 1.0,
				      "page-size", 0.0,
				      NULL);
	
	timeout_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
					  "adjustment", timeout_adjust,
					  "climb-rate", 0.5,
					  "digits", 1,
					  "value", (gdouble) panel_applet_gconf_get_int(sensors_applet->applet, TIMEOUT, NULL) / 1000.0,
					  "width-chars", 4,
					  NULL);


	timeout_label = g_object_new(GTK_TYPE_LABEL,
				     "use-underline", TRUE,
				     "label", _("Refresh _delay (secs)"),
				     "mnemonic-widget", timeout_spinbutton,
				     "xalign", 0.0,
				     NULL);

	g_signal_connect(timeout_spinbutton, "value-changed", G_CALLBACK(prefs_dialog_timeout_changed), sensors_applet);
	


	
	font_size_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());


	gtk_combo_box_append_text(font_size_combo_box, _("largest"));
	gtk_combo_box_append_text(font_size_combo_box, _("larger"));
	gtk_combo_box_append_text(font_size_combo_box, _("large"));
	gtk_combo_box_append_text(font_size_combo_box, _("normal"));
	gtk_combo_box_append_text(font_size_combo_box, _("small"));
	gtk_combo_box_append_text(font_size_combo_box, _("smaller"));
	gtk_combo_box_append_text(font_size_combo_box, _("smallest"));
	
	
	gtk_combo_box_set_active(font_size_combo_box, panel_applet_gconf_get_int(sensors_applet->applet, FONT_SIZE, NULL));

	font_size_label = g_object_new(GTK_TYPE_LABEL,
				       "use-underline", TRUE,
				       "label", _("Font _size"),
				       "mnemonic-widget", font_size_combo_box,
				       "xalign", 0.0,
				       NULL);
	
	g_signal_connect(font_size_combo_box,
			 "changed",
			 G_CALLBACK(prefs_dialog_font_size_changed),
			 sensors_applet);





	display_mode_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());


	gtk_combo_box_append_text(display_mode_combo_box, _("none"));
	gtk_combo_box_append_text(display_mode_combo_box, _("labels"));
	gtk_combo_box_append_text(display_mode_combo_box, _("icons"));

       	
	gtk_combo_box_set_active(display_mode_combo_box, panel_applet_gconf_get_int(sensors_applet->applet, DISPLAY_MODE, NULL));

	display_mode_label = g_object_new(GTK_TYPE_LABEL,
					  "use-underline", TRUE,
					  "label", _("_Label active sensors in panel with"),
					  "mnemonic-widget", display_mode_combo_box,
					  "xalign", 0.0,
					  NULL);
	
	g_signal_connect(display_mode_combo_box,
			 "changed",
			 G_CALLBACK(prefs_dialog_display_mode_changed),
			 sensors_applet);


	/* SIZE AND LAYOUT */
	/* keep all widgets same size */
	size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);

	gtk_size_group_add_widget(size_group,
				  GTK_WIDGET(display_mode_combo_box));

	gtk_size_group_add_widget(size_group,
				  GTK_WIDGET(timeout_spinbutton));

	gtk_size_group_add_widget(size_group,
				  GTK_WIDGET(num_sensors_spinbutton));

	gtk_size_group_add_widget(size_group,
				  GTK_WIDGET(font_size_combo_box));

	globals_table = g_object_new(GTK_TYPE_TABLE,
				     "homogeneous", FALSE,
				     "n-columns", 2,
				     "n-rows", 7,
				     NULL);

	gtk_table_set_col_spacings(globals_table, 12);
	gtk_table_set_row_spacings(globals_table, 3);

	gtk_table_attach(globals_table,
			 GTK_WIDGET(display_mode_label),
			 0, 1,
			 0, 1,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);
	gtk_table_attach(globals_table,
			 GTK_WIDGET(display_mode_combo_box),
			 1, 2,
			 0, 1,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);


	gtk_table_attach(globals_table,
			 GTK_WIDGET(num_sensors_label),
			 0, 1,
			 1, 2,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);

	gtk_table_attach(globals_table,
			 GTK_WIDGET(num_sensors_spinbutton),
			 1, 2,
			 1, 2,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);


	gtk_table_attach(globals_table,
			 GTK_WIDGET(timeout_label),
			 0, 1,
			 2, 3,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);

	gtk_table_attach(globals_table,
			 GTK_WIDGET(timeout_spinbutton),
			 1, 2,
			 2, 3,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);
			 

	gtk_table_attach(globals_table,
			 GTK_WIDGET(font_size_label),
			 0, 1,
			 3, 4,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);
	gtk_table_attach(globals_table,
			 GTK_WIDGET(font_size_combo_box),
			 1, 2,
			 3, 4,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);


	gtk_table_set_row_spacing(globals_table, 3, 12);
	gtk_table_attach(globals_table,
			 GTK_WIDGET(labels_inline_checkbutton),
			 0, 2,
			 4, 5,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);

	gtk_table_attach(globals_table,
			 GTK_WIDGET(show_units_checkbutton),
			 0, 2,
			 5, 6,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);

	gtk_table_attach(globals_table,
			 GTK_WIDGET(Fahrenheit_checkbutton),
			 0, 2,
			 6, 7,
			 GTK_FILL,
			 GTK_FILL,
			 0,
			 0);



	
	view = g_object_new(GTK_TYPE_TREE_VIEW,
					  "model", GTK_TREE_MODEL(sensors_applet->sensors),		     
					  "rules-hint", TRUE,
					  "reorderable", FALSE,
					  "enable-search", TRUE,
					  "search-column", LABEL_COLUMN,
					  NULL);
	
	id_renderer = gtk_cell_renderer_text_new();
	label_renderer = gtk_cell_renderer_text_new();
	g_object_set(label_renderer,
		     "editable", TRUE,
		     NULL);
	
	g_signal_connect(label_renderer, "edited", G_CALLBACK(prefs_dialog_sensor_name_changed), sensors_applet);

	enable_renderer = gtk_cell_renderer_toggle_new();
	g_signal_connect(enable_renderer, "toggled", G_CALLBACK(prefs_dialog_sensor_toggled), sensors_applet);
	icon_renderer = gtk_cell_renderer_pixbuf_new();

	id_column = gtk_tree_view_column_new_with_attributes(_("Sensor"),
										 id_renderer,
										 "text", ID_COLUMN,
										 NULL);
	
	gtk_tree_view_column_set_min_width(id_column, 90);
	
	label_column = gtk_tree_view_column_new_with_attributes(_("Label"),
									      label_renderer,
									      "text", LABEL_COLUMN,
									       "visible", VISIBLE_COLUMN,
									      NULL);
	
	gtk_tree_view_column_set_min_width(label_column, 150);

	/* create the tooltip */
	view_tooltips = gtk_tooltips_new();
	gtk_tooltips_set_tip(view_tooltips,
			     GTK_WIDGET(view),
			     _("Labels can be edited directly by clicking on them."),
			     "");
			     
	enable_column = gtk_tree_view_column_new_with_attributes(_("Enabled"),
									       enable_renderer,
									       "active", ENABLE_COLUMN,
									       "visible", VISIBLE_COLUMN,
									       NULL);

	icon_column = gtk_tree_view_column_new_with_attributes(_("Icon"),
									       icon_renderer,
									     "pixbuf", ICON_PIXBUF_COLUMN,
									       "visible", VISIBLE_COLUMN,
									     NULL);
	gtk_tree_view_append_column(view, id_column);
	gtk_tree_view_append_column(view, icon_column);
	gtk_tree_view_append_column(view, label_column);
	gtk_tree_view_append_column(view, enable_column);

	gtk_tree_view_columns_autosize(view);

	scrolled_window = g_object_new(GTK_TYPE_SCROLLED_WINDOW,
						     "hadjustment", NULL, 
						     "height-request", 200,
						     "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
						     "vadjustment",NULL,
						     "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
						     NULL);

	gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view));

	/* GtkTree Selection */
	sensors_applet->selection = gtk_tree_view_get_selection(view);
	/* allow user to only select one row at a time at most */
	gtk_tree_selection_set_mode(sensors_applet->selection, GTK_SELECTION_SINGLE);
	/* when selection is changed, make sure sensor_config button is
	   activated */

	/* Sensor Config button */
	/* initially make button insensitive until user selects a row
	   from the sensors tree */
	sensor_config_button = g_object_new(GTK_TYPE_BUTTON,
					    "label", _("Configure _Sensor"),
					    "use-underline", TRUE,
					    "sensitive", FALSE,
					    NULL);
	

	g_signal_connect(sensors_applet->selection,
			 "changed",
			 G_CALLBACK(prefs_dialog_selection_changed),
			 sensor_config_button);
	
	/* pass selection to signal handler so we can give user a
	   sensors_applet->prefs_dialog with the selected rows alarm value and enable */
	g_signal_connect(sensor_config_button, "clicked", G_CALLBACK(prefs_dialog_sensor_config_button_clicked), sensors_applet);

	sensors_vbox = g_object_new(GTK_TYPE_VBOX,
					  "border-width", 5,
					  "homogeneous", FALSE,
					  "spacing", 0,
					  NULL);

	sensors_hbox = g_object_new(GTK_TYPE_HBOX,
						  "border-width", 5,
						  "homogeneous", FALSE,
						  "spacing", 0,
						  NULL);
	gtk_box_pack_end(sensors_hbox, GTK_WIDGET(sensor_config_button), FALSE, FALSE, 0);

	/* pack sensors_vbox */
	gtk_box_pack_start(sensors_vbox, GTK_WIDGET(scrolled_window), TRUE, TRUE, 0);
	gtk_box_pack_start(sensors_vbox, GTK_WIDGET(sensors_hbox), FALSE, FALSE, 0);

	globals_alignment = g_object_new(GTK_TYPE_ALIGNMENT,
					 "xalign", 0.5,
					 "yalign", 0.0,
					 "top-padding", 12,
					 "left-padding", 12,
					 "bottom-padding", 12,
					 "right-padding", 12,
					  NULL);
	gtk_container_add(GTK_CONTAINER(globals_alignment), GTK_WIDGET(globals_table));

	notebook = g_object_new(GTK_TYPE_NOTEBOOK,
					      NULL);
	
	gtk_notebook_append_page(notebook, GTK_WIDGET(globals_alignment), gtk_label_new(_("Global Options")));
	gtk_notebook_append_page(notebook, GTK_WIDGET(sensors_vbox), gtk_label_new(_("Sensors")));

	/* pack notebook into prefs_dialog */
	gtk_box_pack_start_defaults(GTK_BOX(sensors_applet->prefs_dialog->vbox), GTK_WIDGET(notebook));


	gtk_widget_show_all(GTK_WIDGET(sensors_applet->prefs_dialog));
}

								   


syntax highlighted by Code2HTML, v. 0.9.1