/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     Internet Radio Automation & Encoding Toolkit
#+
#+     Copyright (C) 2018, 2019, 2020 by Kevin C. O'Kane
#+
#+     Kevin C. O'Kane
#+     kc.okane@gmail.com
#+     https://www.cs.uni.edu/~okane
#+     https://threadsafebooks.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
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

// July 23, 2020

#define _GNU_SOURCE

#include <X11/Xlib.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <ctype.h>
#include <time.h>

GtkWidget       *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12;
GtkWidget	*image[12], *appImage;	// images to be placed in buttons
GtkBuilder	*builder;
GtkWidget	*window, *imageWindow;	// main and popup windows
GtkWidget	*fixed1, *fixed2;	// main and popup containers

GdkPixbuf	*pix[12];	// scaled pictures
GdkPixbuf	*pixIn[12];	// original (unscaled) pictures
GdkPixbuf	*tmp_pixbuf;	// temp storage
GdkPixbuf	*source_pixbuf;	// temp storage

void		on_window_main_destroy() ;

int		drag_source, drag_target;
GtkCssProvider  *cssProvider_button;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	paint css on a widget
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void	css_set(GtkCssProvider * cssProvider, GtkWidget *g_widget) {
	GtkStyleContext *context;
	context = gtk_widget_get_style_context(g_widget);
	gtk_style_context_add_provider (context,
		GTK_STYLE_PROVIDER(cssProvider), 1000);
	}


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

	char tmp[1024];

	gtk_init(&argc, &argv);

        builder = gtk_builder_new_from_resource ("/part1/pics.glade");

        window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));

        gtk_builder_connect_signals(builder, NULL);

        g_signal_connect(window, "destroy", G_CALLBACK(on_window_main_destroy), NULL);

	fixed2		= GTK_WIDGET(gtk_builder_get_object(builder, "fixed2"));	// popup window container
	imageWindow	= GTK_WIDGET(gtk_builder_get_object(builder, "imageWindow"));	// popup window
	appImage	= GTK_WIDGET(gtk_builder_get_object(builder, "appImage"));	// popup window image

	p1		= GTK_WIDGET(gtk_builder_get_object(builder, "p1"));		// buttons
	p2		= GTK_WIDGET(gtk_builder_get_object(builder, "p2"));
	p3		= GTK_WIDGET(gtk_builder_get_object(builder, "p3"));
	p4		= GTK_WIDGET(gtk_builder_get_object(builder, "p4"));
	p5		= GTK_WIDGET(gtk_builder_get_object(builder, "p5"));
	p6		= GTK_WIDGET(gtk_builder_get_object(builder, "p6"));
	p7		= GTK_WIDGET(gtk_builder_get_object(builder, "p7"));
	p8		= GTK_WIDGET(gtk_builder_get_object(builder, "p8"));
	p9		= GTK_WIDGET(gtk_builder_get_object(builder, "p9"));
	p10		= GTK_WIDGET(gtk_builder_get_object(builder, "p10"));
	p11		= GTK_WIDGET(gtk_builder_get_object(builder, "p11"));
	p12		= GTK_WIDGET(gtk_builder_get_object(builder, "p12"));

	image[0]		= GTK_WIDGET(gtk_builder_get_object(builder, "image1")); //images
	image[1]		= GTK_WIDGET(gtk_builder_get_object(builder, "image2"));
	image[2]		= GTK_WIDGET(gtk_builder_get_object(builder, "image3"));
	image[3]		= GTK_WIDGET(gtk_builder_get_object(builder, "image4"));
	image[4]		= GTK_WIDGET(gtk_builder_get_object(builder, "image5"));
	image[5]		= GTK_WIDGET(gtk_builder_get_object(builder, "image6"));
	image[6]		= GTK_WIDGET(gtk_builder_get_object(builder, "image7"));
	image[7]		= GTK_WIDGET(gtk_builder_get_object(builder, "image8"));
	image[8]		= GTK_WIDGET(gtk_builder_get_object(builder, "image9"));
	image[9]		= GTK_WIDGET(gtk_builder_get_object(builder, "image10"));
	image[10]		= GTK_WIDGET(gtk_builder_get_object(builder, "image11"));
	image[11]		= GTK_WIDGET(gtk_builder_get_object(builder, "image12"));

	fixed1		= GTK_WIDGET(gtk_builder_get_object(builder, "fixed1"));

	GError *err;

	FILE *f1 = popen("ls album", "r");

	char ftmp[1024], filename[1024];
	int i = 0, lx;

	while (1) { 
		if (!fgets(ftmp, 1024, f1)) break;
		ftmp[strlen(ftmp)-1] = 0;	// chop new line character
		strcpy(filename, "album/");	// subdirectory
		strcat(filename, ftmp);		// image file name
		printf("%s\n", filename);
		err = NULL;
		pixIn[i] = gdk_pixbuf_new_from_file (filename, &err);			   // unscaled pixbuf
		pix[i] = gdk_pixbuf_scale_simple (pixIn[i], 150, 100, GDK_INTERP_NEAREST); // scaled pixbuf
		gtk_image_set_from_pixbuf (image[i], pix[i]);
		i++;
		if (i >= 12) break;
		}

	fclose(f1);

//	add some fancy button effects

        cssProvider_button = gtk_css_provider_new();
        gtk_css_provider_load_from_resource(cssProvider_button, "/part1/css/albumButton.css");

        css_set(cssProvider_button, p1 );
        css_set(cssProvider_button, p2 );
        css_set(cssProvider_button, p3 );
        css_set(cssProvider_button, p4 );
        css_set(cssProvider_button, p5 );
        css_set(cssProvider_button, p6 );
        css_set(cssProvider_button, p7 );
        css_set(cssProvider_button, p8 );
        css_set(cssProvider_button, p9 );
        css_set(cssProvider_button, p10 );
        css_set(cssProvider_button, p11 );
        css_set(cssProvider_button, p12 );

	gtk_widget_show(window);

	GdkColor color; 
	color.red = 0x5555; color.green = 0x5555; color.blue = 0x6666;

	gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);

	gtk_widget_show_all(window); 

        gtk_window_move(GTK_WINDOW(window), 230, 300);		// position windows
        gtk_window_move(GTK_WINDOW(imageWindow), 900, 300);

	GtkTargetEntry targs[1] = {"dummy", GTK_TARGET_SAME_APP, 1};

//	GtkTargetEntry structure:
//		gchar *target;
//		guint  flags;
//		guint  info;

//	GDK_BUTTON1_MASK means first (left) mouse button
//	GTK_DESTINATION_DEFAULT_ALL turns on all options 

//	macro code -------------------------

//	enable up drag/drop permissions

#define P_BUTTON_DRAG_SETUP(NBR) \
	gtk_drag_source_set(p## NBR, GDK_BUTTON1_MASK, targs, 1, GDK_ACTION_COPY);					\
	gtk_drag_dest_set(p## NBR , GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_MOTION,	\
		targs, 1, GDK_ACTION_COPY);


        P_BUTTON_DRAG_SETUP(1) P_BUTTON_DRAG_SETUP(2) P_BUTTON_DRAG_SETUP(3) P_BUTTON_DRAG_SETUP(4) 
	P_BUTTON_DRAG_SETUP(5) P_BUTTON_DRAG_SETUP(6) P_BUTTON_DRAG_SETUP(7) P_BUTTON_DRAG_SETUP(8) 
	P_BUTTON_DRAG_SETUP(9) P_BUTTON_DRAG_SETUP(10) P_BUTTON_DRAG_SETUP(11) P_BUTTON_DRAG_SETUP(12)

	gtk_widget_hide(imageWindow);	// show when needed

	gtk_main(); // here we go!

	}

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

void on_window_main_destroy() {
	gtk_main_quit();
	}

//	Don't destroy popup window - hide it

gboolean	on_imageWindow_delete_event(GtkWindow *w) {
		gtk_widget_hide(imageWindow);
		return TRUE; // no further processing
		}

//	macro code -------------------------

//	button left click

#define P_BUTTON_CLICKED(NBR)					\
        void on_p## NBR ##_clicked(GtkWidget *b) {		\
        	printf("left click %d\n", NBR); 		\
		}

	P_BUTTON_CLICKED(1) P_BUTTON_CLICKED(2)  P_BUTTON_CLICKED(3)  P_BUTTON_CLICKED(4)  
	P_BUTTON_CLICKED(5) P_BUTTON_CLICKED(6) P_BUTTON_CLICKED(7) P_BUTTON_CLICKED(8)
	P_BUTTON_CLICKED(9)  P_BUTTON_CLICKED(10) P_BUTTON_CLICKED(11) P_BUTTON_CLICKED(12)

//	macro code - several routines ------

//	drag functions
//	Note: always use /* ... */ style comments in macros and not // style

#define P_BUTTON_DRAG(NBR)  									\
        void on_p## NBR ##_drag_begin (GtkWidget *w, GdkDragContext *dc) {			\
			/* drag has begun */							\
			printf("drag begin %d\n", NBR);						\
                        drag_source =  NBR;  							\
                        }									\
												\
        void on_p## NBR ##_drag_drop (GtkWidget *w, GdkDragContext *dc) {			\
			/* drag has ended (button released) */					\
			/* NBR will be number of target button */				\
			printf("drop %d\n", NBR);						\
                        drag_target = NBR; /* buttton number 1-12 */				\
                        }									\
												\
        void on_p## NBR ##_drag_data_get (GtkWidget *w, GdkDragContext *dc) {			\
			/*** drag has ended (button released) */				\
			/*** NBR will be NBR of source button - not used here */		\
			printf("get %d\n", NBR);						\
                        }									\
												\
        void on_p## NBR ##_drag_end (GtkWidget *w, GdkDragContext *dc) {			\
		/* last function to be called */  						\
                printf("move from tile %d to tile %d\n", drag_source, drag_target);		\
		/*** swap scaled pixbufs */							\
		tmp_pixbuf = pix [ drag_target - 1];						\
		pix[ drag_target - 1] = pix[ drag_source - 1];					\
		pix[ drag_source - 1] = tmp_pixbuf;						\
		/*** swap un-scaled pixbufs */							\
		tmp_pixbuf = pixIn [ drag_target - 1];						\
		pixIn[ drag_target - 1] = pixIn[ drag_source - 1];				\
		pixIn[ drag_source - 1] = tmp_pixbuf; 						\
		/*** re-paint images */								\
		gtk_image_set_from_pixbuf (image[drag_target - 1], pix[drag_target - 1]);	\
		gtk_image_set_from_pixbuf (image[drag_source - 1], pix[drag_source - 1]);	\
                drag_source = drag_target = -1; }

	P_BUTTON_DRAG(1) P_BUTTON_DRAG(2)  P_BUTTON_DRAG(3)  P_BUTTON_DRAG(4)
	P_BUTTON_DRAG(5) P_BUTTON_DRAG(6)  P_BUTTON_DRAG(7)  P_BUTTON_DRAG(8)
	P_BUTTON_DRAG(9) P_BUTTON_DRAG(10) P_BUTTON_DRAG(11) P_BUTTON_DRAG(12)

//	macro code -------------------------

#define P_BUTTON_PRESS(NBR)  \
        gboolean on_p## NBR ##_button_press_event							\
                (GtkButton *btn, GdkEventButton *event, gpointer user_data) {				\
		printf("button press %d\n", NBR);							\
                if (event->state == GDK_CONTROL_MASK) printf("ctrl key pressed\n");			\
		/* return TRUE: no futher processing of this signal */					\
		/* return FALSE: continue processing this signal */					\
                if (event->button == 1 ) return FALSE; /* left click - processing done elsewhere */	\
                printf("right click\n");								\
		gtk_widget_show(imageWindow); /* show popup window */					\
        	gtk_window_move(GTK_WINDOW(imageWindow), 900, 300); /* reposition it */			\
		/* scale popup window image */								\
		tmp_pixbuf = gdk_pixbuf_scale_simple (pixIn[NBR - 1], 640, 480, GDK_INTERP_NEAREST);	\
		gtk_image_set_from_pixbuf (appImage, tmp_pixbuf);					\
		g_object_unref(tmp_pixbuf); /* no longer needed - free it */				\
                return TRUE;  /* no further processing for this event */				\
                }

	P_BUTTON_PRESS(1) P_BUTTON_PRESS(2)  P_BUTTON_PRESS(3)  P_BUTTON_PRESS(4)
	P_BUTTON_PRESS(5) P_BUTTON_PRESS(6)  P_BUTTON_PRESS(7)  P_BUTTON_PRESS(8)
	P_BUTTON_PRESS(9) P_BUTTON_PRESS(10) P_BUTTON_PRESS(11) P_BUTTON_PRESS(12)

