// sticknot.c
// 
// (C) 2012 inkeso

// gcc sticknot.c `pkg-config --cflags --libs gtk+-2.0` -o sticknotgcc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
extern  int alphasort();
/*** DEFAULTS ***/

// Notes are stored in this folder. Simple Textfiles. Nothing special.
// this is $XDG_DATA_HOME...
#define PATH "notes"

// Tab-Position: 0=left 1=right 2=top 3=bottom
#define TABS 2

// Word-wrapping?
#define WRAP TRUE

// Font. Leave empty for your systems default. You can use something like
// "Arial 12" or "Times 16" (or just "monospace" if you want your systems
// default monospaced font)
#define FONT ""

// Window-Size
#define SIZEX 600
#define SIZEY 400

// Window-Position
#define POSX 200
#define POSY 200

// Borderless? Set to TRUE to deactivate Windowmanager-decoration. 
#define BORDERLESS FALSE

// Skip Taskbar? If set to TRUE, SticKnot won't show up in your taskbar.
#define SKIPTASKBAR FALSE

// Opacity. Value between 0.0 and 1.0 whereas 1.0 is fully visible and 0.0 is
// completly transparent.
#define OPACITY 0.9


/*** Evil Globals ***/
GtkWidget *mainwindow, *contextmenu, *tabbs;



/* dialog. show a simple input-dialog. return input-text or FALSE */
gboolean input(gchar *message, gchar *etxt, gchar *result) {
    void ok(GtkWidget *widget, gpointer data) {
        gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
    }
    
    GtkWidget *dialog = gtk_dialog_new_with_buttons("Input", GTK_WINDOW(mainwindow),
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_OK,      GTK_RESPONSE_ACCEPT,
        GTK_STOCK_CANCEL,  GTK_RESPONSE_REJECT,
        NULL);

    GtkWidget *label = gtk_label_new(message);
    GtkWidget *entry = gtk_entry_new();

    gtk_entry_set_text(GTK_ENTRY(entry), etxt);
    gtk_widget_grab_focus(entry);
    g_signal_connect(entry, "activate", G_CALLBACK (ok), dialog);

    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, TRUE, TRUE, 0);
    gtk_widget_show(label);
    gtk_widget_show(entry);
    gint resi = gtk_dialog_run(GTK_DIALOG(dialog));
    strcpy(result, gtk_entry_get_text(GTK_ENTRY(entry)));
    gtk_widget_destroy(dialog);
    if (resi == GTK_RESPONSE_ACCEPT && strlen(result) > 1) {
        return TRUE;
    } else {
        return FALSE;
    }
    
}

void tabrename(GtkWidget *widget, gpointer window) {
    // get current Tab Name
    gchar *curent = {"Dennis"};
    gchar nunam[255];
    gchar msg[1024];
    sprintf(msg, "\nRename %s\n", curent);
    
    if (input(msg, curent, nunam)) {
        sprintf(msg, "%s --> %s\n", curent, nunam);
        g_print(msg);
    }
}

void tabnew(GtkWidget *widget, gpointer window) {
    gchar nunam[255];
    if (input("\nName of the new note?\n", "", nunam))
        g_print(nunam);
}


void destroy(GtkWidget *widget, gpointer data) {
    // save all data here and then...
    // Get the entire buffer text.
    //gchar *text;
    //text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
    
    gtk_main_quit ();
}

gboolean rightclick(GtkWidget *widget, GdkEvent *event, GtkWidget *menu) {
    if (event->type == GDK_BUTTON_PRESS && event->button.button == 3) {
        gtk_menu_popup(GTK_MENU(contextmenu), NULL, NULL, NULL, NULL, event->button.button, event->button.time);
        return TRUE;
    }

    if (event->type == GDK_KEY_PRESS && event->key.keyval == GDK_KEY_Escape) {
        destroy(widget, NULL);
    }
    return FALSE;
}
   




// create a scrolled textview from filename.
void makepage(gchar* filename) {
    //load file here
    gchar *content;
    GtkWidget *scrll;
    GtkWidget *textv;
    GtkTextBuffer *buffy;
    
    // read file
    gchar gpath[4096];
    sprintf(gpath, "%s/%s", PATH, filename);
    FILE *input = fopen(gpath, "r");
    fseek(input, 0L, SEEK_END);  // Position to end of file
    int fila = ftell(input);     // Filelength
    content = calloc(fila + 1, sizeof(gchar));
    rewind(input);
    if(content == NULL ) {
        g_print("Insufficient memory to read file.\n");
        return;
    }
    fread(content, fila, 1, input); // Read the entire file

    textv = gtk_text_view_new();
    buffy = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textv));
    gtk_text_buffer_set_text(buffy, content, -1);
    gtk_text_buffer_set_modified(buffy, FALSE);

    g_signal_connect(G_OBJECT(textv), "event", G_CALLBACK(rightclick), contextmenu);
    
    scrll = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    if (WRAP) gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textv), GTK_WRAP_WORD);
    gtk_widget_modify_font (textv, pango_font_description_from_string (FONT));
    gtk_container_add(GTK_CONTAINER(scrll), textv);
    gtk_notebook_append_page(GTK_NOTEBOOK(tabbs), scrll, gtk_label_new(filename));
    gtk_widget_grab_focus(textv);
}

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

    gtk_init (&argc, &argv);
    mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
    g_signal_connect (mainwindow, "delete-event", G_CALLBACK (destroy), NULL);
    
    gtk_container_set_border_width (GTK_CONTAINER(mainwindow), 1);
    gtk_window_set_title (GTK_WINDOW(mainwindow), "SticKnot");
    gtk_window_set_default_size(GTK_WINDOW(mainwindow), SIZEX, SIZEY);
    //gtk_window_set_position(GTK_WINDOW(mainwindow), WIN_POS_CENTER);
    gtk_window_set_opacity(GTK_WINDOW(mainwindow), OPACITY);
    gtk_window_set_decorated(GTK_WINDOW(mainwindow), !BORDERLESS);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwindow), SKIPTASKBAR);
    gtk_window_move(GTK_WINDOW(mainwindow), POSX, POSY);
    
    GdkPixbuf *windowicon = gtk_widget_render_icon(mainwindow, GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU, NULL);
    gtk_window_set_icon(GTK_WINDOW(mainwindow), windowicon);

    /*** prepare menu ***/
    contextmenu = gtk_menu_new();
    GtkWidget *mNew, *mRename, *mDelete, *mExit;

    mNew = gtk_menu_item_new_with_label("New");
    mRename = gtk_menu_item_new_with_label("Rename");
    mDelete = gtk_menu_item_new_with_label("Delete");
    mExit = gtk_menu_item_new_with_label("Exit");

    gtk_widget_show(mNew);
    gtk_widget_show(mRename);
    gtk_widget_show(mDelete);
    gtk_widget_show(mExit);
    
    gtk_menu_append(GTK_MENU(contextmenu), mNew);
    gtk_menu_append(GTK_MENU(contextmenu), mRename);
    gtk_menu_append(GTK_MENU(contextmenu), mDelete);
    gtk_menu_append(GTK_MENU(contextmenu), mExit);

    g_signal_connect(G_OBJECT(mNew), "activate", G_CALLBACK(tabnew), NULL);
    g_signal_connect(G_OBJECT(mRename), "activate", G_CALLBACK(tabrename), NULL);
    g_signal_connect(G_OBJECT(mDelete), "activate", G_CALLBACK(NULL), NULL);
    g_signal_connect(G_OBJECT(mExit), "activate", G_CALLBACK(destroy), NULL);

    
    /*** Create tabbed Notebook ***/
    tabbs = gtk_notebook_new();
    
    int file_select(); // declared below. This way, no warning is issued.
    struct direct **files;
    int fcount = scandir(PATH, &files, file_select, alphasort);
    int i=0;
    
    for (i=0; i<fcount; ++i) {
        makepage(files[i]->d_name);
    }
    
    /* When the button receives the "clicked" signal, it will call the
     * function hello() passing it NULL as its argument.  The hello()
     * function is defined above. */
    //g_signal_connect (button, "clicked", G_CALLBACK (hello), NULL);
    
    /* This packs the button into the window (a gtk container). */
    gtk_container_add (GTK_CONTAINER (mainwindow), tabbs);
    
    /* The final step is to display this newly created widget. */
    //gtk_widget_show (tabbs);
    
    /* and the window */
    //gtk_widget_show (window);
    gtk_widget_show_all(mainwindow);
    
    /* All GTK applications must have a gtk_main(). Control ends here
     * and waits for an event to occur (like a key press or
     * mouse event). */
    gtk_main ();
    
    return 0;
}

int file_select(struct direct *entry) {
    return ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0));
}
