#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <errno.h>

// Example GTK program to create and modify a text entry box.
// BSD license.

// Compile: g++ -g -o gtkTextEntryBox gtkTextEntryBox.c `pkg-config --cflags --libs gtk+-2.0` `gnome-config --cflags --libs gnome gnomeui`



typedef struct texts_pointers_ {
	GtkWidget *cas;
	GtkWidget *pocet_bodu;
	GtkWidget *slovo_k_zobrazeni;
} text_pointers;

#define MENU_OPEN 1
#define MENU_QUIT 2

#define CHAR_BUF 2000 /* počet znaků v bloků pro I/O, počet bajtů může být
			 větší, protože se používá UTF-8 */


#define MAX_POCET_SLOV 2000
#define FONT "Sans 84"
#define FONT_SMALL "Sans 40"
#define TEXT_AREA_LENGTH 14
#define TEXT_SMALL_LENGTH 5



GString*  slovnik[MAX_POCET_SLOV];
gint32 pocet_slov = 0;
GtkWidget *window_Widget;
gint32 GlobalTime = 0;
gint32 GlobalPocetBodu = 0;
gboolean GlobalTimerIsRuning = FALSE;
gulong GlobalTimerNr = 0;
/* -1 je správné pocastecni nastaveni, start game ho zvedne o jednicku */
gint32 GlobalAktualniSlovo = -1;
GString *string; /* Text ve view */
GtkItemFactory *main_menu; /* Item factory pro hlavní menu */


static gboolean delete_event( GtkWidget *widget,
                              GdkEvent  *event,
                              gpointer   data )
{
   return FALSE;
}


static void err_msg(const gchar *msg)
{
    GtkWidget *dialog;

    dialog = gtk_message_dialog_new(GTK_WINDOW(window_Widget), 0, GTK_MESSAGE_ERROR,
				    GTK_BUTTONS_OK, msg);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}

static void info_msg(const gchar *msg)
{
    GtkWidget *dialog;

    dialog = gtk_message_dialog_new(GTK_WINDOW(window_Widget), 0, GTK_MESSAGE_INFO,
				    GTK_BUTTONS_OK, msg);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}


static void destroy( GtkWidget *widget,
                     gpointer   data )
{
    gtk_main_quit ();
}


gboolean clock_tick (gpointer data)
{

  gint minutes;
  gint seconds;
  
   GtkWidget  *cas;

  seconds = GlobalTime % 60;
  minutes = GlobalTime / 60;

  while (minutes > 60) {
	minutes -= 60;
  }

  gchar  time[32];
  GlobalTime ++;
  snprintf(time, 32, "%d:%d", minutes, seconds);

  cas = (GtkWidget  *)data;
  gtk_entry_set_text(GTK_ENTRY(cas), time);

  time [31] = 0;
  //g_print (time);
  return TRUE;
}

/**
 * zapocne hru, nastavi inicilani texty po zapoceti hry 
 */
static void start_game( GtkWidget *widget,
                     gpointer   data )
{
	/* ziskani pointeru na data */
    text_pointers *pointers;
    pointers = (text_pointers *) data;
    
    if (pocet_slov == 0){
    	err_msg("Nejprve musíte načíst nějaká slova... (File->Open...)");
    	return;
    }
    
    /* nastavit casovou textareu */
    GlobalTime = 0;
    gtk_entry_set_text(GTK_ENTRY(pointers->cas), "0:0");
    if (!GlobalTimerIsRuning){
    	GlobalTime = 0;
    	GlobalTimerNr = g_timeout_add (1000, clock_tick, (gpointer) pointers->cas );
    	GlobalTimerIsRuning = TRUE;
    }
    
    
    /* Nastavit slovo */
    GlobalAktualniSlovo = (GlobalAktualniSlovo + 1) % pocet_slov;
    gtk_entry_set_text(GTK_ENTRY(pointers->slovo_k_zobrazeni), slovnik[ GlobalAktualniSlovo ]->str);

    /* Nastavit slovo */
    gtk_entry_set_text(GTK_ENTRY(pointers->pocet_bodu), "0");
}


/**
 * zapocne hru, nastavi inicilani texty po zapoceti hry 
 */
static void reset_game( GtkWidget *widget,
                     gpointer   data )
{
	/* ziskani pointeru na data */
    text_pointers *pointers;
    pointers = (text_pointers *) data;
    
    /* nastavit casovou textareu */
    gtk_entry_set_text(GTK_ENTRY(pointers->cas), "0:0");
    if (GlobalTimerIsRuning){
    		GlobalTime = 0;
    		g_source_remove(GlobalTimerNr);
    		GlobalTimerIsRuning = FALSE;
    }
    
    /* Nastavit slovo */
    gtk_entry_set_text(GTK_ENTRY(pointers->slovo_k_zobrazeni), " :-)");

    /* Nastavit slovo */
    gtk_entry_set_text(GTK_ENTRY(pointers->pocet_bodu), "0");
}

static void stop_game( GtkWidget *widget,
                     gpointer   data )
{
	if (GlobalTimerIsRuning){
		g_source_remove(GlobalTimerNr);
		GlobalTimerIsRuning = FALSE;
	}
}

static void next_word( GtkWidget *widget,
                     gpointer   data )
{
	/* ziskani pointeru na data */
    text_pointers *pointers;
    pointers = (text_pointers *) data;
    
    //info_msg(slovnik[ 1 ]->str);
    
    if (pocet_slov == 0){
    	err_msg("Nejprve musíte načíst nějaká slova... (File->Open...)");
    	return;
    }
    
    /* Nastavit slovo */
    GlobalAktualniSlovo = (GlobalAktualniSlovo + 1) % pocet_slov;
    gtk_entry_set_text(GTK_ENTRY(pointers->slovo_k_zobrazeni), slovnik[ GlobalAktualniSlovo ]->str);
    
}

static void previous_word( GtkWidget *widget,
                     gpointer   data )
{
	/* ziskani pointeru na data */
    text_pointers *pointers;
    pointers = (text_pointers *) data;
    
    //info_msg(slovnik[ 1 ]->str);
    
    if (pocet_slov == 0){
    	err_msg("Nejprve musíte načíst nějaká slova... (File->Open...)");
    	return;
    }
    
    /* Nastavit slovo */
    GlobalAktualniSlovo = (GlobalAktualniSlovo + pocet_slov - 1) % pocet_slov;
    gtk_entry_set_text(GTK_ENTRY(pointers->slovo_k_zobrazeni), slovnik[ GlobalAktualniSlovo ]->str);
    
}

static void next_word_points( GtkWidget *widget,
                     gpointer   data ){
	gchar cislo[32];
	
	/* ziskani pointeru na data */
    text_pointers *pointers;
    pointers = (text_pointers *) data;
    
    if (pocet_slov == 0){
    	err_msg("Nejprve musíte načíst nějaká slova... (File->Open...)");
    	return;
    }
    
    next_word(widget, data );
    
    /* Pocet bodu */
    GlobalPocetBodu ++;
    sprintf(cislo, "%d", GlobalPocetBodu);
    gtk_entry_set_text(GTK_ENTRY(pointers->pocet_bodu), cislo);
	
}






/* Načtení souboru zadaného jména, pokud je NULL, zeptá se na jméno. Funkce je
 * komplikovaná tím, že je proveden ještě převod z locale na utf-8
*/

/* Načtení souboru zadaného jména, pokud je NULL, zeptá se na jméno. Funkce je
 * komplikovaná tím, že před vložením do GtkTextBuffer musíme text konvertovat
 * do UTF-8. */
static void load_file(char *fname)
{
    FILE *f;
    char fbuf[CHAR_BUF];
    size_t l;
    GString* slovo;
    GString* message;
    
    string = g_string_new (NULL);
    gchar *ptr;
    
    if(!fname) {
		GtkWidget *dialog = gtk_file_selection_new("Open File...");
		int resp = gtk_dialog_run(GTK_DIALOG(dialog));
		if(resp == GTK_RESPONSE_OK) {
		    fname = g_strdup(
			gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog)));
		    gtk_widget_destroy(dialog);
		} else {
		    gtk_widget_destroy(dialog);
		    return;
		}
    }
    if(!(f = fopen(fname, "r"))) {
    	g_printerr("%s: %s\n", fname, g_strerror(errno));
    	return;
    }

    while((l = fread(fbuf, 1, sizeof(fbuf), f)) > 0) {
		GError *err = NULL;
		gsize br, bw;
		gchar *text;
		if(!(text = g_locale_to_utf8(fbuf, l, &br, &bw, &err))) {
		    g_printerr("Failed locale to UTF-8 conversion: %s\n", err->message);
		    g_clear_error(&err);
		    break;
		}
		//g_print (text);
		g_string_append (string, text);
		g_free(text);
    }
    if(ferror(f)) {
		g_printerr("%s: %s\n", fname, g_strerror(errno));
		fclose(f);
		return;
    }
    if(fclose(f) == EOF) {
    	g_printerr("%s: %s\n", fname, g_strerror(errno));
    }
    
    //g_print (string->str);
    
    // rozparsovani
    slovo = g_string_new (NULL);
    ptr = string->str;
    while (*ptr){
    	  
    	if (*ptr != '\n'){
    		g_string_append_c(slovo, *ptr);
    	} else {
    		//konec slova
    		slovnik[pocet_slov] = slovo;
    		g_print ("Načteno slovo : ");
    		g_print (slovo->str);
    		g_print("\n");
    	
    		slovo = g_string_new (NULL);
    		pocet_slov ++;
    		
    	}
    	if (pocet_slov > MAX_POCET_SLOV) {
    		err_msg("Tento program umí zpracovat jen 2000 slov. Pokud je potřeba víc, je potřeba překompilovat");
    		break;
    	}
    	*ptr++ ;
    }
    if (slovo->str) {
    	slovnik[pocet_slov] = slovo;
    	pocet_slov++;
   		g_print ("Načteno slovo : ");
    	g_print (slovo->str);
    	g_print("\n");
    }
    
    message = g_string_new (NULL);
    g_string_append_printf(message, "Bylo načteno %d slov", pocet_slov);
    //g_print(message->str);
    info_msg(message->str);
    g_string_free (message, TRUE);
    g_string_free (string, TRUE);
}



/* Zpracování výběru z menu */
static void menu_fun(gpointer data, guint action, GtkWidget *widget)
{
    //GtkTextIter p, q;
    // GtkWidget *dialog;
    
    switch(action) {
    case MENU_OPEN:
	    load_file(NULL);
	break;
    case MENU_QUIT:
   	    gtk_widget_destroy(window_Widget);
   	break;
    default:
    	g_printerr("Unknown menu action %u\n", action);
	break;
    }
}


GtkItemFactoryEntry menu_def[] = {
        { (char *)"/_File", NULL, NULL, 0, (char *)"<Branch>", NULL },
        { (char *)"/File/_Open...", (char *)"<control>O", menu_fun, MENU_OPEN, (char *)"<StockItem>", GTK_STOCK_OPEN },
        { (char *)"/File/_Quit", (char *)"<control>Q", menu_fun, MENU_QUIT, (char *)"<StockItem>", GTK_STOCK_QUIT },
    };
    





int main( int   argc, char *argv[] )
{

    GtkWidget *button, *widget;
    GtkWidget *vBox_Widget;
 //   GtkWidget *boxLabel_Widget;
    GtkWidget *slovo_k_zobrazeni, *pocet_bodu, *cas;
    GtkWidget *textLabel_Widget;
    GtkWidget *table, *table1;
    char       textLabel[64];
    GtkAccelGroup *accel;

    GdkColor colorBlack;
    GdkColor colorGreen;

//    GtkTextIter start, end;
    PangoFontDescription *font_desc;
    GdkColor color;

    // black
    colorBlack.red=0;
    colorBlack.green=0;
    colorBlack.blue=0;

    // Green
    colorGreen.red=0;
    colorGreen.green=65535;
    colorGreen.blue=0;

    text_pointers pointers;

    gtk_init (&argc, &argv);
    window_Widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window_Widget), "Hra Kufr");

    g_signal_connect (G_OBJECT (window_Widget), "delete_event",
                      G_CALLBACK (delete_event), NULL);

    g_signal_connect (G_OBJECT (window_Widget), "destroy",
                      G_CALLBACK (destroy), NULL);

    gtk_container_set_border_width (GTK_CONTAINER (window_Widget), 10);

    vBox_Widget = gtk_vbox_new (FALSE, 0);
    
    	accel = gtk_accel_group_new();
        gtk_window_add_accel_group(GTK_WINDOW(window_Widget), accel);
        main_menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<TextView>", accel);
        gtk_item_factory_create_items(main_menu,
    				  sizeof(menu_def) / sizeof(*menu_def),
    				  menu_def, NULL);
        widget = gtk_item_factory_get_widget(main_menu, "<TextView>");
        gtk_box_pack_start(GTK_BOX(vBox_Widget), widget, FALSE, FALSE, 0);
        gtk_widget_show (widget);
    

    char *textLabel0="Hádané slovo";
    sprintf(textLabel, "<small>%s</small>",textLabel0);

    textLabel_Widget = gtk_label_new (textLabel);
    gtk_label_set_markup(GTK_LABEL (textLabel_Widget),textLabel);
    gtk_label_set_justify(GTK_LABEL (textLabel_Widget),GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment (GTK_MISC (textLabel_Widget), 0, 0.5);
    gtk_widget_show (textLabel_Widget);
    gtk_box_pack_start( GTK_BOX (vBox_Widget),
                        textLabel_Widget,
                        FALSE,
                        TRUE,
                        0);

    // --------------------------------------------------------------------
    // Create text entry widget and modify.
    // --------------------------------------------------------------------

    slovo_k_zobrazeni = gtk_entry_new();
    pointers.slovo_k_zobrazeni = slovo_k_zobrazeni;
    pocet_bodu = gtk_entry_new();
    cas = gtk_entry_new();

    gtk_widget_modify_base(slovo_k_zobrazeni, GTK_STATE_NORMAL, &colorBlack);

    GtkStyle *style = gtk_widget_get_style(slovo_k_zobrazeni);

    pango_font_description_set_weight(style->font_desc, PANGO_WEIGHT_BOLD);
    gtk_widget_modify_font(slovo_k_zobrazeni, style->font_desc);

    // Šířka oblasti, kde se bude zobrazovat text (v počtu písmenek)
    int        text_width = TEXT_AREA_LENGTH;
    gtk_entry_set_width_chars(GTK_ENTRY(slovo_k_zobrazeni), text_width);

    gtk_editable_set_editable(GTK_EDITABLE(slovo_k_zobrazeni), FALSE);
    GTK_WIDGET_UNSET_FLAGS(slovo_k_zobrazeni, GTK_CAN_FOCUS);

    char *txtBuffer = "Zde bude slovo";
    gtk_entry_set_text(GTK_ENTRY(slovo_k_zobrazeni), txtBuffer);


     /* Change default color throughout the widget */
     gdk_color_parse ("yellow", &color);
     gtk_widget_modify_text (slovo_k_zobrazeni, GTK_STATE_NORMAL, &color);

     /* Change default font throughout the widget */
     font_desc = pango_font_description_from_string (FONT);
     gtk_widget_modify_font (slovo_k_zobrazeni, font_desc);
     pango_font_description_free (font_desc);







    style = gtk_widget_get_style(cas);
    pointers.cas = cas;

    pango_font_description_set_weight(style->font_desc, PANGO_WEIGHT_BOLD);
    gtk_widget_modify_font(cas, style->font_desc);

    // Šířka oblasti, kde se bude zobrazovat text (v počtu písmenek)
    text_width = TEXT_SMALL_LENGTH;
    gtk_entry_set_width_chars(GTK_ENTRY(cas), text_width);

    gtk_editable_set_editable(GTK_EDITABLE(cas), FALSE);
    GTK_WIDGET_UNSET_FLAGS(cas, GTK_CAN_FOCUS);

    gtk_entry_set_text(GTK_ENTRY(cas), "Čas");


     /* Change default color throughout the widget */
     gdk_color_parse ("yellow", &color);
     gtk_widget_modify_text (cas, GTK_STATE_NORMAL, &color);

     /* Change default font throughout the widget */
     font_desc = pango_font_description_from_string (FONT_SMALL);
     gtk_widget_modify_font (cas, font_desc);
     pango_font_description_free (font_desc);

    gtk_widget_modify_base(cas, GTK_STATE_NORMAL, &colorBlack);


    style = gtk_widget_get_style(pocet_bodu);
    pointers.pocet_bodu = pocet_bodu;

    pango_font_description_set_weight(style->font_desc, PANGO_WEIGHT_BOLD);
    gtk_widget_modify_font(pocet_bodu, style->font_desc);

    // Šířka oblasti, kde se bude zobrazovat text (v počtu písmenek)
    text_width = TEXT_SMALL_LENGTH;
    gtk_entry_set_width_chars(GTK_ENTRY(pocet_bodu), text_width);

    gtk_editable_set_editable(GTK_EDITABLE(pocet_bodu), FALSE);
    GTK_WIDGET_UNSET_FLAGS(pocet_bodu, GTK_CAN_FOCUS);

    gtk_entry_set_text(GTK_ENTRY(pocet_bodu), "Body");


     /* Change default color throughout the widget */
     gdk_color_parse ("yellow", &color);
     gtk_widget_modify_text (pocet_bodu, GTK_STATE_NORMAL, &color);

     /* Change default font throughout the widget */
     font_desc = pango_font_description_from_string (FONT_SMALL);
     gtk_widget_modify_font (pocet_bodu, font_desc);
     pango_font_description_free (font_desc);
     gtk_widget_modify_base(pocet_bodu, GTK_STATE_NORMAL, &colorBlack);







    // --------------------------------------------------------------------

    //gtk_box_pack_start (GTK_BOX (vBox_Widget), slovo_k_zobrazeni, TRUE, TRUE, 0);
    gtk_container_add (GTK_CONTAINER (window_Widget), vBox_Widget);    
    
    table1 = gtk_table_new (2, 2, FALSE);

    //gtk_container_add (GTK_CONTAINER (vBox_Widget), table1);

	gtk_box_pack_start( GTK_BOX (vBox_Widget),
                        table1,
                        FALSE,
                        TRUE,
                        0);


    gtk_table_attach_defaults (GTK_TABLE (table1), slovo_k_zobrazeni, 0, 1, 0, 2);
    gtk_widget_show (slovo_k_zobrazeni);
    gtk_table_attach(GTK_TABLE (table1), pocet_bodu, 1, 2, 0, 1, 0, 0, 0, 0);
    gtk_widget_show (pocet_bodu);
    gtk_table_attach(GTK_TABLE (table1), cas, 1, 2, 1, 2 , 0, 0, 0, 0);
    gtk_widget_show (cas);


    table = gtk_table_new (5, 3, TRUE);

    	gtk_box_pack_start( GTK_BOX (vBox_Widget),
                        table,
                        FALSE,
                        TRUE,
                        0);

    /* Vytvorime si cudliky, pomoci ktere se bude prechazet mezi slovy */
    button = gtk_button_new_with_label ("<< Předchozí slovo");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
	              G_CALLBACK (previous_word), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);

    button = gtk_button_new_with_label ("Následující slovo (Bez bodů) >>");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
	              G_CALLBACK (next_word), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 0, 1);

    button = gtk_button_new_with_label ("Následující slovo (přičíst body) >>");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
	              G_CALLBACK (next_word_points), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 3, 0, 1);

    button = gtk_button_new_with_label ("Start!");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
	              G_CALLBACK (start_game), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 3, 1, 2);

    button = gtk_button_new_with_label ("Stop!");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
	              G_CALLBACK (stop_game), (gpointer) "button 1");
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 3, 2, 3);
    
    button = gtk_button_new_with_label ("Reset!");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
 	              G_CALLBACK (reset_game), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 3, 3, 4);
 
    button = gtk_button_new_with_label ("Konec (zavřít okno)!");
    gtk_widget_show (button);
    g_signal_connect (G_OBJECT (button), "clicked",
 	              G_CALLBACK (destroy), (gpointer) &pointers);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 3, 4, 5);    


    
    
    
    gtk_widget_show (table1);
    gtk_widget_show (table);
    gtk_widget_show (vBox_Widget); 
    gtk_window_fullscreen(GTK_WINDOW(window_Widget));
    gtk_widget_show (window_Widget);
    

    gtk_main ();

    return 0;
}
