/* Nessus
 * Copyright (C) 1998 - 2001 Renaud Deraison
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation
 *
 * 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, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * In addition, as a special exception, Renaud Deraison
 * gives permission to link the code of this program with any
 * version of the OpenSSL library which is distributed under a
 * license identical to that listed in the included COPYING.OpenSSL
 * file, and distribute linked combinations including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * this file, you may extend this exception to your version of the
 * file, but you are not obligated to do so.  If you do not wish to
 * do so, delete this exception statement from your version.
 *
 * This code deals with the 'save report' dialog.
 */


#include <includes.h>
#ifdef USE_GTK
#include <gtk/gtk.h>
#include "xstuff.h"

#include "preferences.h"
#include "context.h"
#include "error_dialog.h"
#include "backend.h"
#include "nsr_output.h"
#include "html_output.h"
#include "report_utils.h"
#include "error_dialog.h"
#include "latex_output.h"
#include "text_output.h"
#include "xml_output.h"
#include "xml_output_ng.h"
#include "html_graph_output.h"
#include "nbe_output.h"
#include "pdf_output.h"

#include "nessus_i18n.h"

#include "globals.h"

#define SAVE_NBE 	0
#define SAVE_NSR 	1
#define SAVE_HTML 	2
#define SAVE_TEXT 	3
#define SAVE_LATEX 	4
#define SAVE_HTML_GRAPH 5
#define SAVE_PDF 	6
#define SAVE_XML 	7
#define SAVE_XML_NG 	8
#define SAVE_MAX SAVE_XML_NG


/*------------------------------------------------------------------------*/

static int
file_save_ok_callback(widget, filedialog)
  GtkWidget *widget;
  GtkWidget *filedialog;
{
  const char *filename =
    gtk_file_selection_get_filename(GTK_FILE_SELECTION(filedialog));
  char *basename = g_path_get_basename(filename);
  char *ext = strrchr(basename, '.');
  char *fname;
  struct arglist *hosts = NULL;
  GtkWidget *menu = gtk_object_get_data(GTK_OBJECT(filedialog), "menu");
  GtkWidget *active = gtk_menu_get_active(GTK_MENU(menu));
  int type = (int)gtk_object_get_data(GTK_OBJECT(active), "type");
  char *suffixes[] =
      { ".nbe", ".nsr", ".html", ".txt", ".tex", "", ".pdf", ".xml", ".xml" };
#define MAX_SUFFIX_LEN 5	/* .html */
  char *suffix = suffixes[type];
  int be = (int)arg_get_value(arg_get_value(MainDialog, "REPORT"), "BE");

  gtk_widget_hide(filedialog);

  if(check_is_dir(filename))
    fname = g_build_filename(filename, basename, NULL);
  else
    fname = g_strdup(filename);

  /*
   * Add a default extension
   */
  if(suffix && (!ext || strcmp(ext, suffix)))
  {
    char *tmpname = g_strdup_printf("%s%s", fname, suffix);

    g_free(fname);
    fname = tmpname;
  }

  switch (type)
  {
    case SAVE_HTML:
      hosts = backend_convert(be);
      arglist_to_html(hosts, fname);
      break;
    case SAVE_XML:
      hosts = backend_convert(be);
      arglist_to_xml(hosts, fname);
      break;
    case SAVE_XML_NG:
      backend_to_xml_ng(be, fname);
      break;
    case SAVE_LATEX:
      hosts = backend_convert(be);
      arglist_to_latex(hosts, fname);
      break;
    case SAVE_TEXT:
      hosts = backend_convert(be);
      arglist_to_text(hosts, fname);
      break;
#ifndef _NOPIE
    case SAVE_HTML_GRAPH:
      hosts = backend_convert(be);
      arglist_to_html_graph(hosts, fname);
      break;
#endif
    case SAVE_PDF:
      arglist_to_pdf(be, fname);
      break;
    case SAVE_NSR:
      backend_to_nsr(be, fname);
      break;
    case SAVE_NBE:
    default:
      backend_to_nbe(be, fname);
      break;
  }
  g_free(basename);
  g_free(fname);
  if(hosts)
    arg_free_all(hosts);
  gtk_widget_destroy(filedialog);
  return 0;
}

/*
 *  "inspired" from the Gimp 1.2.2
 * See gimp/app/fileops.c for a cleaner function
 */
void
report_save_cb(window)
  GtkWidget *window;
{
  GtkWidget *filesave;
  GtkWidget *frame;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *option_menu;
  GtkWidget *menu;
  GtkWidget *save_options;
  GtkWidget *type;

  filesave = gtk_file_selection_new(_("Export Report"));

  gtk_window_set_position(GTK_WINDOW(filesave), GTK_WIN_POS_MOUSE);

  gtk_container_border_width(GTK_CONTAINER(filesave), 2);
  gtk_container_border_width(GTK_CONTAINER(GTK_FILE_SELECTION(filesave)->
	  button_area), 2);

  g_signal_connect(GTK_FILE_SELECTION(filesave)->ok_button,
      "clicked", G_CALLBACK(file_save_ok_callback), filesave);

  g_signal_connect_swapped(GTK_FILE_SELECTION(filesave)->cancel_button,
      "clicked", G_CALLBACK(gtk_widget_destroy), filesave);

  save_options = gtk_hbox_new(TRUE, 1);

  frame = gtk_frame_new(_("Export Options"));
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start(GTK_BOX(save_options), frame, TRUE, TRUE, 4);

  hbox = gtk_hbox_new(FALSE, 4);
  gtk_container_border_width(GTK_CONTAINER(hbox), 4);
  gtk_container_add(GTK_CONTAINER(frame), hbox);
  gtk_widget_show(hbox);

  label = gtk_label_new(_("Report file format : "));
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
  gtk_widget_show(label);

  option_menu = gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), option_menu, TRUE, TRUE, 0);
  gtk_widget_show(option_menu);


 /*---------------------------------------------------------------*
  *	We fill the dialog with the various export formats
  *	we know about
  *---------------------------------------------------------------*/
  menu = gtk_menu_new();
  gtk_object_set_data(GTK_OBJECT(filesave), "menu", menu);

  type = gtk_menu_item_new_with_label("NBE");
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_NBE);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);


  type = gtk_menu_item_new_with_label(_("NSR (deprecated)"));
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_NSR);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

  type = gtk_menu_item_new_with_label("XML");
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_XML_NG);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

  type = gtk_menu_item_new_with_label(_("XML (old style - deprecated)"));
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_XML);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);


  type = gtk_menu_item_new_with_label("HTML");
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_HTML);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

  type = gtk_menu_item_new_with_label("LaTeX");
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_LATEX);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

  type = gtk_menu_item_new_with_label(_("ASCII text"));
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_TEXT);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

#ifndef _NO_PIES
  type = gtk_menu_item_new_with_label(_("HTML with Pies and Graphs"));
  gtk_object_set_data(GTK_OBJECT(type), "type", (void *)SAVE_HTML_GRAPH);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);
#endif

  type = gtk_menu_item_new_with_label("PDF");
  gtk_object_set_data(GTK_OBJECT(type), "type", (void*)SAVE_PDF);
  gtk_menu_append(GTK_MENU(menu), type);
  gtk_widget_show(type);

 /*----------------------------------------------------------------*/
  gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu);
  gtk_widget_show(menu);
  gtk_widget_show(frame);

  /* pack the containing save_options hbox into the save-dialog */
  gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(filesave)->main_vbox),
      save_options, FALSE, FALSE, 0);
  gtk_widget_show(save_options);
  gtk_widget_show(filesave);
}

/*
 * Open a pdf file with the configured pdf viewer.
 * XXX: This function eventually should be moved into a more
 * suitable module.
 */
void
show_pdf(filename)
  char * filename;
{
  const gchar *pdfviewer = prefs_get_string(Global, "pdfviewer");

  if (!check_is_file(filename))
  {
    show_warning(_("PDF file %s not found."), filename);
    return;
  }

  if (!pdfviewer)
  {
    show_warning(_("You haven't configured a PDF viewer."
                   "\nThe report was saved as %s so you can manually open it."),
                 filename);
    return;
  }

  {
  gchar *cmd = g_strdup_printf("'%s' '%s'", pdfviewer, filename);

  /* start PDF viewer */
  if(!g_spawn_command_line_async(cmd, NULL))
    show_error(_("Can't launch PDF viewer: %s"), pdfviewer);
  g_free(cmd);
  }
}

void
report_open_pdf(menuitem, ctrls)
  GtkWidget *menuitem;
  gpointer ctrls;
{
  int be = (int)arg_get_value(arg_get_value(ctrls, "REPORT"), "BE");
  char *basename = g_path_get_basename(Context->dir);
  char *fname = g_strdup_printf("%s.pdf", basename);
  char *filename = g_build_filename(Context->dir, fname, NULL);

  g_free(basename);
  g_free(fname);

  arglist_to_pdf(be, filename);

  show_pdf(filename);
  g_free(filename);
}

#endif
