#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <fakekey/fakekey.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>

FakeKey *fakekey;
GtkWidget *window;
GtkWidget *label;
char *key, *prev_key = "";

char *get_key_for_coord(int x, int y, int *cx, int *cy) {
    if (y > 150 && y < 250) {
	if (x > 40 && x < 600) {
	    int xr;

	    xr = x % 56;
	    if (xr < 45) {
		char *p;
		p = malloc(2);
		p[0] = "qwertyuiop"[(x-40)/56];
		p[1] = 0;
		*cy = 200;
		*cx = 40 + ((x-40)/56)*56 + 56/2;
		return p;
	    }
	}
    }
    return "";
}

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

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

void magnify(int x, int y) {
    int cx, cy;
    key = get_key_for_coord(x,
			    y,
			    &cx,
			    &cy);
    printf("magnify key %s prev_key %s\n", key, prev_key);
    if (strcmp(key, prev_key)) {
	prev_key = key;
	if (*key) {
	    char buf[256];
	    int sizex, sizey;

	    sprintf(buf, "<span font_desc=\"Times 72\">%s</span>", key);
	    gtk_label_set_markup(GTK_LABEL(label),
				 buf);
	    gtk_window_get_size(GTK_WINDOW(window), &sizex, &sizey);
	    gtk_window_move(GTK_WINDOW(window),
			    cx - sizex/2,
			    cy - sizey - 40);
	} else {
	    gtk_window_move(GTK_WINDOW(window),
			    -100,
			    -100);
	}
	
    }
}
void motion_notify(GtkWidget *widget, GdkEventMotion *e) {
    g_print("motion %f %f\n",
	    e->x_root,
	    e->y_root);
    magnify(e->x_root,
	    e->y_root);
}

void button_press(GtkWidget *widget, GdkEventButton *e) {
    g_print("button_press %f %f\n",
	    e->x_root,
	    e->y_root);
    magnify(e->x_root,
	    e->y_root);
}

void button_release(GtkWidget *widget, GdkEventButton *e) {
    g_print("button_release %f %f\n",
	    e->x_root,
	    e->y_root);
    if (*key) {
	int ret;
	ret = fakekey_press(fakekey,
			    (unsigned char*)key,
			    1,
			    0);
	assert(ret == 1);
	
	fakekey_release(fakekey);
    }
    magnify(0,0);
}

int main(int argc, char *argv[]) {
    {
	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_POPUP);
	assert(window);

	g_signal_connect(G_OBJECT(window),
			 "delete_event",
			 G_CALLBACK(delete_event), NULL);
	
	g_signal_connect(G_OBJECT(window),
			 "destroy",
			 G_CALLBACK(destroy), NULL);

	g_signal_connect(G_OBJECT(window),
			 "motion_notify_event",
			 G_CALLBACK(motion_notify),
			 NULL);

	g_signal_connect(G_OBJECT(window),
			 "button_press_event",
			 G_CALLBACK(button_press),
			 NULL);

	g_signal_connect(G_OBJECT(window),
			 "button_release_event",
			 G_CALLBACK(button_release),
			 NULL);

	label = gtk_label_new("");
	gtk_container_add(GTK_CONTAINER(window), label);

	gtk_widget_show(label);
	gtk_widget_show(window);
    }
    {
	fakekey = fakekey_init(GDK_DISPLAY());
	assert(fakekey);
    }

    {
	int ret;
	ret = gdk_pointer_grab(window->window,
			       TRUE,
			       GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK |  GDK_BUTTON_RELEASE_MASK,
			       NULL,
			       NULL,
			       GDK_CURRENT_TIME);
	assert(ret == GDK_GRAB_SUCCESS);
    }
    gtk_main();
    return 0;
}

// better text placement
// rethink layout api
// libfakekey-dev libgtk2.0-dev
