/*******************************************************************
 *            main.c
 *
 *  Sat Jul 29 14:14:52 2006
 *  Copyright  2006-2008  Neil Williams
 *  linux@codehelp.co.uk
 *******************************************************************/
/*
    This package 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 3 of the License, or
    (at your option) any later version.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
#include <archive.h>
#include <unistd.h>
#include "dvarchive.h"
#include "dvpreview.h"
#include "interface.h"
#include "support.h"
#include "callbacks.h"
#include <getopt.h>

/** list of other windows derived from this instance. */
static GList * subwindows = NULL;

void dv_add_child (GtkWindow * child) {
	subwindows = g_list_append (subwindows, child);
}

guint dv_count_kids (void) {
	return g_list_length (subwindows);
}

void dv_remove_child (GtkWindow * child) {
	subwindows = g_list_remove (subwindows, child);
}

static gboolean convert_vfs_to_gfile (const gchar * path, GtkWindow * window1) {
	gchar * filename;
	GVfs * vfs;
	GError * result;
	GFile * gfile;
	GFileInfo * ginfo;
	DVContents * context;

	result = NULL;
	context = dv_create();
	dv_set_needs_uri (context, TRUE);
	g_object_set_data (G_OBJECT(window1), DVCONTENTS, context);
	set_dv_parent (GTK_WIDGET(window1));
	vfs = g_vfs_get_default ();

	if (g_vfs_is_active(vfs)) {
		gfile = g_vfs_get_file_for_path (vfs, path);
		dv_set_needs_uri (context, FALSE);
	} else {
		gfile = g_file_new_for_commandline_arg (path);
		dv_set_needs_uri (context, FALSE);
	}
	/* take a look at the target file */
	if (!g_file_query_exists (gfile, NULL)) {
		/* if no file, try to create a GFile for a URI instead */
		g_object_unref (gfile);
		dv_set_needs_uri (context, TRUE);
		gfile = g_vfs_get_file_for_uri (vfs, path);
		if (!g_file_query_exists (gfile, NULL)) {
			/* nothing at all, return error. */
			g_object_unref (gfile);
			return FALSE;
		}
	}
	ginfo = g_file_query_info (gfile, G_FILE_ATTRIBUTE_STANDARD_SIZE,
		G_FILE_QUERY_INFO_NONE, NULL, &result);
	if (0 == g_file_info_get_attribute_uint64 (ginfo, 
		G_FILE_ATTRIBUTE_STANDARD_SIZE)) {
		g_object_unref (gfile);
		g_object_unref (ginfo);
		return FALSE;
	}
	/* ok, we have a readable GFile with non-zero size, proceed. */
	filename = g_file_get_parse_name (gfile);
	dv_set_working_path (context, filename);
	if (g_str_has_suffix(filename, ".changes")) {
		dv_parse_changes(gfile, context);
	} else {
		set_deb_file (gfile, context);
		gtk_widget_show (GTK_WIDGET(window1));
		subwindows = g_list_append (subwindows, window1);
	}
	g_free (filename);
	return TRUE;
}

int main (int argc, char *argv[]) {
	DVContents * context;
	gchar **remaining_args;
	GOptionContext *option_context;
	gboolean check_vfs;
	GtkDialog * dialog;
	GtkWindow * window1;
	int opt;

	GOptionEntry option_entries[] = {
		/* option that collects filenames */
		{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY,
			&remaining_args, NULL, _("file")},
		{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
	};

	static struct option long_options[] =
	{
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'v'}
	};

	int option_index = 0;

	// Parse -h (help) or -v (version) arg if present
	while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) {
		switch (opt) {
			case 'h':
				printf("Usage:\n");
				printf("  deb-gview [OPTION?] <.deb file>\n\n");
				printf("Help Options:\n");
				printf("  -h, --help       Show help options\n");
				printf("  -v, --version    Show version number\n");
				exit(0);
			case 'v':
				printf("deb-gview version %s\n", VERSION);
				exit(0);
			default:
				break;
		}
	}

#ifdef ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);
#endif
	g_assert ((archive_version_number() / 1000000) ==
	          (ARCHIVE_VERSION_NUMBER   / 1000000));
	remaining_args = NULL;
	window1 = NULL;
	option_context = g_option_context_new ("");
	g_option_context_add_main_entries (option_context,
		option_entries, GETTEXT_PACKAGE);
	g_option_context_parse (option_context, &argc, &argv, NULL);
	gtk_init (&argc, &argv);
	subwindows = NULL;
	if (!preview_init ()) {
		g_warning (_("Unable to create preview key file"));
	}
	/* parse remaining command-line arguments that are not
	   options (i.e. filenames)*/
	if (remaining_args != NULL) {
		gint i, num_args;
		gchar * debfile;

		num_args = g_strv_length (remaining_args);
		for (i = 0; i < num_args; ++i) {
			/* one window for each .deb file specified */
			debfile = g_strdup (remaining_args[i]);
			window1 = GTK_WINDOW(create_deb_gview_window ());
			g_return_val_if_fail (window1, EXIT_FAILURE);
			check_vfs = convert_vfs_to_gfile (debfile, window1);
			if (!check_vfs) {
				GdkPixbuf *deb_gview_window_icon_pixbuf;
				set_dv_parent (GTK_WIDGET(window1));
				dialog = GTK_DIALOG (gtk_message_dialog_new (window1,
							0, GTK_MESSAGE_ERROR,
							GTK_BUTTONS_CLOSE, _("Error loading file '%s'."),
							debfile));
				deb_gview_window_icon_pixbuf = create_pixbuf ("deb-gview.png");
				if (deb_gview_window_icon_pixbuf) {
					gtk_window_set_icon (GTK_WINDOW (dialog), 
						deb_gview_window_icon_pixbuf);
					g_object_unref (deb_gview_window_icon_pixbuf);
				}
				else {
					g_warning("Failed to set png image as icon");
				}
				gtk_dialog_run (dialog);
				gtk_widget_destroy (GTK_WIDGET (dialog));
				gtk_widget_show (GTK_WIDGET(window1));
				subwindows = g_list_append (subwindows, window1);
				g_strfreev (remaining_args);
				remaining_args = NULL;
				num_args = i;
				g_free (debfile);
			}
		}
	} else {
		context = dv_create();
		window1 = GTK_WINDOW(create_deb_gview_window ());
		g_return_val_if_fail (window1, EXIT_FAILURE);
		g_object_set_data (G_OBJECT(window1), DVCONTENTS, context);
		set_dv_parent (GTK_WIDGET(window1));
		gtk_widget_show GTK_WIDGET((window1));
		subwindows = g_list_append (subwindows, window1);
	}
	gtk_main ();
	return EXIT_SUCCESS;
}
