/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* main.c - genesis of a GHex application

   Copyright (C) 1998, 1999 Free Software Foundation

   GHex is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   GHex is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GHex; see the file COPYING.
   If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Author: Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
*/

#include <config.h>
#include <gnome.h>
#include "ghex.h"

enum {
		TARGET_URI_LIST,
};

/* callbacks for MDI signals */
static gint remove_doc_cb(GnomeMDI *, HexDocument *);
static void view_changed_cb(GnomeMDI *, GtkHex *);
static void child_changed_cb(GnomeMDI *, HexDocument *);
static void customize_app_cb(GnomeMDI *, GnomeApp *);
static void cleanup_cb(GnomeMDI *);

GnomeMDI *mdi;

gint mdi_mode = GNOME_MDI_DEFAULT_MODE;

gint remove_doc_cb(GnomeMDI *mdi, HexDocument *doc) {
	static char msg[512];
	GnomeMessageBox *mbox;
	gint reply;
	
	sprintf(msg, _("File %s has changed since last save.\n"
				   "Do you want to save changes?"), GNOME_MDI_CHILD(doc)->name);
	
	if(hex_document_has_changed(doc)) {
		mbox = GNOME_MESSAGE_BOX(gnome_message_box_new( msg, GNOME_MESSAGE_BOX_QUESTION, GNOME_STOCK_BUTTON_YES,
														GNOME_STOCK_BUTTON_NO, GNOME_STOCK_BUTTON_CANCEL, NULL));
		gnome_dialog_set_default(GNOME_DIALOG(mbox), 2);
		reply = ask_user(mbox);
		
		if(reply == 0)
			hex_document_write(doc);
		else if(reply == 2)
			return FALSE;
	}
	
	return TRUE;
}

void cleanup_cb(GnomeMDI *mdi) {
	save_configuration();
	gtk_main_quit();
}

void child_changed_cb(GnomeMDI *mdi, HexDocument *doc) {
	create_dialog_title(find_dialog.window, _("GHex (%s): Find Data"));
	create_dialog_title(replace_dialog.window, _("GHex (%s): Find & Replace Data"));
	create_dialog_title(jump_dialog.window, _("GHex (%s): Jump To Byte"));
}

void view_changed_cb(GnomeMDI *mdi, GtkHex *old_view) {
	GnomeApp *app;
	GnomeUIInfo *uiinfo;
	GtkWidget *shell, *item;
	HexDocument *doc;
	gint pos;
	gint group_item;
	char *p;

	if(mdi->active_view == NULL)
		return;

	app = gnome_mdi_get_app_from_view(mdi->active_view);
	
	GROUP_MENU_PATH(p);
	shell = gnome_app_find_menu_pos(app->menubar, p, &pos);
	if (shell){
		group_item = GTK_HEX(mdi->active_view)->group_type / 2;
		shell = gnome_app_find_menu_pos(shell, _(group_type_label[group_item]), &pos);
		
		item = g_list_nth(GTK_MENU_SHELL(shell)->children, pos - 1)->data;
		
		gtk_menu_shell_activate_item(GTK_MENU_SHELL(shell), item, TRUE);
	}
	uiinfo = gnome_mdi_get_child_menu_info(app);
	uiinfo = (GnomeUIInfo *)uiinfo[0].moreinfo;
    doc = HEX_DOCUMENT(gnome_mdi_get_child_from_view(mdi->active_view));
	gtk_widget_set_sensitive(uiinfo[0].widget, doc->undo_depth > 0);
	gtk_widget_set_sensitive(uiinfo[1].widget, doc->undo_top != doc->undo_stack);

	gnome_app_install_menu_hints(app, gnome_mdi_get_child_menu_info(app));
	g_free(p);
}

static void app_drop_cb(GtkWidget *widget, GdkDragContext *context,
		        gint x, gint y, GtkSelectionData *selection_data,
			guint info, guint time, gpointer data) {
	GList *names, *list;

	switch (info) {
	case TARGET_URI_LIST:
		list = names = gnome_uri_list_extract_filenames (selection_data->data);
		while (names) {
			HexDocument *doc;

			printf("dragged %s\n", names->data);
			doc = hex_document_new((gchar *)names->data);
			if(doc) {
				gnome_mdi_add_child(mdi, GNOME_MDI_CHILD(doc));
				gnome_mdi_add_view(mdi, GNOME_MDI_CHILD(doc));
			}
			names = names->next;
		}
		gnome_uri_list_free_strings (list);
		break;
	default:
	}
}

void customize_app_cb(GnomeMDI *mdi, GnomeApp *app) {
	GtkWidget *bar;
	static GtkTargetEntry drop_types [] = {
		{ "text/uri-list", 0, TARGET_URI_LIST}
	};
	static gint n_drop_types = sizeof (drop_types) / sizeof(drop_types[0]);

	gtk_drag_dest_set (GTK_WIDGET (app),
	                   GTK_DEST_DEFAULT_MOTION |
			   GTK_DEST_DEFAULT_HIGHLIGHT |
			   GTK_DEST_DEFAULT_DROP,
			   drop_types, n_drop_types,
			   GDK_ACTION_COPY);
        gtk_signal_connect (GTK_OBJECT (app), "drag_data_received",
			    GTK_SIGNAL_FUNC(app_drop_cb), NULL);

	bar = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_USER);
	gnome_app_set_statusbar(app, bar);
	gtk_widget_show(bar);

	gnome_app_install_menu_hints(app, gnome_mdi_get_menubar_info(app));
}

int main(int argc, char **argv) {
	GnomeClient *client;
	HexDocument *doc;
	char **cl_files;
	poptContext ctx;

	bindtextdomain (PACKAGE, GNOMELOCALEDIR);
	textdomain(PACKAGE);

	gnome_init_with_popt_table("ghex", VERSION, argc, argv, options, 0, &ctx);

	client = gnome_master_client();

	gtk_signal_connect (GTK_OBJECT (client), "save_yourself",
						GTK_SIGNAL_FUNC (save_state), (gpointer) argv[0]);
	gtk_signal_connect (GTK_OBJECT (client), "die",
						GTK_SIGNAL_FUNC (client_die), NULL);

    mdi = GNOME_MDI(gnome_mdi_new("ghex", "GHex"));

    /* set up MDI menus */
    gnome_mdi_set_menubar_template(mdi, main_menu);

    /* and document menu and document list paths */
    gnome_mdi_set_child_menu_path(mdi, CHILD_MENU_PATH);
    gnome_mdi_set_child_list_path(mdi, CHILD_LIST_PATH);

    /* connect signals */
    gtk_signal_connect(GTK_OBJECT(mdi), "remove_child", GTK_SIGNAL_FUNC(remove_doc_cb), NULL);
    gtk_signal_connect(GTK_OBJECT(mdi), "destroy", GTK_SIGNAL_FUNC(cleanup_cb), NULL);
    gtk_signal_connect(GTK_OBJECT(mdi), "view_changed", GTK_SIGNAL_FUNC(view_changed_cb), NULL);
	gtk_signal_connect(GTK_OBJECT(mdi), "child_changed", GTK_SIGNAL_FUNC(child_changed_cb), NULL);
	gtk_signal_connect(GTK_OBJECT(mdi), "app_created", GTK_SIGNAL_FUNC(customize_app_cb), NULL);

    /* load preferences */
    load_configuration();
    /* set MDI mode */
    gnome_mdi_set_mode(mdi, mdi_mode);

    /* restore state from previous session */
    if (gnome_client_get_flags (client) & GNOME_CLIENT_RESTORED) {

		gnome_config_push_prefix (gnome_client_get_config_prefix (client));
		
		restarted= gnome_mdi_restore_state (mdi, "Session", (GnomeMDIChildCreator)hex_document_new_from_config);		
		
		gnome_config_pop_prefix ();
	}

	if (!restarted)
		gnome_mdi_open_toplevel(mdi);
	
    cl_files = poptGetArgs(ctx);
	
    while(cl_files && *cl_files) {
		doc = hex_document_new(*cl_files);
		if(doc) {
			gnome_mdi_add_child(mdi, GNOME_MDI_CHILD(doc));
			gnome_mdi_add_view(mdi, GNOME_MDI_CHILD(doc));
		}
		cl_files++;
    }
    poptFreeContext(ctx);
	
    /* and here we go... */
    gtk_main();

	return 0;
}
