/**
 * remove.c - code for removing nodes
 *
 *  Copyright 2011-2017 Andreas Rönnquist
 *
 * This file is part of SciteProj
 *
 * SciteProj 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 3 of the License, or
 * (at your option) any later version.
 *
 * SciteProj 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 SciteProj.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <string.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>

#include <locale.h>

#include "clicked_node.h"

#include "gui.h"

#include "tree_manipulation.h"

#include "remove.h"

#include "file_utils.h"

#include "prefs.h"


/**
 * delete_file
 * 	deletes a file (or directory) from the filesystem - directories needs to
 * be empty to be able to delete them.
 */
gboolean delete_file(gchar *filename,GError **error)
{
   gboolean result = FALSE;

   gchar *file_to_delete;

   if (g_file_test(filename, G_FILE_TEST_IS_DIR)) {
      file_to_delete = filename;

      // We have already checked if the folder is empty
   } else {

      if (!relative_path_to_abs_path(filename, &file_to_delete, get_project_directory(), error)) {
         result = FALSE;
         goto EXITPOINT;
      }
   }

   printf("%s\n", file_to_delete);
   result=TRUE;

EXITPOINT:
   return result;
}


/**
 *
 */
GList *get_list_of_selected_items_rows(GtkTreeView *treeview)
{
   GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
   GtkTreeModel *model;

   if (gtk_tree_selection_count_selected_rows(selection) == 0)
      return NULL;

   model = gtk_tree_view_get_model(treeview);

   GList *result_list = gtk_tree_selection_get_selected_rows(selection, &model);

   return result_list;
}


/**
 *
 */
GList *get_list_of_selected_items_string_list(GtkTreeView *treeview)
{
   GtkTreeModel *model = gtk_tree_view_get_model(treeview);
   GList *row_list = get_list_of_selected_items_rows(treeview);

   GList *string_list = NULL;

   // Begin at the end, and go to the start
   row_list = g_list_last(row_list);

   GtkTreeIter iter;

   while (row_list) {
      GtkTreePath *path = (GtkTreePath *)row_list->data;

      if (path) {

         gtk_tree_model_get_iter(model, &iter, path);

         gchar *path_string;

         gtk_tree_model_get(model, &iter, COLUMN_FILEPATH, &path_string, -1);

         string_list = g_list_prepend(string_list, path_string);
      }

      row_list = row_list -> prev;
   }

   g_list_foreach (row_list, (GFunc)gtk_tree_path_free, NULL);
   g_list_free (row_list);

   return string_list;
}


/**
 * get_list_of_selected_items_strings
 * 	Will only give the 7 first values, orelse it probably wouldn't fit in a
 *		dialog
 */
gchar *get_list_of_selected_items_strings(GtkTreeView *treeview)
{
   GtkTreeModel *model = gtk_tree_view_get_model(treeview);
   GList *list = get_list_of_selected_items_rows(treeview);

   // Begin at the end, and go to the start
   list = g_list_last(list);

   GtkTreeIter iter;

   gchar *result_string = g_strdup("\n\n");

   int count = 0;

   while (list) {
      GtkTreePath *path = (GtkTreePath *)list->data;

      if (path) {

         gtk_tree_model_get_iter(model, &iter, path);

         gchar *path_string;

         gtk_tree_model_get(model, &iter,
                            COLUMN_FILEPATH, &path_string, -1);

         if (count <7) {
            gchar *temp = g_strconcat(result_string, path_string, "\n", NULL);
            g_free(result_string);
            result_string=temp;

         } else if (count == 7) {
            gchar *temp = g_strconcat(result_string, "...\n", NULL);
            g_free(result_string);
            result_string=temp;
         }
         count++;

      }

      list = list -> prev;
   }

   g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
   g_list_free (list);

   return result_string;
}


/**
 *		Actually remove selected nodes
 */
void remove_selected_items ( GtkTreeView *treeview )
{
   GError *error = NULL;
   GtkTreeIter iter;
   GtkTreeModel *model = gtk_tree_view_get_model(treeview);
   GList *list = get_list_of_selected_items_rows(treeview); // gtk_tree_selection_get_selected_rows( selection, &model );

   // Begin at the end and go to the start

   list = g_list_last(list);
   while(list) {
      GString *fixed_path = g_string_new("");
      g_string_printf(fixed_path, "%s", gtk_tree_path_to_string((GtkTreePath*)list->data)/*ipath*/);

      GtkTreePath *path = gtk_tree_path_new_from_string(fixed_path->str);
      g_string_free(fixed_path, TRUE);

      if (path) {
         if ( gtk_tree_model_get_iter ( model, &iter, path) ) { // get iter from specified path

            remove_tree_node(&iter, &error);
         }
         else { // invalid path
            g_error(_("Error!!!\n"));
         }
         gtk_tree_path_free(path);
      }
      else {
         g_error(_("Error!!!\n"));
      }
      list = list->prev;
   }

   g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
   g_list_free (list);
}


/**
 *
 */
GtkWidget *do_question_dialog(const gchar *buffer)
{

   GtkWidget *dialog = gtk_message_dialog_new(NULL,
                       GTK_DIALOG_MODAL,
                       GTK_MESSAGE_QUESTION,
                       GTK_BUTTONS_OK_CANCEL,
                       "%s", buffer);
   return dialog;
}


/**
 *
 */
gboolean really_do_delete_question(const gchar *format, ...)
{
   GtkWidget *dialog;
   gint dialog_response;
   char buffer[256];
   gboolean result;

   va_list args;
   va_start(args, format);
   vsprintf(buffer, format, args);

   dialog = do_question_dialog(buffer);

   va_end(args);

   result = TRUE;

   dialog_response = gtk_dialog_run(GTK_DIALOG (dialog));
   if (dialog_response_is_exit(dialog_response)) {
      result = FALSE;
      goto EXITPOINT;
   }

   // Ask again to really make sure the user knows what he/she is doing.
   if (result) {

      gtk_widget_destroy(dialog);

      gchar *extended_question_string = g_strdup_printf(
                                            "Are you really really sure? \n"
                                            "This will actually delete the files\n"
                                            "from the filesystem.\n\n%s",buffer);

      dialog = do_question_dialog(extended_question_string);

      dialog_response=gtk_dialog_run(GTK_DIALOG(dialog));
      if (dialog_response_is_exit(dialog_response)) {
         result = FALSE;
         goto EXITPOINT;
      }
   }

EXITPOINT:

   gtk_widget_destroy(dialog);
   return result;
}


/**
 *
 */
void do_remove_node(gboolean ignore_clicked_node)
{
   GError *err = NULL;
   GtkWidget *dialog = NULL;
   gchar *nodename = NULL;

   gint selected_rows = 0;

   gboolean multiple_selected = FALSE;

   // Check if we are in "write-protect" mode

   if (prefs.write_protect) {

      dialog = gtk_message_dialog_new(NULL,
                                      GTK_DIALOG_MODAL,
                                      GTK_MESSAGE_INFO,
                                      GTK_BUTTONS_OK,
                                      "You are in write protected mode!\n\n"
                                      "You cannot delete anything when using sciteproj in this mode.\n"
                                      "To be able to delete files, either use your terminal, your\n"
                                      "file-manager of choice, or you can set the 'write_protect'\n"
                                      "variable in your sciteprojrc.lua to false.\n");

      gtk_dialog_run(GTK_DIALOG(dialog));

      gtk_widget_destroy(dialog);
      dialog = NULL;

      goto EXITPOINT;
   }

   // Make sure a node has been selected
   if (!ignore_clicked_node) {
      if (!clicked_node.valid) {
         goto EXITPOINT;
      }
   }

   GtkTreeSelection *tree_select;

   tree_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(projectTreeView));

   selected_rows = gtk_tree_selection_count_selected_rows(tree_select);
   if (selected_rows>1) {
      multiple_selected = TRUE;
   }

   if (!ignore_clicked_node) {
      // Figure out the node name
      nodename = strrchr(clicked_node.name, '/');

      if (nodename) {
         ++nodename;
      }
      else {
         nodename = clicked_node.name;
      }
   } else {
      // if there is only one selected, get its name
      nodename = NULL;
      multiple_selected = TRUE;
   }

   // Confirm removal from project

   if (multiple_selected) {

      gchar *file_list_string = get_list_of_selected_items_strings(GTK_TREE_VIEW(projectTreeView));

      gchar *question_string = g_strdup_printf("%s\n%s",_("Delete all selected items?"),file_list_string);

      if (really_do_delete_question(question_string)) {
         // remove them!

         GList *string_list = get_list_of_selected_items_string_list(GTK_TREE_VIEW(projectTreeView));

         while (string_list) {
            gchar *temp = (gchar *)string_list->data;

            if (!delete_file(temp, &err)) {
               goto EXITPOINT;
            }

            string_list = string_list->next;
         };

         remove_selected_items(GTK_TREE_VIEW(projectTreeView));
      }

      g_free(file_list_string);

      g_free(question_string);


   } else {

      gboolean really_do_delete = FALSE;

      if (clicked_node.type == ITEMTYPE_FILE) {
         if (nodename) {
            really_do_delete = really_do_delete_question(_("Delete file '%s'?"), nodename);

         } else {
            really_do_delete = really_do_delete_question(_("Delete file?"));
         }
      }
      else {

         // TODO: check if the folder is empty already here before "confirmation" questions

         gchar *filepath;

         GtkTreeModel *tree_model = gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView));

         gtk_tree_model_get(tree_model, &clicked_node.iter,
                            COLUMN_FILEPATH, &filepath, -1);

         if (get_number_of_files_in_folder(filepath) > 0) {

            dialog = gtk_message_dialog_new(NULL,
                                GTK_DIALOG_MODAL,
                                GTK_MESSAGE_INFO,
                                GTK_BUTTONS_OK,
                                "Folder need to be empty to be able to delete it!");
            gtk_dialog_run(GTK_DIALOG(dialog));

            gtk_widget_destroy(dialog);

            goto EXITPOINT;
         }


         if (nodename) {
            really_do_delete = really_do_delete_question(_("Delete folder '%s' and any contained files?"),nodename);

         } else {
            really_do_delete = really_do_delete_question(_("Delete folder and any contained files?"));
         }
      }

      if (!really_do_delete) {
         goto EXITPOINT;
      }

      // Delete the file

      gchar *filepath;

      GtkTreeModel *tree_model = gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView));

      gtk_tree_model_get(tree_model, &clicked_node.iter,
                         COLUMN_FILEPATH, &filepath, -1);

      if (!delete_file(filepath, &err)) {
         goto EXITPOINT;
      }

      // Remove the node

      if (!remove_tree_node(&(clicked_node.iter), &err)) {
         GtkWidget *errDialog = gtk_message_dialog_new(NULL,
                                GTK_DIALOG_MODAL,
                                GTK_MESSAGE_ERROR,
                                GTK_BUTTONS_OK,
                                _("Could not delete the selected node: \n\n%s"),
                                err->message);

         gtk_dialog_run(GTK_DIALOG (errDialog));

         gtk_widget_destroy(errDialog);
      }
   }

EXITPOINT:

   if (err) g_error_free(err);
   if (dialog) gtk_widget_destroy(dialog);
}



