/* Copyright (C) 2010, 2011 Martin Linder <mali2297@users.sf.net>
 * 
 * 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.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
 */
#include <gio/gio.h>
#include "e6x-dialogs.h"
#include "e6x-common.h"
#include "e6x-util.h"
#include "e6x-pref.h"
#include "e6x-properties-dialog.h"


E6xDocument *
e6x_dialogs_open_file (GtkWindow *win)
{
  GtkWidget *dialog;
  GtkFileFilter *filter = NULL;
  E6xDocument *doc = NULL;
  gint response = 0;
  
  dialog  = gtk_file_chooser_dialog_new (_("Open Document"),
                                         win,
                                         GTK_FILE_CHOOSER_ACTION_OPEN,
                                         GTK_STOCK_CANCEL, 
                                         GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OPEN, 
                                         GTK_RESPONSE_ACCEPT,
                                         NULL);
  
  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), 
                                       g_get_home_dir ());
  
  filter = gtk_file_filter_new ();
#ifdef ENABLE_PDF
  gtk_file_filter_add_mime_type (filter, "application/pdf");
#endif
#ifdef ENABLE_PS
  gtk_file_filter_add_mime_type (filter, "application/postscript");
#endif
  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog),
                               filter);
  
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response == GTK_RESPONSE_ACCEPT)
  {
    gchar *filename = NULL;
    GError *error = NULL;
    
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    doc = e6x_util_open_document (filename, NULL, &error);
    
    if (error != NULL)
    {
      e6x_dialogs_show_error_message (win, error->message);
      g_clear_error (&error);
    }
    g_free (filename);
  }
  
  gtk_widget_destroy (dialog);
  
  return doc;
}


E6xDocument *
e6x_dialogs_decrypt (E6xDocument *doc,
                     GtkWindow *win)
{
  gchar *passwd = NULL;
  E6xDocument *new_doc = NULL;
  GError *error = NULL;
  
  g_return_val_if_fail (doc != NULL, NULL);
  
  passwd = e6x_dialogs_get_password (win);
  new_doc = e6x_util_open_document (doc->filename, passwd, &error);
  g_free (passwd);
  
  if (error != NULL)
  {
    e6x_dialogs_show_error_message (win, error->message);
    g_clear_error (&error);
  }
  
  return new_doc;
}


void
e6x_dialogs_save_copy (E6xDocument *doc,
                       GtkWindow *win)
{
  gchar *filename = NULL;
  GError *error = NULL;
    
  g_return_if_fail (doc != NULL);
  
  filename = e6x_dialogs_get_copyname (doc->filename, _("Save Copy"), win);
  e6x_document_save_copy (doc, filename, &error);
    
  if (error != NULL)
  {
    e6x_dialogs_show_error_message (win, error->message);
    g_clear_error (&error);
  }  
  g_free (filename);
  
  return;
}


gchar *
e6x_dialogs_get_copyname (const gchar *filename,
                          const gchar *dialogtitle,
                          GtkWindow *win)
{
  GtkWidget *dialog = NULL;
  GtkFileChooser *chooser = NULL;
  GtkFileFilter *filter = NULL;
  gchar *basename = NULL;
  gchar *mime_type = NULL;
  gchar *new_filename = NULL;
  gint response = 0;
  
  dialog  = gtk_file_chooser_dialog_new (dialogtitle,
                                         win,
                                         GTK_FILE_CHOOSER_ACTION_SAVE,
                                         GTK_STOCK_CANCEL, 
                                         GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_SAVE, 
                                         GTK_RESPONSE_ACCEPT,
                                         NULL);
  
  chooser = GTK_FILE_CHOOSER (dialog);
  g_object_set (chooser, "do-overwrite-confirmation", TRUE, NULL);
  
  gtk_file_chooser_set_current_folder (chooser, g_get_home_dir ());
  basename = g_path_get_basename (filename);
  gtk_file_chooser_set_current_name (chooser, basename);
  
  mime_type = e6x_util_get_mime_type (filename, NULL);
  if (mime_type != NULL)
  {
    filter = gtk_file_filter_new ();
    gtk_file_filter_add_mime_type (filter, mime_type);
    gtk_file_chooser_set_filter (chooser, filter);
  }
  
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response == GTK_RESPONSE_ACCEPT)
    new_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
  
  g_free (basename);
  g_free (mime_type);
  gtk_widget_destroy (dialog);
  
  return new_filename;
}


void 
e6x_dialogs_print (E6xDocument *doc, GtkWindow *win)
{
  GKeyFile *keyfile = e6x_pref_get_keyfile ();
  gchar *cmd = NULL;
  GtkWidget *dialog = NULL;
  GtkWidget *alignment = NULL;
  GtkWidget *area = NULL;
  GtkWidget *entry = NULL;
  GtkWidget *image = NULL;
  gint response = 0;
  
  g_return_if_fail (doc != NULL);
  
  dialog = gtk_message_dialog_new (win,
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_OTHER,
                                   GTK_BUTTONS_OK_CANCEL,
                                   _("Print"));
  
  image = gtk_image_new_from_stock (GTK_STOCK_PRINT, 
                                    GTK_ICON_SIZE_DIALOG);
  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            _("Enter print command:"));
  
  area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
  entry = gtk_entry_new ();
  gtk_entry_set_width_chars (GTK_ENTRY (entry), 10);
  alignment = gtk_alignment_new (0.9, 0.5, 0.5, 0.5);
  gtk_container_add (GTK_CONTAINER (alignment), entry);
  gtk_box_pack_start (GTK_BOX (area), 
                      alignment, FALSE, FALSE, 5);
  
  gtk_widget_show_all (area);
  
  cmd = g_key_file_get_string (keyfile, "Commands", "Print", NULL);
  if (cmd != NULL)
  {
    gtk_entry_set_text (GTK_ENTRY (entry), cmd);
    g_free (cmd);
  }
  
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response == GTK_RESPONSE_OK)
  {
    GError *error = NULL;
    const gchar *cmd = gtk_entry_get_text (GTK_ENTRY (entry));
    
    if (e6x_util_launch_cmd (cmd, doc->filename, &error) != FALSE)
      g_key_file_set_string (keyfile, "Commands", "Print", cmd);  
    
    if (error != NULL)
    {
      e6x_dialogs_show_error_message (win, error->message);
      g_clear_error (&error);
    }
  }

  gtk_widget_destroy (dialog);  
}


void
e6x_dialogs_properties (E6xDocument *doc,
                        GtkWindow *win)
{
  GtkWidget *dialog = NULL;
  
  g_return_if_fail (doc != NULL);
  
  dialog = e6x_properties_dialog_new (win, doc->info);
  gtk_dialog_run (GTK_DIALOG (dialog));
  
  gtk_widget_destroy (dialog);
}


static const gchar comments[] = N_("a PDF viewer");

static const gchar copyright[] = "Copyright \302\251 2010, 2011 Martin Linder";

static const gchar website[] = "http://electrix.sf.net";

static const gchar *authors[] = 
{
  "Martin Linder <mali2297@users.sf.net>", 
  NULL
};

static const gchar *license =
  "eLectrix 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.\n\n"
  "eLectrix 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.\n\n"
  "You should have received a copy of the GNU General Public License along "
  "with this program. If not, see \n"
  "<http://www.gnu.org/licenses/gpl-2.0.html>.";

void 
e6x_dialogs_about (GtkWindow *win)
{
  gtk_show_about_dialog (win,
                         "logo-icon-name", NULL,
                         "program-name", g_get_application_name (),
                         "version", VERSION,
                         "comments", _(comments),
                         "copyright", copyright,
                         "website", website,
                         "authors", authors,
                         "license", license,
                         "wrap-license", TRUE,
                         NULL);
}


void
e6x_dialogs_show_error_message (GtkWindow *win,
                                const gchar *message)
{
  GtkWidget *dialog = NULL;
  
  dialog = gtk_message_dialog_new (win,
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_ERROR,
                                   GTK_BUTTONS_CLOSE,
                                   _("Error"));
  g_signal_connect_swapped (dialog, "response",
                            G_CALLBACK (gtk_widget_destroy),
                            dialog);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            message);
  gtk_widget_show_all (dialog);
}


gchar *
e6x_dialogs_get_password (GtkWindow *win)
{
  gchar *passwd = NULL;
  GtkWidget *dialog = NULL;
  GtkWidget *alignment = NULL;
  GtkWidget *area = NULL;
  GtkWidget *entry = NULL;
  GtkWidget *image = NULL;
  gint response = 0;
  
  dialog = gtk_message_dialog_new (win,
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_OTHER,
                                   GTK_BUTTONS_OK_CANCEL,
                                   _("Password"));
  
  image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, 
                                    GTK_ICON_SIZE_DIALOG);
  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            _("Input password:"));  
  area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
  
  entry = gtk_entry_new ();
  gtk_entry_set_width_chars (GTK_ENTRY (entry), 10);
  gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
  alignment = gtk_alignment_new (0.9, 0.5, 0.5, 0.5);
  gtk_container_add (GTK_CONTAINER (alignment), entry);
  gtk_box_pack_start (GTK_BOX (area), 
                      alignment, FALSE, FALSE, 5);
  
  gtk_widget_show_all (area);
  
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response == GTK_RESPONSE_OK)
    passwd = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));

  gtk_widget_destroy (dialog);
  
  return passwd;
}


enum
{
  E6X_APP_COL_STRING,
  E6X_APP_COL_OBJECT,
  E6X_APP_NCOLS
};

void 
e6x_dialogs_open_with (const gchar *path, GtkWindow *win)
{
  gchar *content_type = NULL;
  gchar *string = NULL;
  GList *infolist = NULL;
  GList *l = NULL;
  GtkWidget *dialog = NULL;
  GtkWidget *image = NULL;
  GtkWidget *alignment = NULL;
  GtkWidget *area = NULL;
  GtkWidget *combobox = NULL;
  GtkWidget *checkbtn = NULL;
  GtkTreeModel *model = NULL;
  gint response = 0;
  
  model = GTK_TREE_MODEL (gtk_list_store_new (E6X_APP_NCOLS, 
                                              G_TYPE_STRING, 
                                              G_TYPE_OBJECT));
  
  content_type = e6x_util_get_content_type (path, NULL);
  if (content_type != NULL)
    infolist =  g_app_info_get_all_for_type (content_type);
    
  for (l = infolist; l != NULL; l = g_list_next (l))
  {
    GAppInfo *appinfo = G_APP_INFO (l->data);
    GtkTreeIter iter;

    gtk_list_store_append (GTK_LIST_STORE (model), &iter);
    gtk_list_store_set (GTK_LIST_STORE (model), &iter,
                        E6X_APP_COL_STRING, 
                        g_app_info_get_commandline (appinfo),
                        E6X_APP_COL_OBJECT, 
                        appinfo, 
                        -1);
  }
    
  dialog = gtk_message_dialog_new (win,
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_OTHER,
                                   GTK_BUTTONS_OK_CANCEL,
                                   _("Open with..."));
  
  image = gtk_image_new_from_stock (GTK_STOCK_OPEN, 
                                    GTK_ICON_SIZE_DIALOG);
  gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
  string = g_path_get_basename (path);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            _("Open %s with:"), 
                                            string);
  g_free (string);
   
  area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
  
  combobox = gtk_combo_box_entry_new_with_model (model, E6X_APP_COL_STRING);
  gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
  alignment = gtk_alignment_new (0.9, 0.5, 0.5, 0.5);
  gtk_container_add (GTK_CONTAINER (alignment), combobox);
  gtk_box_pack_start (GTK_BOX (area), 
                      alignment, FALSE, FALSE, 5);
  
  string = g_strdup_printf (_("Use as _default for files of type \"%s\""), 
                            content_type);
  checkbtn = gtk_check_button_new_with_mnemonic (string);
  alignment = gtk_alignment_new (1.0, 0.5, 0.5, 0.5);
  gtk_container_add (GTK_CONTAINER (alignment), checkbtn);
  gtk_box_pack_start (GTK_BOX (area), 
                      alignment, FALSE, FALSE, 5);
  g_free (string);
  
  gtk_widget_show_all (area);
  
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response == GTK_RESPONSE_OK)
  {
    GAppInfo *appinfo = NULL;
    GtkTreeIter iter;
    GError *error = NULL;
    
    if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &iter))
      gtk_tree_model_get (model, &iter, E6X_APP_COL_OBJECT, &appinfo, -1);
    else
    {
      gchar *cmd = NULL;
      
      cmd = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combobox));
      if (cmd != NULL)
      {
        appinfo = g_app_info_create_from_commandline (cmd, NULL, 0, &error);
        g_free (cmd);
      }
    }
  
    if (appinfo != NULL && error == NULL)
    {
      if (e6x_util_launch_app (appinfo, path, &error) &&
          gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbtn)))
        g_app_info_set_as_default_for_type (appinfo, content_type, &error);
      g_object_unref (appinfo);
    }
    
    if (error != NULL)
    {
      e6x_dialogs_show_error_message (win, error->message);
      g_clear_error (&error);
    }
  }

  gtk_widget_destroy (dialog);
  gtk_list_store_clear (GTK_LIST_STORE (model));
  g_object_unref (model);
  g_list_free_full (infolist, &g_object_unref);
  g_free (content_type);
}


