/*
 * Copyright (c) 2004 Jean-François Wauthy (pollux@xfce.org)
 *
 * 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 Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

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

#ifdef HAVE_STRING_H
#include <string.h>
#endif

/* */
#include <xfconf/xfconf.h>
#include <libxfcegui4/libxfcegui4.h>

#include <printing-system.h>

/* */
#define CHANNEL         "xfprint"

#define PROP_PRINTING_SYSTEM  "/printing-system"

#define SOEXT 		("." G_MODULE_SUFFIX)
#define SOEXT_LEN 	(strlen (SOEXT))
#define strequal(s1,s2) !strcmp (s1, s2)

#define BORDER          6

enum
{
  COLUMN_NAME,
  COLUMN_DESCRIPTION,
  COLUMN_VERSION,
  COLUMN_AUTHOR,
  COLUMN_HOMEPAGE,
  COLUMN_PATH,
  N_COLUMNS,
};

/* setting */
static gchar *printing_system = NULL;
static XfconfChannel *channel = NULL;

/* */
static GtkWidget *treeview;
static GtkWidget *label_description;
static GtkWidget *label_version;
static GtkWidget *label_author;
static GtkWidget *label_homepage;


/* static prototypes */
static GtkWidget *create_settings_dialog();

/* */
int
main (int argc, char **argv)
{
  gchar *s;

  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");

  gtk_init (&argc, &argv);

  xfconf_init(NULL);

  channel = xfconf_channel_new (CHANNEL);

  if (xfconf_channel_has_property (channel, PROP_PRINTING_SYSTEM)) {
    const gchar *system_name = xfconf_channel_get_string (channel, PROP_PRINTING_SYSTEM, "none");
    if ((s = strrchr (system_name, G_DIR_SEPARATOR))) {
      g_message ("xfprint: full path module, using basename: %s", ++s);
      printing_system = g_strdup (s);
    }
    else
      printing_system = g_strdup (system_name);
  }
  else {
    printing_system = g_strdup ("none");
    xfconf_channel_set_string (channel, PROP_PRINTING_SYSTEM, printing_system);
  }

  GtkWidget *dialog = create_settings_dialog();
  
  gtk_dialog_run (GTK_DIALOG(dialog));

  xfconf_shutdown();

  return 0;
}


static void
cb_selection_changed (GtkTreeSelection * selection, gpointer data)
{
  GtkTreeModel *model;
  GtkTreeIter iter;
  
  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    gchar *description = NULL;
    gchar *version = NULL;
    gchar *author = NULL;
    gchar *homepage = NULL;
    gchar *path = NULL;


    gtk_tree_model_get (model, &iter, COLUMN_DESCRIPTION, &description,
			COLUMN_VERSION, &version, COLUMN_AUTHOR, &author, COLUMN_HOMEPAGE, &homepage,
			COLUMN_PATH, &path, -1);


    if (description)
      gtk_label_set_text (GTK_LABEL (label_description), description);
    if (version)
      gtk_label_set_text (GTK_LABEL (label_version), version);
    if (author)
      gtk_label_set_text (GTK_LABEL (label_author), author);
    if (homepage)
      gtk_label_set_text (GTK_LABEL (label_homepage), homepage);
      
    g_free (printing_system);
    printing_system = g_strdup (path);

    xfconf_channel_set_string (channel, PROP_PRINTING_SYSTEM, printing_system);

    g_free (path);
    g_free (homepage);
    g_free (author);
    g_free (version);
    g_free (description);
  }
}

/* */
static GtkWidget *
create_settings_dialog ()
{
  GtkWidget *dialog;
  GtkWidget *hbox;
  GtkWidget *swin;
  GtkListStore *store;
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;
  GtkWidget *frame;
  GtkWidget *table;
  GtkWidget *label;
  gchar *label_text;

  GtkTreeModel *model;
  GtkTreeIter iter;

  GDir *gdir;
  GError *error = NULL;
  const char *file;
  GtkTreeSelection *selection;

  dialog = xfce_titled_dialog_new_with_buttons (_("Printing System Selection"),
                                        NULL, GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
  gtk_window_set_icon_name (GTK_WINDOW (dialog), "printer");

  hbox = gtk_hbox_new (FALSE, BORDER);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, BORDER);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), BORDER - 1);

  /* add printing systems list */
  swin = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start (GTK_BOX (hbox), swin, FALSE, FALSE, 0);

  store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
			      G_TYPE_STRING, G_TYPE_STRING);
  treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
  gtk_container_add (GTK_CONTAINER (swin), treeview);
  g_object_unref (G_OBJECT (store));

  column = gtk_tree_view_column_new ();
  renderer = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, renderer, FALSE);
  gtk_tree_view_column_set_attributes (column, renderer, "text", COLUMN_NAME, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);

  /* add information frame */
  frame = gtk_frame_new (_("Information"));
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
  table = gtk_table_new (4, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
  gtk_container_set_border_width (GTK_CONTAINER (table), 6);
  gtk_container_add (GTK_CONTAINER (frame), table);
  gtk_widget_show (table);

  label_text = g_strdup_printf ("<b>%s</b>", _("Description"));
  label = gtk_label_new (label_text);
  g_free (label_text);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
  label_description = gtk_label_new ("");
  gtk_label_set_line_wrap (GTK_LABEL (label_description), TRUE);
  gtk_label_set_selectable (GTK_LABEL (label_description), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label_description), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label_description, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);

  label_text = g_strdup_printf ("<b>%s</b>", _("Version"));
  label = gtk_label_new (label_text);
  g_free (label_text);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);

  label_version = gtk_label_new ("");
  gtk_label_set_selectable (GTK_LABEL (label_version), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label_version), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label_version, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);

  label_text = g_strdup_printf ("<b>%s</b>", _("Author"));
  label = gtk_label_new (label_text);
  g_free (label_text);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0);

  label_author = gtk_label_new ("");
  gtk_label_set_selectable (GTK_LABEL (label_author), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label_author), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label_author, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);

  label_text = g_strdup_printf ("<b>%s</b>", _("Homepage"));
  label = gtk_label_new (label_text);
  g_free (label_text);
  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0);

  label_homepage = gtk_label_new ("");
  gtk_label_set_selectable (GTK_LABEL (label_homepage), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label_homepage), 0, 0);
  gtk_table_attach (GTK_TABLE (table), label_homepage, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);

  /* handle selection */
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
  g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (cb_selection_changed), channel);

  /* Initialize printing system list */
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));

  /* Add the 'None' entry */
  gtk_list_store_append (GTK_LIST_STORE (model), &iter);
  gtk_list_store_set (GTK_LIST_STORE (model), &iter,
		      COLUMN_NAME, _("None"), 
		      COLUMN_DESCRIPTION, _("Use this backend if you just want to print to file."),
		      COLUMN_VERSION, VERSION,
		      COLUMN_AUTHOR, "Jean-François Wauthy",
		      COLUMN_HOMEPAGE, "http://www.xfce.org",
		      COLUMN_PATH, "none", -1);
  
  gdir = g_dir_open (PLUGIN_DIR, 0, &error);
  if (gdir) {
    while ((file = g_dir_read_name (gdir))) {
      const char *s = file;

      s += strlen (file) - SOEXT_LEN;

      if (strequal (s, SOEXT)) {
        char *path;
	PrintingSystem *ps = NULL;

        path = g_build_filename (PLUGIN_DIR, file, NULL);

	/* can be optimized by using directly g_module_open and binding the required symbols
	   instead of using printing_system_new 
	*/
	ps = printing_system_new (path);

	if (ps) {
          gtk_list_store_append (GTK_LIST_STORE (model), &iter);
          gtk_list_store_set (GTK_LIST_STORE (model), &iter,
                              COLUMN_NAME, ps->name,
			      COLUMN_DESCRIPTION, _(ps->description),
			      COLUMN_VERSION, ps->version,
			      COLUMN_AUTHOR, ps->author,
			      COLUMN_HOMEPAGE, ps->homepage,
			      COLUMN_PATH, file, -1);

          if (strcmp (file, printing_system) == 0) {
            GtkTreePath *treepath;

            treepath = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
            gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), treepath, NULL, FALSE);
            gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview), treepath, NULL, TRUE, 0.5, 0.0);
            gtk_tree_path_free (treepath);
          }
	  g_object_unref (ps);
        } else {
          g_warning ("%s isn't a xfprint printing system module", path);
        }

        g_free (path);
      }
    }
    g_dir_close (gdir);
  } else {
    g_warning ("An error occurred in the opening of the plugin directory (%d): %s", error->code, error->message);
    g_error_free (error);
  }

  xfce_gtk_window_center_on_monitor_with_pointer (GTK_WINDOW (dialog));
  gtk_widget_show_all (dialog);
  return dialog;
}

