/*
 *  Copyright (c) 2006 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

#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

#include <libxfcegui4/libxfcegui4.h>

#include <printing-system.h>

#include "filter.h"
#include "input_page.h"
#include "head_page.h"
#include "pprint_page.h"
#include "sheets_page.h"
#include "vpages_page.h"
#include "xfprintsettings.h"

#include "print_dialog.h"

#define BORDER 4

#define PRINT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PRINT_DIALOG_TYPE, PrintDialogPrivate))

/* Prototypes */
static void checkbutton_apply_filters_toggled_cb (GtkToggleButton *button, PrintDialog *dlg);
static void radiobutton_printtobackend_toggled_cb (GtkToggleButton *button, PrintDialog *dlg);
static void radiobutton_printtofile_toggled_cb (GtkToggleButton *button, PrintDialog *dlg);
static void button_select_file_clicked_cb (GtkWidget *widget, PrintDialog *dlg);
static void button_save_clicked_cb (GtkWidget * widget, PrintDialog *dlg);
static void dialog_response_cb (GtkDialog *dialog, gint response, PrintDialog *dlg);
static XfprintFilter *a2ps_filter (const XfprintSettings * settings, const gchar * ifile);

static void print_dialog_class_init (PrintDialogClass * klass);
static void print_dialog_init (PrintDialog * sp);
static void print_dialog_finalize (GObject * object);
static void print_dialog_set_printing_system (PrintDialog *dlg, PrintingSystem *ps);

enum {
  PRINTER_ICON_COLUMN,
  PRINTER_NAME_COLUMN,
  PRINTER_ALIAS_COLUMN,
  PRINTER_N_COLUMNS
};

struct PrintDialogPrivate
{
  const gchar *input_file;
  GtkIconTheme *icontheme;
  XfprintSettings *settings;
  
  GtkWidget *radiobutton_printto_backend;
  GtkWidget *combobox_printer;
  GtkWidget *radiobutton_printto_file;
  GtkWidget *entry_file;
  GtkWidget *notebook;
  GtkWidget *sheets;
  GtkWidget *vpages;
  GtkWidget *pprint;
  GtkWidget *input;
  GtkWidget *head;
  
  GtkWidget *copies;
  GtkWidget *checkbutton_apply_filters;
  
  PrintingSystem *ps;
};

enum {
  PROP_0,
  PROP_PRINTING_SYSTEM,
};

static GtkDialogClass *parent_class = NULL;

GType
print_dialog_get_type ()
{
  static GType type = 0;

  if (type == 0) {
    static const GTypeInfo our_info = {
      sizeof (PrintDialogClass),
      NULL,
      NULL,
      (GClassInitFunc) print_dialog_class_init,
      NULL,
      NULL,
      sizeof (PrintDialog),
      0,
      (GInstanceInitFunc) print_dialog_init,
    };

    type = g_type_register_static (GTK_TYPE_DIALOG, "PrintDialog", &our_info, 0);
  }

  return type;
}

static void
print_dialog_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (object);
  
  switch (prop_id)
    {
    case PROP_PRINTING_SYSTEM:
      g_value_set_object (value, priv->ps);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
    
static void
print_dialog_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
  PrintDialog *dlg = PRINT_DIALOG (object);

  switch (prop_id)
    {
    case PROP_PRINTING_SYSTEM:
      print_dialog_set_printing_system (dlg, g_value_get_object (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}


static void
print_dialog_class_init (PrintDialogClass * klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GParamSpec *param_spec;
  
  g_type_class_add_private (klass, sizeof (PrintDialogPrivate));
  
  parent_class = g_type_class_peek_parent (klass);
  
  object_class->finalize = print_dialog_finalize;
  object_class->get_property = print_dialog_get_property;
  object_class->set_property = print_dialog_set_property;
  
  param_spec = g_param_spec_object ("printing-system", "printing system prop", "set printing system",
                                    PRINTING_SYSTEM_TYPE, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);

  g_object_class_install_property (object_class, PROP_PRINTING_SYSTEM, param_spec);
}

static void
print_dialog_init (PrintDialog * obj)
{
  PrintDialogPrivate *dlg;
  
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *button_save;
  GtkWidget *button_select_file;
  GtkWidget *image;
  GSList *group;
  GtkListStore *store;
  GtkCellRenderer *cell;

  gchar *path;

  dlg = obj->priv = PRINT_DIALOG_GET_PRIVATE (obj);
 
  dlg->icontheme = gtk_icon_theme_get_default ();
  
  gtk_window_set_icon_name (GTK_WINDOW (obj), "printer");
  
  button_save = xfce_create_mixed_button (GTK_STOCK_SAVE, _("Save settings"));
  g_signal_connect (G_OBJECT (button_save), "clicked", G_CALLBACK (button_save_clicked_cb), obj);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (obj)->action_area), button_save, TRUE, TRUE, 0);

  gtk_dialog_add_buttons (GTK_DIALOG (obj),
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_PRINT, GTK_RESPONSE_OK, NULL);

  gtk_window_set_default_size (GTK_WINDOW (obj), 300, 10);
  gtk_window_set_title (GTK_WINDOW (obj), _("Xfprint"));

  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (obj)->vbox), BORDER);
  gtk_widget_show (button_save);
  
  /* Print to */
  hbox = gtk_hbox_new (FALSE, BORDER);
    
  dlg->radiobutton_printto_backend = gtk_radio_button_new_with_label (NULL, _("Print to:"));   
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (dlg->radiobutton_printto_backend));
  gtk_box_pack_start (GTK_BOX (hbox), dlg->radiobutton_printto_backend, FALSE, TRUE, BORDER);
  
  store = gtk_list_store_new (PRINTER_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
  dlg->combobox_printer = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
  
  cell = gtk_cell_renderer_pixbuf_new ();
  g_object_set (cell, "xalign", 0.0, "ypad", 0, NULL);
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, "pixbuf", PRINTER_ICON_COLUMN, NULL);
  
  cell = gtk_cell_renderer_text_new ();
  g_object_set (cell, "ypad", 0, "yalign", 0.5, NULL);
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, "text", PRINTER_NAME_COLUMN, NULL);
  
  cell = gtk_cell_renderer_text_new ();
  g_object_set (cell, "ypad", 0, "yalign", 0.5, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, "width-chars", 35, NULL);
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (dlg->combobox_printer), cell, "text", PRINTER_ALIAS_COLUMN, NULL);
  
  gtk_box_pack_start (GTK_BOX (hbox), dlg->combobox_printer, TRUE, TRUE, BORDER);
  
  gtk_widget_show_all (hbox);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (obj)->vbox), hbox, TRUE, TRUE, 0);
              
  /* Print to file */
  hbox = gtk_hbox_new (FALSE, BORDER);
  
  dlg->radiobutton_printto_file = gtk_radio_button_new_with_label (group, _("Print to file:"));
  gtk_box_pack_start (GTK_BOX (hbox), dlg->radiobutton_printto_file, FALSE, TRUE, BORDER);  
    
  dlg->entry_file = gtk_entry_new ();
  gtk_widget_set_sensitive (dlg->entry_file, FALSE);
  gtk_box_pack_start (GTK_BOX (hbox), dlg->entry_file, TRUE, TRUE, 0);

  /* set default value in print to */
  path = xfce_get_homefile ("print.ps", NULL);
  gtk_entry_set_text (GTK_ENTRY (dlg->entry_file), path);
  g_free (path);

  button_select_file = gtk_button_new ();
  g_signal_connect (G_OBJECT (button_select_file), "clicked",
   		    G_CALLBACK (button_select_file_clicked_cb), obj);
  
  image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
  gtk_container_add (GTK_CONTAINER (button_select_file), image);
  gtk_box_pack_start (GTK_BOX (hbox), button_select_file, FALSE, TRUE, 0);
    
  gtk_widget_show_all (hbox);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (obj)->vbox), hbox,
		      TRUE, TRUE, 0);

  /* Notebook */
  dlg->notebook = gtk_notebook_new ();
  gtk_container_set_border_width (GTK_CONTAINER (dlg->notebook), 5);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (obj)->vbox), dlg->notebook, TRUE, TRUE, 0);

  dlg->sheets = sheets_page_new ();
  label = gtk_label_new (_("Sheets"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_notebook_append_page (GTK_NOTEBOOK (dlg->notebook), dlg->sheets, label);

  dlg->vpages = vpages_page_new ();
  label = gtk_label_new (_("Virtual pages"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_notebook_append_page (GTK_NOTEBOOK (dlg->notebook), dlg->vpages, label);

  dlg->pprint = pprint_page_new ();
  label = gtk_label_new (_("Pretty-printing"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_notebook_append_page (GTK_NOTEBOOK (dlg->notebook), dlg->pprint, label);

  dlg->input = input_page_new ();
  label = gtk_label_new (_("Input"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_notebook_append_page (GTK_NOTEBOOK (dlg->notebook), dlg->input, label);

  dlg->head = head_page_new ();
  label = gtk_label_new (_("Headings"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_notebook_append_page (GTK_NOTEBOOK (dlg->notebook), dlg->head, label);

  /* number of copies */
  hbox = gtk_hbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (obj)->vbox), hbox, FALSE, TRUE, 0);

  label = gtk_label_new (_("Copies:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  dlg->copies = gtk_spin_button_new_with_range (1.0, 1000.0, 1.0);
  gtk_box_pack_start (GTK_BOX (hbox), dlg->copies, FALSE, FALSE, 0);

  dlg->checkbutton_apply_filters = gtk_check_button_new_with_label (_("Apply filters"));
  gtk_box_pack_end (GTK_BOX (hbox), dlg->checkbutton_apply_filters, FALSE, FALSE, 0);
  gtk_widget_show_all (hbox);
  g_signal_connect (G_OBJECT (dlg->checkbutton_apply_filters), "toggled", 
                    G_CALLBACK (checkbutton_apply_filters_toggled_cb), obj);
  
  gtk_widget_show_all (GTK_WIDGET (dlg->notebook));

    
  /* load the settings */
  dlg->settings = xfprintsettings_load ();
  sheets_page_set_settings (SHEETS_PAGE (dlg->sheets), &dlg->settings->sheets);
  vpages_page_set_settings (VPAGES_PAGE (dlg->vpages), &dlg->settings->vpages);
  pprint_page_set_settings (PPRINT_PAGE (dlg->pprint), &dlg->settings->pprint);
  input_page_set_settings (INPUT_PAGE (dlg->input), &dlg->settings->input);
  head_page_set_settings (HEAD_PAGE (dlg->head), &dlg->settings->headings);

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->copies), dlg->settings->copies);
  
  g_signal_connect (G_OBJECT (dlg->radiobutton_printto_backend), "toggled",
                    G_CALLBACK (radiobutton_printtobackend_toggled_cb), obj);
  g_signal_connect (G_OBJECT (dlg->radiobutton_printto_file), "toggled",
                    G_CALLBACK (radiobutton_printtofile_toggled_cb), obj);
  
  g_signal_connect (G_OBJECT (obj), "response", G_CALLBACK (dialog_response_cb), obj);
}

static void
print_dialog_finalize (GObject * object)
{
  PrintDialog *cobj;
  cobj = PRINT_DIALOG (object);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
print_dialog_set_printing_system (PrintDialog *dlg, PrintingSystem *ps)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);
  gchar *ret;
  gboolean a2ps_found = FALSE;
  GList *printers, *printer;
  Printer *default_printer;
  GtkTreeModel *model;
  GtkTreeIter iter;
  GdkPixbuf *icon_class, *icon_printer;
  
  priv->ps = ps;
  
  ret = g_find_program_in_path ("a2ps");
  a2ps_found = (ret != NULL);
  g_free (ret);
    
  if (!ps && !a2ps_found) {
    xfce_err (_("Neither the printing system backend or a2ps could be found on your system, you won't be able to print a file with xfprint !"));
    exit (1);
  }
  
  /* (de)activate dialog elements */
  if (ps) {
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_printto_backend), TRUE);
    gtk_widget_set_sensitive (priv->entry_file, FALSE);
  } else {
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_printto_file), TRUE);
    gtk_widget_set_sensitive (priv->entry_file, TRUE);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_printto_backend), FALSE);
    gtk_widget_set_sensitive (priv->radiobutton_printto_backend, FALSE);
    gtk_widget_set_sensitive (priv->combobox_printer, FALSE);
    gtk_widget_set_sensitive (priv->checkbutton_apply_filters, FALSE);
    gtk_widget_set_sensitive (priv->copies, FALSE);
  }
  
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_apply_filters), a2ps_found);
  gtk_widget_set_sensitive (priv->checkbutton_apply_filters, a2ps_found);
  gtk_widget_set_sensitive (priv->notebook, a2ps_found); 
  
  /* load printer list */
  printer = printers = printing_system_get_printers (ps);
  default_printer = printing_system_get_default_printer (ps);
  
  icon_printer = gtk_icon_theme_load_icon (priv->icontheme, "printer", 16, 0, NULL);
  icon_class = gtk_icon_theme_load_icon (priv->icontheme, "printer-class", 16, 0, NULL);
  
  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combobox_printer));
  gtk_list_store_clear (GTK_LIST_STORE (model));
  
  while (printer) {
    static gboolean default_printer_found = FALSE;
    
    Printer *printer_data = (Printer *) printer->data;
    
    gtk_list_store_append (GTK_LIST_STORE (model), &iter);
    gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
                        PRINTER_ICON_COLUMN, printer_data->type == PRINTER_TYPE_PRINTER ? icon_printer : icon_class, 
                        PRINTER_NAME_COLUMN, printer_data->name, 
                        PRINTER_ALIAS_COLUMN, printer_data->alias ? printer_data->alias : "", -1);
    
    if (default_printer && !default_printer_found && g_ascii_strcasecmp (default_printer->name, printer_data->name) == 0) {
      default_printer_found = TRUE;
      gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->combobox_printer), &iter);
    }
    
    printer = g_list_next (printer);
  }

  if (G_LIKELY (G_IS_OBJECT (icon_printer)))
    g_object_unref (icon_printer);
  if (G_LIKELY (G_IS_OBJECT (icon_class)))
    g_object_unref (icon_class);
  
  printers_free (printers);
}

/*************/
/* callbacks */
/*************/
static void
dialog_response_cb (GtkDialog *dialog, gint response, PrintDialog *dlg) 
{
  if (response == GTK_RESPONSE_OK) {
    PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);
    gchar *ofile = NULL;
    int output = -1;
    
    XfprintFilterList *filters;
    XfprintFilter *filter;
    
    filters = xfprint_filterlist_new ();
    
    if (GTK_WIDGET_IS_SENSITIVE (priv->entry_file)) {
      ofile = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry_file)));
      output = open (ofile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP);
      
      filter = a2ps_filter (priv->settings, priv->input_file);
      xfprint_filterlist_append (filters, filter);

      if (priv->settings->sheets.reverse) {
        filter = xfprint_filter_new ("psselect");
        xfprint_filter_add (filter, "-r");
        xfprint_filterlist_append (filters, filter);
      }
      
      xfprint_filterlist_execute (filters, STDIN_FILENO, output, STDERR_FILENO);
      (void) close (output);  
    } else {   
      GtkTreeIter iter;
      
      if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbutton_apply_filters)) ) {
        output = g_file_open_tmp ("xfprintXXXXXX", &ofile, NULL);
        
        filter = a2ps_filter (priv->settings, priv->input_file);
        xfprint_filterlist_append (filters, filter);

        if (priv->settings->sheets.reverse) {
          filter = xfprint_filter_new ("psselect");
          xfprint_filter_add (filter, "-r");
          xfprint_filterlist_append (filters, filter);
        }
      
        xfprint_filterlist_execute (filters, STDIN_FILENO, output, STDERR_FILENO);
        (void) close (output);  
      } else 
        ofile = g_strdup (priv->input_file);
      
      if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->combobox_printer), &iter)) {
        gchar *printer = NULL;
        GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combobox_printer));
        
        gtk_tree_model_get (model, &iter, PRINTER_NAME_COLUMN, &printer, -1);
        
        if (!printing_system_print_file (priv->ps, printer, priv->input_file, ofile, 
					 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbutton_apply_filters))))
          xfce_err (_("An error occurred while trying to print the file"));
      
        g_free (printer);
      }
    }
        
    g_free (ofile);
    xfprint_filterlist_free (filters);
  }
}

static void
button_save_clicked_cb (GtkWidget * widget, PrintDialog *dlg)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);
  XfprintSettings *settings;
  
  settings = xfprintsettings_defaults ();

  sheets_page_get_settings (SHEETS_PAGE (priv->sheets), &settings->sheets);
  vpages_page_get_settings (VPAGES_PAGE (priv->vpages), &settings->vpages);
  pprint_page_get_settings (PPRINT_PAGE (priv->pprint), &settings->pprint);
  input_page_get_settings (INPUT_PAGE (priv->input), &settings->input);
  head_page_get_settings (HEAD_PAGE (priv->head), &settings->headings);
  settings->copies = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->copies));

  xfprintsettings_save (settings);
  xfprintsettings_free (settings);
}

static void button_select_file_clicked_cb (GtkWidget *widget, PrintDialog *dlg)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);
  GtkWidget *selection;
  gint response = GTK_RESPONSE_NONE;
  gchar *file = NULL;

  selection = gtk_file_chooser_dialog_new (_("Select file where to print"),
				     GTK_WINDOW (dlg),
				     GTK_FILE_CHOOSER_ACTION_SAVE,
				     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				     GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);

  response = gtk_dialog_run (GTK_DIALOG (selection));
  
  if (response == GTK_RESPONSE_OK) {
    file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selection));
    
    gtk_entry_set_text (GTK_ENTRY (priv->entry_file), file);
    
    g_free (file);
  }
  
  gtk_widget_destroy (selection);
}

static void checkbutton_apply_filters_toggled_cb (GtkToggleButton *button, PrintDialog *dlg)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);

  gtk_widget_set_sensitive (priv->notebook, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbutton_apply_filters)));
}

static void radiobutton_printtobackend_toggled_cb (GtkToggleButton *button, PrintDialog *dlg)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);

  if (gtk_toggle_button_get_active (button)) {
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_printto_file), FALSE);
    gtk_widget_set_sensitive (priv->combobox_printer, TRUE);
    gtk_widget_set_sensitive (priv->entry_file, FALSE);
    gtk_widget_set_sensitive (priv->checkbutton_apply_filters, TRUE);
    gtk_widget_set_sensitive (priv->copies, TRUE);
  }
}

static void radiobutton_printtofile_toggled_cb (GtkToggleButton *button, PrintDialog *dlg)
{
  PrintDialogPrivate *priv = PRINT_DIALOG_GET_PRIVATE (dlg);
  
  if (gtk_toggle_button_get_active (button)) {
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_printto_backend), FALSE);
    gtk_widget_set_sensitive (priv->combobox_printer, FALSE);
    gtk_widget_set_sensitive (priv->entry_file, TRUE);
    gtk_widget_set_sensitive (priv->checkbutton_apply_filters, FALSE);
    gtk_widget_set_sensitive (priv->copies, FALSE);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_apply_filters), TRUE);
  } 
}

static XfprintFilter *
a2ps_filter (const XfprintSettings * settings, const gchar * ifile)
{
  XfprintFilter *filter;

  filter = xfprint_filter_new ("a2ps");

  /* sheet settings */
  xfprint_filter_add (filter, "--medium=%s", settings->sheets.papersize);
  if (settings->sheets.landscape)
    xfprint_filter_add (filter, "--landscape");
  else
    xfprint_filter_add (filter, "--portrait");
  xfprint_filter_add (filter, "--columns=%d", settings->sheets.cols);
  xfprint_filter_add (filter, "--rows=%d", settings->sheets.rows);
  if (settings->sheets.fillcols)
    xfprint_filter_add (filter, "--major=columns");
  else
    xfprint_filter_add (filter, "--major=rows");
  if (settings->sheets.borders)
    xfprint_filter_add (filter, "--borders=yes");
  else
    xfprint_filter_add (filter, "--borders=no");

  /* virtual pages settings */
  xfprint_filter_add (filter, "--line-numbers=%d", settings->vpages.linenumbers);
  if (settings->vpages.lpp > 0)
    xfprint_filter_add (filter, "--lines-per-page=%d", settings->vpages.lpp);
  if (settings->vpages.cpl > 0)
    xfprint_filter_add (filter, "--chars-per-line=%d", settings->vpages.cpl);
  xfprint_filter_add (filter, "--tabsize=%d", settings->vpages.tabsize);
  xfprint_filter_add (filter, "--non-printable-format=%s", settings->vpages.nonprtfmt);

  /* pretty print settings */
  if (strcmp (settings->pprint.language, "__auto__") != 0)
    xfprint_filter_add (filter, "--pretty-print=%s", settings->pprint.language);
  xfprint_filter_add (filter, "--highlight-level=%s", settings->pprint.highlight);
  xfprint_filter_add (filter, "--strip-level=%d", settings->pprint.strip);

  /* input settings */
  xfprint_filter_add (filter, "--encoding=%s", settings->input.encoding);
  if (!settings->input.all) {
    xfprint_filter_add (filter, "--pages=%d-%d", settings->input.from, settings->input.to);
  }
  if (settings->input.cut)
    xfprint_filter_add (filter, "--truncate-lines=yes");
  else
    xfprint_filter_add (filter, "--truncate-lines=no");
  if (settings->input.interpret)
    xfprint_filter_add (filter, "--interpret=yes");
  else
    xfprint_filter_add (filter, "--interpret=no");
  if (settings->input.binary)
    xfprint_filter_add (filter, "--print-anyway=yes");
  else
    xfprint_filter_add (filter, "--print-anyway=no");

  /* headings settings */
  if (!settings->headings.headers) {
    xfprint_filter_add (filter, "--no-header");
  }
  else {
    xfprint_filter_add (filter, "--header=%s", settings->headings.header);
    xfprint_filter_add (filter, "--underlay=%s", settings->headings.underlay);
    xfprint_filter_add (filter, "--center-title=%s", settings->headings.ctitle);
    xfprint_filter_add (filter, "--left-title=%s", settings->headings.ltitle);
    xfprint_filter_add (filter, "--right-title=%s", settings->headings.rtitle);
    xfprint_filter_add (filter, "--left-footer=%s", settings->headings.lfooter);
    xfprint_filter_add (filter, "--footer=%s", settings->headings.cfooter);
    xfprint_filter_add (filter, "--right-footer=%s", settings->headings.rfooter);
  }

  xfprint_filter_add (filter, "--output=-");
  xfprint_filter_add (filter, "%s", ifile);

  return (filter);
}

/*        */
/* public */
/*        */
GtkWidget *
print_dialog_new (PrintingSystem *ps, const gchar *input_file)
{
  PrintDialog *obj;
  
  g_return_val_if_fail (input_file, NULL);
  
  obj = PRINT_DIALOG (g_object_new (PRINT_DIALOG_TYPE, "printing-system", ps, NULL));

  obj->priv->input_file = input_file;
  
  return GTK_WIDGET (obj);
}
