/*
 * Copyright (C) Henning Prömpers 2008 <henning.proempers@uni-jena.de>
 *
 * The Methods of this file creates and update the GUI or they are signal handler. 
 */


/*
 * variables that belong to the GUI
 */
GladeXML *gxml;
GtkWidget *window;
GtkIconView *icon_view;
GtkListStore *store;
GtkComboBox *ztree_version_combobox, *webcam_update_combobox;
GtkFileChooser *ztree_workpath_filechooserbutton;
GtkToggleButton *ztree_use_ramdisk_checkbutton, *auto_quittung_checkbutton;

GtkImage *webcam_picture_widget;
GFile* webcam_picture_file;
GSource* webcam_source = NULL;
//guint webcam_source_id;

GdkPixbuf *icons[6];									// *clientoff, *booting, *clienton, *leafrunning, *halting, *standart;


gboolean webcam_update(gpointer data){
	GInputStream* webcam_picture_stream;
	webcam_picture_stream = G_INPUT_STREAM(g_file_read(webcam_picture_file, NULL, NULL));
	GdkPixbuf *webcam_picture_pixbuf;
	webcam_picture_pixbuf = gdk_pixbuf_scale_simple(gdk_pixbuf_new_from_stream(webcam_picture_stream, NULL, NULL), 320, 240, GDK_INTERP_HYPER);
	gtk_image_set_from_pixbuf(webcam_picture_widget, webcam_picture_pixbuf);
	return TRUE;
}

void webcam_update_combobox_changed(){
	g_message("Update picture %s", gtk_combo_box_get_active_text (webcam_update_combobox));	
	// wenn bereits die Webcam aktualisiert wird, die Funktion stoppen
	if(webcam_source != NULL) g_source_destroy(webcam_source);
	// aktive Einstellung auslesen und GSource mit entsprechendem timeout anlegen
	switch(gtk_combo_box_get_active(webcam_update_combobox)){
		case 0: gtk_image_set_from_pixbuf(webcam_picture_widget, NULL); return;
		case 1: webcam_source = g_timeout_source_new_seconds(600); break;
		case 2: webcam_source = g_timeout_source_new_seconds(60); break;
		case 3: webcam_source = g_timeout_source_new_seconds(10); break;
		case 4: webcam_source = g_timeout_source_new_seconds(1); break;
		case 5: webcam_source = g_idle_source_new(); break;
	}
	// erstes Bild holen
	webcam_update(NULL);
	// GSource die Funktion zuweisen und automatisch periodisch ausführen lassen
	g_source_set_callback(webcam_source, webcam_update, NULL, NULL);
	g_source_attach (webcam_source, NULL);
}

/*
 * creates thr GUI from a glade-file and make some widgets accessable
 */
void init_GUI(){
	int i; // Zähler für lokale Schleifen
	gxml = glade_xml_new (gconf_client_get_string(gconf_client, "/apps/labcontrol/system_config/glade_file", NULL), NULL, NULL);
//	gxml = glade_xml_new ("/home/henning/labcontrol/src/labcontrol.glade", NULL, NULL);
	glade_xml_signal_autoconnect (gxml);
	// Zeiger auf die Widgets zeigen lassen
	window = glade_xml_get_widget (gxml, "window");
	ztree_version_combobox = GTK_COMBO_BOX(glade_xml_get_widget (gxml, "ztree_version_combobox"));
	webcam_update_combobox = GTK_COMBO_BOX(glade_xml_get_widget (gxml, "webcam_update_combobox"));
	ztree_workpath_filechooserbutton = GTK_FILE_CHOOSER(glade_xml_get_widget (gxml, "ztree_workpath_filechooserbutton"));
	ztree_use_ramdisk_checkbutton = GTK_TOGGLE_BUTTON(glade_xml_get_widget (gxml, "ztree_use_ramdisk_checkbutton"));
	auto_quittung_checkbutton = GTK_TOGGLE_BUTTON(glade_xml_get_widget (gxml, "auto_quittung_checkbutton"));
	icon_view = GTK_ICON_VIEW(glade_xml_get_widget (gxml, "iconview1"));
	gtk_icon_view_set_pixbuf_column(icon_view, 0);
	gtk_icon_view_set_text_column(icon_view, 1);
	gtk_icon_view_set_columns(icon_view,  gconf_client_get_int(gconf_client, "/apps/labcontrol/system_config/symbols_no_cols", NULL));

	// benötigte Bilder in Pixbufs laden
	icons[state_off] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/client_off.svg", NULL);
	icons[state_booting] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/booting.svg", NULL);
	icons[state_on] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/client_on.svg", NULL);
	icons[state_zleaf_running] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/leafrunning.svg", NULL);
	icons[state_shutdowning] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/halting.svg", NULL);
	icons[state_undefined] = gdk_pixbuf_new_from_file("/opt/labcontrol/icons/network-workgroup.svg", NULL);

	/* get the list of symbols, stored in the gconf-value-list symbols */
	symbols = gconf_client_get_list(gconf_client, "/apps/labcontrol/system_config/symbols", GCONF_VALUE_INT, NULL);
	// Die Symbole anlegen
	icon_view = GTK_ICON_VIEW(glade_xml_get_widget (gxml, "iconview1"));
	store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
	gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), GTK_TREE_MODEL (store));
	GtkTreeIter iter;
	num_clients = 0; // direkt die Anzahl der Clients mitzählen
	for (i=1; i<=g_slist_length(symbols); i++){
		if (GPOINTER_TO_INT(g_slist_nth_data(symbols, i-1)) == 0){
			gtk_list_store_insert_with_values (store, &iter, 100, -1);
		}
		else {
			gtk_list_store_insert_with_values (store, &iter, 100, 0, icons[state_undefined], 1, g_strdup_printf("%i", GPOINTER_TO_INT(g_slist_nth_data(symbols, i-1))), -1);
			num_clients++;
		}
	}

	// erstes webcam-Bild einfügen
	webcam_picture_widget = GTK_IMAGE(glade_xml_get_widget (gxml, "image1"));
	webcam_picture_file = g_file_new_for_uri(gconf_client_get_string(gconf_client, "/apps/labcontrol/user_config/webcam_picture_path", NULL));
	// Standardmäßig alle 10 Sekunden aktualisieren (webcam_update_combobox_changed() wird automatischa usgeführt)
	gtk_combo_box_set_active(GTK_COMBO_BOX(glade_xml_get_widget (gxml, "webcam_update_combobox")), 
	                         gconf_client_get_int(gconf_client, "/apps/labcontrol/user_config/webcam_update_period", NULL));
}




/** This method is called every time a client's state value has changed in gconf.
 * The parameters are decribed on http://library.gnome.org/devel/gconf/stable/gconf-GConfClient.html#GConfClientNotifyFunc
 */
void update_symbol(GConfClient *config, guint cnx_id, GConfEntry *entry, gpointer user_data){
	guint client_no;

	// Client-Nr aus dem übergebenen GConf-Entry extrahieren
	client_no = g_ascii_strtoull(g_strstrip(g_strcanon(g_strdup(gconf_entry_get_key(entry)), "0123456789", ' ')), NULL, 0);

	GtkTreeIter citer;									// iterator, der auf das entsprechende Symbol zeigt
	// setzt die Iteratoren an die Position, wo sich das zugehörige Icon des clients findet.
	int j;	
	// GtkTreeModel (die Liste, in der die Symbole gespeichert sind) zugreifbar machen
	GtkTreeModel *model;
	model = gtk_icon_view_get_model(icon_view);
	// iter an erste Position stellen
	gtk_tree_model_get_iter_first(model, &citer);
	// die nötigen Sprünge machen
	for (j=1; j<=g_slist_index(symbols, GUINT_TO_POINTER(client_no)); j++){
		gtk_tree_model_iter_next(model, &citer);
	}

	// Symbol aktualisieren
	gtk_list_store_set (store, &citer, 0, icons[gconf_value_get_int(gconf_entry_get_value(entry))], -1);
}





/*
 Wird bei jeder Änderung der Symbol-Markierungen aufgerufen und demarkiert in der Symbolliste "leere" Symbole.
*/
void Platzhalter_demarkieren(){
	// GtkTreeModel (die Liste, in der die Symbole gespeichert sind) zugreifbar machen
	GtkTreeModel *model = gtk_icon_view_get_model(icon_view);
	// Den Iterator an die erste Stelle springen lassen
	GtkTreeIter iter;   gtk_tree_model_get_iter_first(model, &iter);
	// Durch den Iterator zu dem ersten Pfad (=Symbol) springen
	GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
	// in einer Schleife alle Symbole durchgehen, jedesmal den iter weitersetzen. Wenn Symbol = 0; dann demarkieren
	int i;
	for(i=0; i<=g_slist_length(symbols); i++){
		if (GPOINTER_TO_UINT(g_slist_nth_data(symbols, i)) == 0){
			gtk_icon_view_unselect_path (icon_view, path);
		}
		gtk_tree_path_next(path);
	}
}



/*
 * Popup-Menü anzeigen, die unteren beiden Funktionen sind die Signalhandler
 */
void client_actions_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
{
	GtkWidget *menu;
	int button, event_time;
	menu = glade_xml_get_widget (gxml, "menu2");
	if (event)  {button = event->button;	event_time = event->time;}
	else		{button = 0;				event_time = gtk_get_current_event_time ();}
	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time);
}
gboolean on_iconview1_popup_menu(GtkWidget *widget){client_actions_popup_menu (widget, NULL); return TRUE;}
gboolean on_iconview1_button_press_event(GtkWidget *widget, GdkEventButton *event){
	// Ignore double-clicks and triple-clicks 
	if (event->button == 3 && event->type == GDK_BUTTON_PRESS){client_actions_popup_menu(widget, event); return TRUE;}
	return FALSE;
}