#include <stdio.h>

#include "aux_module.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

AuxResult neima_aux_Start(aux_ext_data_t *aux_ext_data);
AuxResult neima_aux_Draw(aux_ext_data_t *aux_ext_data);
AuxResult neima_aux_Done(aux_ext_data_t *aux_ext_data);

AuxModuleMethodsRec aux_module_methods = {
	neima_aux_Start,
	neima_aux_Draw,
	neima_aux_Done
};

AuxModuleRec neima_aux_module = {
	NULL,
	NULL,
	"com.sun.iiim.cle.aux.neima",
	&aux_module_methods,
};

static GtkWidget *_toolbar = NULL;
static GtkWidget *_label = NULL;

static gboolean	_toolbar_draging      = FALSE;
static gint	_toolbar_drag_x       = 0;
static gint	_toolbar_drag_y       = 0;

static gint	_toolbar_pos_x 	     = 0;
static gint	_toolbar_pos_y 	     = 0;

static gboolean	_toolbar_show_status  = FALSE;

static int
ui_screen_width (void)
{
    return gdk_screen_width ();
}

static int
ui_screen_height (void)
{
    return gdk_screen_height ();
}

static void ui_toolbar_set_position (gint pos_x, gint pos_y)
{
    GtkRequisition ws;

    gtk_widget_size_request (_toolbar, &ws);
                                                                                                         
    if (pos_x <= 0) {
        pos_x = ui_screen_width () - 400;
    } else if (pos_x + ws.width > ui_screen_width ()) {
        pos_x = ui_screen_width () - ws.width;
    }

    if (pos_y <= 0) {
        pos_y = ui_screen_height () - 76;
    } else if (pos_y + ws.height > ui_screen_height ()) {
        pos_y = ui_screen_height () - ws.height;
    }
                                                                                                                  
    if (_toolbar_pos_x != pos_x || _toolbar_pos_y != pos_y) {
        gtk_window_move (GTK_WINDOW (_toolbar), pos_x, pos_y);
        _toolbar_pos_x = pos_x;
        _toolbar_pos_y = pos_y;
    }
}

static gboolean
ui_toolbar_motion_cb (GtkWidget *window,
                             GdkEventMotion *event,
                             gpointer user_data)
{
    gint pos_x, pos_y;
    if ((event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) != 0 &&
        _toolbar_draging) {
        gtk_window_get_position (GTK_WINDOW (window), &pos_x, &pos_y);
        ui_toolbar_set_position(
            pos_x + ((gint) event->x_root - _toolbar_drag_x),
            pos_y + ((gint) event->y_root - _toolbar_drag_y));

        _toolbar_drag_x = (gint) event->x_root;
        _toolbar_drag_y = (gint) event->y_root;

        return TRUE;
    }
    return FALSE;
}
                                                                                                          
static gboolean
ui_toolbar_click_cb (GtkWidget *window,
                            GdkEventButton *event,
                            gpointer user_data)
{
    int click_type = GPOINTER_TO_INT (user_data);
    static gulong motion_handler;
    GdkCursor *cursor;
                                                                                                          
    if (click_type == 0 && event->button <= 1) {
        if (_toolbar_draging)
            return FALSE;
                                                                                                          
        // Connection pointer motion handler to this window.
        motion_handler = g_signal_connect (G_OBJECT (window), "motion-notify-event",
                                           G_CALLBACK (ui_toolbar_motion_cb),
                                           NULL);
                                                                                                          
        _toolbar_draging = TRUE;
        _toolbar_drag_x = (gint) event->x_root;
        _toolbar_drag_y = (gint) event->y_root;
                                                                                                          
        cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
                                                                                                          
        // Grab the cursor to prevent losing events.
        gdk_pointer_grab (window->window, TRUE,
                          (GdkEventMask) (GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
                          NULL, cursor, event->time);
        gdk_cursor_unref (cursor);
        return TRUE;
    } else if (click_type == 1 && event->button <= 1) {
        if (!_toolbar_draging)
            return FALSE;
                                                                                                          
        g_signal_handler_disconnect (G_OBJECT (window), motion_handler);
        gdk_pointer_ungrab (event->time);
        _toolbar_draging = FALSE;

        return TRUE;
    } else if (click_type == 1 && event->button > 1) {
        return TRUE;
    }
    return FALSE;
}

static void GetWindowPosition(Display *display, Window clientwindow, int *win_x, int *win_y)
{
	int x=0, y=0;
	Window w_none;
	XWindowAttributes attr;

	if (clientwindow && display) {
		XGetWindowAttributes(display, clientwindow, &attr);
		if (attr.root)
			XTranslateCoordinates(display, clientwindow, 
				attr.root, -(attr.border_width), -(attr.border_width), &x, &y,
				 &w_none );
	}
	*win_x = x;
	*win_y = y;
}

static void GetDefaultPosition(int *win_x, int *win_y)
{
	GtkRequisition ws;

	gtk_widget_size_request (_toolbar, &ws);

	*win_x = (gdk_screen_width () > 640)?200:100;
	*win_y = (gdk_screen_height () - ws.height - 10 - 36);
}


static void SetCandidateAuxPosition(aux_ext_data_t *aux_ext_data)
{
	int win_x = 0, win_y = 0;

	GetWindowPosition((Display *)GDK_WINDOW_XDISPLAY(_toolbar->window), aux_ext_data->clientwin, &win_x, &win_y);
	if ((win_x == 0 && win_y == 0) || 
	    (aux_ext_data->point.x == 0 && aux_ext_data->point.y == 0)) {
		GetDefaultPosition(&win_x, &win_y);
	} else {
		win_x += aux_ext_data->point.x;
		win_y += aux_ext_data->point.y + 22;
	}

	ui_toolbar_set_position(win_x, win_y);
}

AuxResult neima_aux_Start(aux_ext_data_t *aux_ext_data)
{
	GtkWidget *frame;
	GtkWidget *hbox;

	printf("_toolbar: %p\n", _toolbar);

	if (_toolbar != NULL) {
		return (AUX_OK);
	}

        _toolbar = gtk_window_new (GTK_WINDOW_POPUP);
        gtk_window_set_policy (GTK_WINDOW (_toolbar), TRUE, TRUE, FALSE);
        gtk_window_set_resizable (GTK_WINDOW (_toolbar), FALSE);
        gtk_widget_add_events (_toolbar,GDK_BUTTON_PRESS_MASK);
        gtk_widget_add_events (_toolbar,GDK_BUTTON_RELEASE_MASK);
        gtk_widget_add_events (_toolbar,GDK_POINTER_MOTION_MASK);
        g_signal_connect (G_OBJECT (_toolbar), "button-press-event",
                          G_CALLBACK (ui_toolbar_click_cb),
                          GINT_TO_POINTER (0));
        g_signal_connect (G_OBJECT (_toolbar), "button-release-event",
                          G_CALLBACK (ui_toolbar_click_cb),
                          GINT_TO_POINTER (1));

	gtk_container_set_border_width (GTK_CONTAINER (_toolbar), 0);

        frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
        gtk_container_add (GTK_CONTAINER (_toolbar), frame);

        //New status button.
        _label = gtk_label_new("1.    2.    3.    4.    5.    6.    7.    8.    9.    0.    ");
        gtk_container_add (GTK_CONTAINER (frame), _label);

	gtk_widget_realize(_toolbar);
	_toolbar_show_status = TRUE;
                                                                                                         
        ui_toolbar_set_position(0, 0);
	return (AUX_OK);
}

AuxResult neima_aux_Draw(aux_ext_data_t *aux_ext_data)
{
	int integer_count;
	int string_count;
	char candidate_buf[2048];
	int encoding;
	int i;
	
	integer_count = aux_ext_data->integer_count;
	printf("integer_count: %d\n", integer_count);
	if (integer_count < 1)
		return (AUX_OK);

	string_count = aux_ext_data->string_count;
	printf("string_count: %d\n", string_count);
	if (string_count <= 1)
		return (AUX_OK);

	encoding = aux_ext_data->integer_list[0];
	printf("encoding: %d\n", encoding);

	memset(candidate_buf, 0, sizeof(char) * 2048);
	for (i=0; i < string_count; i++) {
		char label[10];
		unsigned char tmp_buf[512];
		unsigned char *tmp_ptr = tmp_buf;
		int from_len, to_left;
		int ret;

		aux_ext_data->string_list[i].ptr[aux_ext_data->string_list[i].length] = 0;
		printf("string: %s, len:  %d\n", aux_ext_data->string_list[i].ptr,  aux_ext_data->string_list[i].length);
/*
*/

		from_len = aux_ext_data->string_list[i].length;
		to_left = 512;
		memset(tmp_buf, 0, sizeof(char) * 512);
		ret = Convert_Native_To_UTF8(   encoding,
						aux_ext_data->string_list[i].ptr,
						from_len,
						(char **)&tmp_ptr,
						(size_t *)&to_left);
		
        	if (ret == -1) return (AUX_FAIL);

		tmp_buf[512-to_left] = 0;
		snprintf(label, 10, " %d: ", (i+1)%10);
		strcat(candidate_buf, label);
		strcat(candidate_buf, tmp_buf);
		if (i != string_count - 1) strcat(candidate_buf, " \n");
	}

	if (_toolbar != NULL) {
		printf("%s\n", candidate_buf);
		gtk_label_set_text(GTK_LABEL(_label), candidate_buf);
		gtk_widget_show_all(_toolbar);
		printf("x: %d, y: %d\n", aux_ext_data->point.x, aux_ext_data->point.y);
		SetCandidateAuxPosition(aux_ext_data);
/*
		printf("neima screen num: %d\n", gtk_widget_get_screen(GTK_WIDGET(_toolbar)));
		gtk_window_set_screen(GTK_WINDOW(_toolbar), gtk_widget_get_screen(GTK_WIDGET(_toolbar)));
*/
	}

	return (AUX_OK);
}

AuxResult neima_aux_Done(aux_ext_data_t *aux_ext_data)
{
	if (_toolbar != NULL) {
		gtk_widget_hide(_toolbar);
	}
	return (AUX_OK);
}
