/*
 * main.c
 * 
 * Copyright (C) 2005-2007  Josef Kufner <jk@myserver.cz>
 * 
 * This program 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.
 *
 * 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.
 *
 */

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

#include <gtk/gtk.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

#include "connection.h"
#include "session.h"
#include "message.h"
#include "msg_handle.h"
#include "options.h"
#include "dirs.h"
#include "draw.h"
#include "gui.h"
#include "backend.h"
#include "playerlist.h"
#include "roles.h"
#include "record.h"

#define DEBUG 0
#include "debug.h"


GtkWidget *main_window;

/* gui update */
extern struct s_gui gui;

static void cleanup(void) {
	option_store_to_default();
	dir_cleanup();
}

static void on_signal(int sig) {
	DBG_MSG(1, "Caught signal %d", sig);
	if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP) {
		cleanup();
		exit(0);
	} else {
		DBG_MSG(1, "Signal ignored");
	}
}

int
main (int argc, char *argv[])
{
	const char *autorun = NULL;
	gchar *config_filename = NULL;
	gchar *config_autoconnect = NULL;
	gchar *config_autoconnect_addr = NULL;
	GError *err = NULL;
	GOptionEntry cmd_line_options[] = {
		{
			"config", 'c', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME, &config_filename,
			_("Načíst konfiguraci z tohoto souboru"),
			_("filename")
		},
		{
			"connect", 'e', 0, G_OPTION_ARG_STRING, &config_autoconnect,
			_("Navázat spojení ihned po startu"),
			_("profile_id")
		},
		{
			"address", 'a', 0, G_OPTION_ARG_STRING, &config_autoconnect_addr,
			_("Adresa pro připojení po startu"),
			_("address")
		},
		{
			NULL, 0, 0, 0, NULL, NULL, NULL
		}
	};

#ifdef ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);
#endif

	/* gtk initialization */
	if (!gtk_init_with_args (&argc, &argv, "", cmd_line_options, NULL, &err)) {
		g_printerr("%s: %s\n", argv[0], err->message);
		return EXIT_FAILURE;
	}
	add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");

	/* set up default configuration & parse cmd line options */
	option_init();

	/* register message destinations */
	message_init();
	message_register_target('O', msg_handle_options, "options");
	message_register_target('C', msg_handle_chat, "chat");
	message_register_target('N', msg_handle_backend, "network backend");
	message_register_target('G', msg_handle_backend, "game backend");
	message_register_target('S', msg_handle_session, "session");
	message_register_target('B', msg_handle_draw, "draw");
	message_register_target('P', msg_handle_playerlist, "playerlist");
	message_register_target('F', msg_handle_network_profiles, "network profiles");
	message_register_target('T', msg_handle_test, "test");

	/* signal handlers */
	signal(SIGINT, on_signal);
	signal(SIGTERM, on_signal);
	signal(SIGHUP, on_signal);
	signal(SIGPIPE, on_signal);
	
	/* initialize data stores */
	playerlist_init();
	record_init();
	roles_init();
	
	/* initialize state machines */
	connection_init();
	session_init();

	/* create main window */
	gui_create_main_window ();
	draw_init(lookup_widget(main_window, "board_drawingarea"));
	playerlist_set_update_callback(gui_update_playerlist);

	/* load configuration */
	option_freeze_callbacks();
	if (config_filename) {
		option_load_file(config_filename);
		option_set_string("main", "dir", "config_file", config_filename);
	} else {
		dir_update();
		option_load_file(dir_main_config);
	}
	option_thaw_callbacks();

	/* check if configuration is complete */
	if (!option_get_integer("main", "runtime", "option_load_complete")) {
		gui_show_error_message(
				_("Vaše konfigurace nebyla načtena správně"),
				_("V případě, že spouštíte tento program poprvé, "
				"je vše v pořádku.\n\n"
				"Pokud však jste již tento program "
				"spouštěl(a), pravděpodobně došlo k poškození "
				"konfiguračního souboru a před zavřením tohoto okna "
				"byste měl(a) provédst všechny pokusy "
				"o záchranu.\n\n"
				"Tak jako tak, bude použita defaultní "
				"konfigurace a případné zbytky Vaší "
				"konfigurace."));
		option_load_defaults();
	}

	/* update paths */
	dir_update();

	/* initialize model views */
	gui_record_init(record_store);
	gui_role_init(roles_store);
	
	/* update everything for the first time and show main window */
	gui_update_main_window();
	gtk_widget_show (main_window);
	gui_update_expanders();			/* we do not want resize window */
	
	/* options are loaded, so we can launch state machines */
	status_switch(connection_status, S_C_OFFLINE, NULL);
	status_switch(session_status, S_S_IDLE, NULL);

	/* run startup file */
	if ((autorun = option_get_string("main", "dir", "startup_file")) && autorun[0])
		option_load_file(autorun);

	/* connect or show connect dialog */
	if (config_autoconnect) {
		const char *backend;
		if (config_autoconnect_addr)
			option_set_string("main", "net", "address", config_autoconnect_addr);
		backend = option_get_string("network", config_autoconnect, "backend");
		option_set_string("main", "net", "profile", config_autoconnect);
		option_set_string("main", "net", "backend", backend ? backend : "");
		status_switch(connection_status, S_C_CONNECTING, NULL);
	} else if (option_get_integer("main", "ui", "show_connect_on_startup")) {
		gui_show_dialog_connect();
	}
	
	/* Go ! */
	gtk_main();

	/* Bye */
	cleanup();
	return EXIT_SUCCESS;
}

