/*
 * Copyright (c) 2004 Jean-Yves Lefort
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <locale.h>
#include <errno.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "sg-util.h"
#include "sgtk-stock.h"
#include "sgtk-util.h"
#include "st-thread.h"
#include "st-stock.h"
#include "st-transfer.h"
#include "st-settings.h"
#include "st-session.h"
#include "st-action.h"
#include "st-handler.h"
#include "st-handlers.h"
#include "st-plugins.h"
#include "st-shell.h"
#include "st-splash.h"
#include "st-util.h"

/*** variable declarations ***************************************************/

static char *custom_private_dir = NULL;
char **st_main_argv;

/*** function declarations ***************************************************/

static STSplash   *st_main_splash_create	(void);
static void       st_main_splash_set_text	(STSplash	*splash,
						 const char	*str);
static void       st_main_splash_set_progress	(STSplash	*splash,
						 double		progress);

static void       st_main_parse_args		(int		argc,
						 char		**argv);
static void       st_main_print_help		(void);
static void       st_main_print_version		(void);

/*** implementation **********************************************************/

int
main (int argc, char **argv)
{
  STSplash *splash = NULL;
  GtkWindow *window;

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

  /*
   * gtk_init() calls setlocale(), but we need the locale to be set
   * right now, so that g_print() and friends correctly convert
   * internationalized strings to the user's charset (g_print() and
   * friends might be used from st_thread_init() and
   * st_main_parse_args()).
   */
  setlocale(LC_ALL, "");

  st_main_parse_args(argc, argv);

  st_thread_init();		/* must be called before gtk_init() */
  gtk_init(&argc, &argv);

  GDK_THREADS_ENTER();

  st_settings_init(custom_private_dir);
  if (st_settings.splash_enabled)
    splash = st_main_splash_create();

  st_main_splash_set_text(splash, _("Initializing subsystems..."));
  sgtk_stock_init();		st_main_splash_set_progress(splash, (double) 1 / 8);
  st_stock_init();		st_main_splash_set_progress(splash, (double) 2 / 8);
  st_transfer_init();		st_main_splash_set_progress(splash, (double) 3 / 8);
  st_action_init();		st_main_splash_set_progress(splash, (double) 4 / 8);
  
  st_main_splash_set_text(splash, _("Loading plugins..."));
  st_handlers_load_static();	st_main_splash_set_progress(splash, (double) 5 / 8);
  st_plugins_load();		st_main_splash_set_progress(splash, (double) 6 / 8);

  st_main_splash_set_text(splash, _("Loading session..."));
  st_session_load();
  g_slist_foreach(st_handlers_list, (GFunc) st_handler_select_category, NULL);

  st_main_splash_set_progress(splash, (double) 7 / 8);

  st_main_splash_set_text(splash, _("Creating user interface..."));
  st_shell_new();		st_main_splash_set_progress(splash, (double) 8 / 8);

  if (splash)
    gtk_widget_destroy(GTK_WIDGET(splash));

  window = st_shell_get_window(st_shell);
  gtk_widget_show(GTK_WIDGET(window));

  gtk_main();

  GDK_THREADS_LEAVE();

  return 0;
}

static STSplash *
st_main_splash_create (void)
{
  GtkWidget *splash;

  gtk_window_set_auto_startup_notification(FALSE);
  splash = st_splash_new();
  gtk_widget_show(splash);

  sgtk_flush();
  gtk_window_set_auto_startup_notification(TRUE);

  return ST_SPLASH(splash);
}

static void
st_main_splash_set_text (STSplash *splash, const char *str)
{
  g_return_if_fail(str != NULL);

  if (splash)
    {
      st_splash_set_text(splash, str);
      sgtk_flush();
    }
}

static void
st_main_splash_set_progress (STSplash *splash, double progress)
{
  if (splash)
    {
      st_splash_set_progress(splash, progress);
      sgtk_flush();
    }
}

static void
st_main_parse_args (int argc, char **argv)
{
  const struct option options[] = {
    { "directory",	required_argument,	NULL,		'd' },
    { "help",		no_argument,		NULL,		'?' },
    { "version",	no_argument,		NULL,		'v' },
    { NULL,		0,			NULL,		0 },
  };
  int i;
  int c;

  st_main_argv = g_new0(char *, argc + 1);
  for (i = 0; i < argc; i++)
    st_main_argv[i] = g_strdup(argv[i]);
  st_main_argv[i] = NULL;

  while ((c = getopt_long(argc, argv, "d:?v", options, NULL)) != -1)
    switch (c)
      {
      case 'd':
	custom_private_dir = g_strdup(optarg);
	break;

      case '?':
	st_main_print_help();
	exit(0);

      case 'v':
	st_main_print_version();
	exit(0);

      default:
	g_return_if_reached();
      }
}

static void
st_main_print_help (void)
{
  g_print("%s\n", _("Usage: streamtuner [OPTIONS]"));
  g_print("\n");
  g_print("%s\n", _("Options:"));
  g_print("  -d, --directory=DIR      %s\n", _("Specify a configuration directory [~/.streamtuner]"));
  g_print("  -?, --help               %s\n", _("Show this help"));
  g_print("  -v, --version            %s\n", _("Show version information"));
}

static void
st_main_print_version (void)
{
  g_print(_("%s version %s\n"), PACKAGE, VERSION);
  g_print(ST_COPYRIGHT "\n");
}
