#include <gtk/gtk.h>
#include <stdio.h>
#include "about.xpm"

GtkWidget *textview, *window;
GtkTextBuffer *textbuffer;
char currentfile[1000];
static void save_file(GtkWidget *w, gpointer data);

static gboolean delete_event( GtkWidget *widget,
                              GdkEvent  *event,
                              gpointer   data )
{
    if (gtk_text_buffer_get_modified(textbuffer)) {
	GtkWidget *dlg;
	    dlg = gtk_message_dialog_new(GTK_WINDOW(window),
			GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
			GTK_BUTTONS_NONE,
			"There are unsaved changes. Save first?");
	gtk_dialog_add_buttons(GTK_DIALOG(dlg),
			GTK_STOCK_SAVE, GTK_RESPONSE_YES,
			"Don't Save", GTK_RESPONSE_NO,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			NULL);
	switch (gtk_dialog_run(GTK_DIALOG(dlg))) {
		case GTK_RESPONSE_NO: /* don't save */
		gtk_widget_destroy(dlg);
		gtk_main_quit();
			break;
		case GTK_RESPONSE_YES: /* save */
		gtk_widget_destroy(dlg);
 		save_file(NULL, NULL); 
		gtk_main_quit();
			break;
		case GTK_RESPONSE_CANCEL: /* cancel */
		gtk_widget_destroy(dlg);
  		default:
			break;
		}
	}
	else
    		gtk_main_quit ();
    return FALSE;
}

static void help_about (GtkWidget *w, gpointer data)
{
	GtkWidget *aboutdlg, *image, *label;
	static GdkBitmap *mask = NULL; static GdkPixmap *pixmap = NULL;
	gint temp;
	aboutdlg = gtk_dialog_new_with_buttons("About TomoText", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_REJECT, NULL);
    g_signal_connect_swapped (G_OBJECT (aboutdlg),"response", G_CALLBACK (gtk_widget_destroy), G_OBJECT (aboutdlg));
        pixmap = gdk_pixmap_create_from_xpm_d(window->window, &mask, NULL, about_xpm);
	image = gtk_image_new_from_pixmap(pixmap, mask);
	label = gtk_label_new("TomoText, a GTK2 text editor by Avery M.\nDistributed under the GNU General Public License.");
	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER); 
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutdlg)->vbox), image, TRUE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutdlg)->vbox), label, FALSE, FALSE, 0);
	gtk_widget_show(label);
	label = gtk_entry_new();
	temp = GTK_ENTRY(label)->text_length;
	gtk_editable_insert_text(GTK_EDITABLE(label), "http://osaka.is.dreaming.org/", -1, &temp);
	gtk_editable_set_editable(GTK_EDITABLE(label), FALSE);
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutdlg)->vbox), label, FALSE, FALSE, 0);
	gtk_widget_show_all(aboutdlg);
	
}

static void file_new (GtkWidget *w,
		gpointer data)
{
    if (gtk_text_buffer_get_modified(textbuffer)) {
	GtkWidget *dlg;
	    dlg = gtk_message_dialog_new(GTK_WINDOW(window),
			GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
			GTK_BUTTONS_NONE,
			"There are unsaved changes. Save first?");
	gtk_dialog_add_buttons(GTK_DIALOG(dlg),
			GTK_STOCK_SAVE, GTK_RESPONSE_YES,
			"Don't Save", GTK_RESPONSE_NO,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			NULL);
	switch (gtk_dialog_run(GTK_DIALOG(dlg))) {
		case GTK_RESPONSE_NO: /* don't save */
		gtk_widget_destroy(dlg);
		gtk_text_buffer_set_text(textbuffer, "", 0);
	gtk_text_buffer_set_modified(textbuffer, FALSE);
			break;
		case GTK_RESPONSE_YES: /* save */
		gtk_widget_destroy(dlg);
 		save_file(NULL, NULL); 
		gtk_text_buffer_set_text(textbuffer, "", 0);
	gtk_text_buffer_set_modified(textbuffer, FALSE);
			break;
		case GTK_RESPONSE_CANCEL: /* cancel */
		gtk_widget_destroy(dlg);
  		default:
			break;
		}
	}
    else
	gtk_text_buffer_set_text(textbuffer, "", 0);
	gtk_text_buffer_set_modified(textbuffer, FALSE);
}

static void file_quit( GtkWidget *w,
                         gpointer   data )
{
  delete_event(NULL, NULL, NULL);
}

static void set_wrap_mode(gpointer data, guint action, GtkWidget *checkbox)
{
	if (GTK_CHECK_MENU_ITEM(checkbox)->active)
		gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
	else
		gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_NONE);
}

static void do_the_save(GtkWidget *w, GtkFileSelection *saved)
{
	FILE *output;
	GtkTextIter start, end;
	output = fopen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(saved)), "w");
	strcpy(currentfile, gtk_file_selection_get_filename(GTK_FILE_SELECTION(saved)));
	gtk_text_buffer_get_bounds(textbuffer, &start, &end);
	fprintf(output, gtk_text_buffer_get_text(textbuffer, &start, &end, TRUE));
	gtk_text_buffer_set_modified(textbuffer, FALSE);
	fclose(output);
	gtk_widget_destroy(w->parent->parent->parent);
}

static void save_file_as(GtkWidget *w, gpointer data)
{
	GtkWidget *save;
	save = gtk_file_selection_new("Save as...");
	gtk_widget_show_all(save);
    g_signal_connect (G_OBJECT (save), "destroy",
	              G_CALLBACK (gtk_widget_destroy), NULL);
    /* Connect the ok_button to file_ok_sel function */
    g_signal_connect (G_OBJECT (GTK_FILE_SELECTION (save)->ok_button),
		      "clicked", G_CALLBACK (do_the_save), (gpointer) save);
    
    /* Connect the cancel_button to destroy the widget */
    g_signal_connect_swapped (G_OBJECT (GTK_FILE_SELECTION (save)->cancel_button),"clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (save));
}

static void save_file(GtkWidget *w, gpointer data)
{
	if (strcmp(currentfile, "")) {
	FILE *output;
GtkTextIter start, end;
	output= fopen(currentfile, "w");
	gtk_text_buffer_get_bounds(textbuffer, &start, &end);
	fprintf(output, gtk_text_buffer_get_text(textbuffer, &start, &end, TRUE));
	gtk_text_buffer_set_modified(textbuffer, FALSE);
	fclose(output);

	}
	else
		save_file_as(w, data);
}

static void do_the_open(GtkWidget *w, GtkFileSelection *toopen)
{
	FILE *input;
		GtkWidget *dialog;
	gchar buffer[1000];
	input = fopen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(toopen)), "r");
	gtk_text_buffer_set_text(textbuffer, "", 0);
  while (fgets (buffer, sizeof (buffer), input))
    {
      gtk_text_buffer_insert_at_cursor (textbuffer, buffer, strlen (buffer));
    }
	gtk_text_buffer_set_modified(textbuffer, FALSE);
	fclose(input);
	if (strlen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(toopen))) < 1000)
		strcpy(currentfile, gtk_file_selection_get_filename(GTK_FILE_SELECTION(toopen)));
	else {
		g_message("Too Long");
		dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CANCEL, "This filename is too long. The file was not saved.");
		gtk_dialog_run(GTK_DIALOG(dialog));
	}
	gtk_widget_destroy(w->parent->parent->parent);
}

static void open_file(GtkWidget *w, gpointer data)
{
	GtkWidget *save;
    if (gtk_text_buffer_get_modified(textbuffer)) {
	GtkWidget *dlg;
	    dlg = gtk_message_dialog_new(GTK_WINDOW(window),
			GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
			GTK_BUTTONS_NONE,
			"There are unsaved changes. Save first?");
	gtk_dialog_add_buttons(GTK_DIALOG(dlg),
			GTK_STOCK_YES, GTK_RESPONSE_YES,
			GTK_STOCK_NO, GTK_RESPONSE_NO,
			NULL);
	switch (gtk_dialog_run(GTK_DIALOG(dlg))) {
		case GTK_RESPONSE_NO: /* don't save */
		gtk_widget_destroy(dlg);
			break;
		case GTK_RESPONSE_YES: /* save */
		gtk_widget_destroy(dlg);
 		save_file(NULL, NULL); 
			break;
  		default:
			break;
		}
	}	
	save = gtk_file_selection_new("Open...");
	gtk_widget_show_all(save);
    g_signal_connect (G_OBJECT (save), "destroy",
	              G_CALLBACK (gtk_widget_destroy), NULL);
    /* Connect the ok_button to file_ok_sel function */
    g_signal_connect (G_OBJECT (GTK_FILE_SELECTION (save)->ok_button),
		      "clicked", G_CALLBACK (do_the_open), (gpointer) save);
    
    /* Connect the cancel_button to destroy the widget */
    g_signal_connect_swapped (G_OBJECT (GTK_FILE_SELECTION (save)->cancel_button),"clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (save));
}

static GtkItemFactoryEntry menu_items[] = {
  { "/_File",         NULL,         NULL,           0, "<Branch>" },
  { "/File/_New",     "<control>N", file_new,    0, "<StockItem>", GTK_STOCK_NEW },
  { "/File/_Open",    "<control>O", open_file,    0, "<StockItem>", GTK_STOCK_OPEN },
  { "/File/_Save",    "<control>S", save_file,    0, "<StockItem>", GTK_STOCK_SAVE },
  { "/File/Save _As", NULL,         save_file_as,           0, "<Item>" },
  { "/File/sep1",     NULL,         NULL,           0, "<Separator>" },
  { "/File/_Quit",    "<CTRL>Q",    file_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
  { "/_Options",      NULL,         NULL,           0, "<Branch>" },
  { "/Options/Word Wrap", NULL,     set_wrap_mode,   1, "<CheckItem>" },
  { "/_Help",         NULL,         NULL,           0, "<LastBranch>" },
  { "/_Help/About",   NULL,         help_about,           0, "<StockItem>", GTK_STOCK_DIALOG_INFO },
};

/* from GTK 2.2 tutorial */
static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);

/* Returns a menubar widget made from the above menu */
static GtkWidget *get_menubar_menu( GtkWidget  *window )
{
  GtkItemFactory *item_factory;
  GtkAccelGroup *accel_group;

  /* Make an accelerator group (shortcut keys) */
  accel_group = gtk_accel_group_new ();

  /* Make an ItemFactory (that makes a menubar) */
  item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
                                       accel_group);

  /* This function generates the menu items. Pass the item factory,
     the number of items in the array, the array itself, and any
     callback data for the the menu items. */
  gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);

  /* Attach the new accelerator group to the window. */
  gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);

  /* Finally, return the actual menu bar created by the item factory. */
  return gtk_item_factory_get_widget (item_factory, "<main>");
}

int main (gint argc, char *argv[])
{
	GtkWidget *vbox, *menubar, *scrollies;

	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_widget_set_usize(window, 100, 30);
	gtk_widget_set_size_request(window, 500, 350);
	gtk_window_set_title(GTK_WINDOW(window), "TomoText 0.9");
	g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
	vbox = gtk_vbox_new(FALSE, 1);
	gtk_container_add(GTK_CONTAINER(window), vbox);
	textview = gtk_text_view_new();
	textbuffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
	scrollies = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollies), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_add(GTK_CONTAINER(scrollies), textview);
	gtk_box_pack_end(GTK_BOX(vbox), scrollies, TRUE, TRUE, 0);
	menubar = get_menubar_menu(window);
	strcpy(currentfile, "");
	gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}
