#/* gtk2 alternative to xmessage 
# * by Erik Waling <erikw@acc.umu.se> 

echo "Compiling gmessage..."
a="cc"
b="-s $CFLAGS `pkg-config --cflags gtk+-2.0`  `pkg-config --libs gtk+-2.0`"
c="-o `basename "$0" .c` $0"
echo "$a $b $c"
if $a $b $c;then echo -n
else echo "$a $c"
  if $a $c;then echo -n
  else echo "Failed - please check the output.";exit
  fi
fi
echo "done."
exit
*/

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <gtk/gtk.h>

#define BUFSIZE 8192

static void cb_destroy(GtkWidget *widget, gpointer data) {

    gtk_main_quit();
}

static gboolean cb_delete_event(GtkWidget *widget, GdkEvent  *event, gpointer data) {

    return FALSE;
}

void msg_from_file(GtkTextBuffer *buf, GtkTextIter *it, gchar *name);
void print_usage(void);

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

    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *scrollwin;
    GtkWidget *button;
    GtkWidget *textview;
    
    GtkTextBuffer *buffer;
    GtkTextIter   iter;
    PangoFontDescription *fontdesc;
    
    gint     optindex = 0;
    gint     ret;
    gchar    *filename = NULL;
    gchar    *fontname = NULL;
    gboolean center = FALSE;
    gboolean nearmouse = FALSE;
    gboolean popup = FALSE;
    gboolean sticky = FALSE;
    gint     height = -1;
    gint     width = -1;
    
    struct option long_options[] = {
        {"file"         , required_argument, 0          , 'f'},
        {"timeout"      , required_argument, 0          , 't'},
        {"center"       , no_argument      , 0          , 'c'},
        {"nearmouse"    , no_argument      , 0          , 'n'},
        {"popup"        , no_argument      , 0          , 'p'},
        {"sticky"       , no_argument      , 0   	, 'S'},
        {"size"         , required_argument, 0          , 's'},
        {"font"         , required_argument, 0          , 'F'},
        {"help"         , no_argument      , 0          , 'h'},
        {0              , 0                , 0          , 0  }
    };

    gtk_init(&argc, &argv);

    while ((ret = getopt_long_only(argc, argv, "f:t:hcnpSs:F:", long_options, &optindex)) != -1) {
        
        switch (ret) {
            case '?':
                printf("\nTry `gmessage --help' for help.\n");
                exit(-1);
                break;
            case 'f':
                filename = &optarg[0];
                break;
            case 't':
                signal(SIGALRM, (void *) gtk_main_quit);
                alarm(atoi(optarg));
                break;
            case 'c':
                center = TRUE;
                nearmouse = FALSE;
                break;
            case 'n':
                nearmouse = TRUE;
                center = FALSE;
                break;
            case 'p':
                popup = TRUE;
                break;
            case 'S':
                sticky = TRUE;
                break;
            case 's':
                width = atoi(optarg);
                while (*optarg++ != '\0') 
                    if (*optarg == 'x' || *optarg == 'X')
                        height = atoi(optarg+1);
                break;
            case 'h':
                print_usage();
                exit(0);
                break;
            case 'F':
                fontname = &optarg[0];
                break;
        
        }
    }
    
    window = gtk_window_new(popup ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width(GTK_CONTAINER(window), 5);
    gtk_window_set_title(GTK_WINDOW(window), "gmessage");
    if (sticky)
        gtk_window_stick(GTK_WINDOW(window));
    if (height > 0 && width > 0)
        gtk_window_set_default_size(GTK_WINDOW(window), width, height);
    else
        gtk_window_set_default_size(GTK_WINDOW(window), 300, 150);
    

    vbox = gtk_vbox_new(FALSE, 3);
    gtk_container_add(GTK_CONTAINER(window), vbox);
    gtk_widget_show(vbox);
    
    scrollwin = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin), GTK_SHADOW_ETCHED_IN);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
    gtk_widget_show(scrollwin);
    
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    gtk_widget_show(hbox);
    
    button = gtk_button_new_from_stock(GTK_STOCK_OK);
    gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
    gtk_widget_grab_focus(button);
    gtk_widget_show(button);
    
    
    textview = gtk_text_view_new();
    if (fontname) {
        fontdesc = pango_font_description_from_string(fontname);
        gtk_widget_modify_font(textview, fontdesc);
        pango_font_description_free(fontdesc);
    }
    
    gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
    gtk_text_buffer_get_end_iter(buffer, &iter);

    if (!filename) {
        while (optind < argc) {
            gtk_text_buffer_insert(buffer, &iter, g_locale_to_utf8(argv[optind++], -1, NULL, NULL, NULL), -1);
            if (optind < argc) {
                gtk_text_buffer_insert(buffer, &iter, " ", 1);
            }
        }
    }
    else  {
        msg_from_file(buffer, &iter, filename);
    }

    gtk_container_add(GTK_CONTAINER(scrollwin), textview);
    gtk_widget_show(textview);
    
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(cb_delete_event), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(cb_destroy), NULL);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit),G_OBJECT(window));
    
    if (center)
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
    if (nearmouse)
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
    
    gtk_widget_show(window);

    gtk_main();
    
    return 0;
    
}

void msg_from_file(GtkTextBuffer *buf, GtkTextIter *it, gchar *name) {

    FILE *fp;
    gchar fbuf[BUFSIZE];
    
    if (name[0] == '-' && name[1] == '\0') {
        if ((fp = fdopen(0, "r")) == NULL) {
            perror("fopen()");
            exit(-1);
        }
    }
    else {
        if ((fp = fopen(name, "r")) == NULL) {
            perror("fopen()");
            exit(-1);
        }
    }

    while ((fgets(fbuf, sizeof(fbuf)-1, fp)) != NULL) 
        gtk_text_buffer_insert(buf, it, g_locale_to_utf8(fbuf, -1, NULL, NULL, NULL), -1);
    
    return;
}

void print_usage(void) {

    printf("Usage: gmessage [options] [message ...]\n\n");
    printf("Options:\n");
    printf("-f, -file <file>                read message from file, \"-\" for stdin\n");
    printf("-s, -size <width>x<height>      open window with given size\n");
    printf("-c, -center                     open window at center of screen\n");
    printf("-n, -nearmouse                  open window near the mouse pointer\n");
    printf("-S, -sticky                     try to make window sticky\n");
    printf("-p, -popup                      use GTK_WINDOW_POPUP instead of\n");
    printf("                                GTK_WINDOW_TOPLEVEL\n");
    printf("-t, -timeout <secs>             exit with errorlevel 0 after <secs> seconds\n");
    printf("-F, -font <arg>                 format \"[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]\"\n");                      
    
}
    
            

