// My File Manager (MFM).
//
// Copyright 2005-2006 by Stefano Gatti.
//
// 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
//=====================================================================

#include <time.h>
#include <locale.h>

#include <FL/Fl.H>

#include <FL/Fl_Menu_Button.H>

#include "mfm_util.hxx"
#include "mfm_main_table.hxx"
#include "mfm_main_ui.hxx"
#include "mfm_dir_ui.hxx"
#include "mfm_dnd.hxx"
#include "file_info.hxx"

int drag_source = 0;  
void *drag_source_ptr;

int drag_target = 0;
void *drag_target_ptr;

/**************************************************************************
*
* drag_source = 0 : no Drag & Drop procedure
* drag_source = 1 : drag from main browser window
* drag_source = 2 : drag from directory tree window, used button 3 (copy/move dirs)
* drag_source = 3 : drag from directory tree window, used button 2 (change path)
* drag_target = 0 : no Drag & Drop procedure
* drag_target = 1 : drop into main browser window
* drag_target = 2 : drop into directory tree window
*
****************************************************************************/

/**************************************************************************
*
* dnd_cb
*
* Drag and drop callback
*
****************************************************************************/

void dnd_cb() {

  char *command = NULL,
       *file_list = NULL,
			 *dest_path = NULL,
       *source_path = NULL,
			 *str_options,
			 *mod_dest_path = NULL;

	int dest_row, dest_col;
  
  int option = 0;

	bool point_dir = false; 
  
// Drop into main browser window
  
  if ((drag_source == 1 || drag_source == 2) && drag_target == 1) {
  
    dest_row = ((class_mfm_window *) drag_target_ptr)->mfm_window_table->get_pointed_row();       

    if (dest_row > -1) {

      char *name;

			file_info file_stat;

			dest_col = ((class_mfm_window *) drag_target_ptr)->col_name;

      name = convert_names(((class_mfm_window *) drag_target_ptr)->mfm_window_table->cell_label(dest_col, dest_row), false);

      file_stat.set_file(((class_mfm_window *) drag_target_ptr)->path, name);

      if (file_stat.is_dir()) {

        asprintf(&dest_path, "%s%s", ((class_mfm_window *) drag_target_ptr)->path, name);

				point_dir = true;

      }

      free(name);

    }

    if (Fl::event_ctrl())

      option = 5;

    else if (Fl::event_alt())

      option = 6;

		else {

      ((class_mfm_window *) drag_target_ptr)->popup->clear();

      ((class_mfm_window *) drag_target_ptr)->popup->menu(NULL);

      ((class_mfm_window *) drag_target_ptr)->popup->add("copy");
      ((class_mfm_window *) drag_target_ptr)->popup->add("move");
      ((class_mfm_window *) drag_target_ptr)->popup->add("soft link");
      ((class_mfm_window *) drag_target_ptr)->popup->add("hard link");

			if (point_dir) {

        ((class_mfm_window *) drag_target_ptr)->popup->add("copy in dir");
        ((class_mfm_window *) drag_target_ptr)->popup->add("move in dir");
        ((class_mfm_window *) drag_target_ptr)->popup->add("soft link in dir");
        ((class_mfm_window *) drag_target_ptr)->popup->add("hard link in dir");

      }

      ((class_mfm_window *) drag_target_ptr)->popup->position(Fl::event_x(), Fl::event_y());

      ((class_mfm_window *) drag_target_ptr)->popup->popup();

      option = ((class_mfm_window *) drag_target_ptr)->popup->value() + 1;
 
    }

  	if (option > 0 && option <= 4) {

			free(dest_path);

			dest_path = NULL;

			option += 4;

    }

		if (dest_path == NULL)

      asprintf(&dest_path, "%s", ((class_mfm_window *) drag_target_ptr)->path);

		mod_dest_path = convert_names(dest_path, true);

    free(dest_path);

  }

// Drop into directory tree window

  if ((drag_source == 1 || drag_source == 2) && drag_target == 2) {

    dest_path = ((class_mfm_dir *) drag_target_ptr)->mfm_dir_browser->get_dir(((class_mfm_dir *) drag_target_ptr)->mfm_dir_browser->get_pointed_row());

    if (Fl::event_ctrl())

      option = 5;

    else if (Fl::event_alt())

      option = 6;

		else {

      ((class_mfm_dir *) drag_target_ptr)->popup->clear();
      ((class_mfm_dir *) drag_target_ptr)->popup->menu(NULL);

      ((class_mfm_dir *) drag_target_ptr)->popup->add("copy");
      ((class_mfm_dir *) drag_target_ptr)->popup->add("move");
      ((class_mfm_dir *) drag_target_ptr)->popup->add("soft link");
      ((class_mfm_dir *) drag_target_ptr)->popup->add("hard link");

      ((class_mfm_dir *) drag_target_ptr)->popup->position(Fl::event_x(), Fl::event_y());

      ((class_mfm_dir *) drag_target_ptr)->popup->popup();

      option = ((class_mfm_dir *) drag_target_ptr)->popup->value() + 5;

    }

		mod_dest_path = convert_names(dest_path, true);

    free(dest_path);

  }

// Drag from main browser window

  if (drag_source == 1 && drag_target > 0) {

    if (((class_mfm_window *) drag_source_ptr)->mfm_window_table->get_selected_rows()
         && ((class_mfm_window *) drag_source_ptr)->path != NULL
         && ((class_mfm_window *) drag_source_ptr)->path[0] != '*') {

		  chdir(((class_mfm_window *) drag_source_ptr)->path);

 		  str_options = ((class_mfm_window *) drag_source_ptr)->str_options;

      if (option == 7)

   	    file_list = ((class_mfm_window *) drag_source_ptr)->get_list_file(true);

		  else

   	    file_list = ((class_mfm_window *) drag_source_ptr)->get_list_file(false);

		  switch (option) {

			  case 5:

          asprintf(&command, "mfmexec 'COPYING...' '%s' 'cp -r %s %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, str_options, file_list, mod_dest_path);

				  break;

			  case 6:

          asprintf(&command, "mfmexec 'MOVING...' '%s' 'mv %s %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, str_options, file_list, mod_dest_path);

				  break;

			  case 7:

// str_options causing failure during dnd linking:
//        asprintf(&command, "mfmexec 'soft link files' '%s' 'ln -s %s %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, str_options, file_list, mod_dest_path);
          asprintf(&command, "mfmexec 'SOFT LINKING...' '%s' 'ln -s -f -v %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, file_list, mod_dest_path);

				  break;

			  case 8:

// str_options causing failure during dnd linking:
//        asprintf(&command, "mfmexec 'hard link files' '%s' 'ln %s %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, str_options, file_list, mod_dest_path);
          asprintf(&command, "mfmexec 'HARD LINKING...' '%s' 'ln -f -v %s %s 2>&1' &", ((class_mfm_window *) drag_source_ptr)->path, file_list, mod_dest_path);

				  break;

      }

      free(mod_dest_path);

      free(file_list);

    }

  }

// Drag from directory tree window, used button 3 (copy/move dirs)

  if (drag_source == 2 && drag_target > 0) {

    if (((class_mfm_dir_browser *) drag_source_ptr)->value() > 0) {

      asprintf(&source_path, "%s", ((class_mfm_dir_browser *) drag_source_ptr)->get_dir(0));

      if (source_path[strlen(source_path)-1] == '/')

        source_path[strlen(source_path)-1] = 0;

		  chdir(source_path);

      if (((class_mfm_dir *) drag_target_ptr)->verbose && ((class_mfm_dir *) drag_target_ptr)->overwrite)

// Busybox does not recognize -b option, changed to -f (overwrite):
//      asprintf(&str_options, " -v -b ");
        asprintf(&str_options, " -v -f ");

      else if (((class_mfm_dir *) drag_target_ptr)->verbose && !((class_mfm_dir *) drag_target_ptr)->overwrite)

        asprintf(&str_options, " -v ");

      else if (!((class_mfm_dir *) drag_target_ptr)->verbose && ((class_mfm_dir *) drag_target_ptr)->overwrite)

// Busybox does not recognize -b option, changed to -f (overwrite):
//      asprintf(&str_options, " -b ");
        asprintf(&str_options, " -f ");


      else {

        str_options = (char *) malloc(1);

        str_options[0] = 0;

      }

		  switch (option) {

			  case 5:

          asprintf(&command, "mfmexec 'COPYING DIRECTORY...' '%s' 'cp -r %s %s %s 2>&1' &", source_path, str_options, source_path, mod_dest_path);

				  break;

			  case 6:

//        asprintf(&command, "mfmexec 'Moving directory...' '%s' 'mv %s %s %s 2>&1' &", source_path, str_options, source_path, mod_dest_path);
          asprintf(&command, "mfmexec 'MOVING DIRECTORY...' '%s' 'mv -n %s %s %s 2>&1' &", source_path, str_options, source_path, mod_dest_path);

				  break;

			  case 7:

// str_options causing failure during dnd linking:
//        asprintf(&command, "mfmexec 'soft link directory' '%s' 'ln -s %s %s %s 2>&1' &", source_path, str_options, source_path, mod_dest_path);
          asprintf(&command, "mfmexec 'SOFT LINKING DIRECTORY...' '%s' 'ln -s -f -v %s %s 2>&1' &", source_path, source_path, mod_dest_path);

				  break;

			  case 8:

// str_options causing failure during dnd linking:
//        asprintf(&command, "mfmexec 'hard link directory' '%s' 'ln %s %s %s 2>&1' &", source_path, str_options, source_path, mod_dest_path);
          asprintf(&command, "mfmexec 'HARD LINKING DIRECTORY...' '%s' 'ln -f -v %s %s 2>&1' &", source_path, source_path, mod_dest_path);

				  break;																		

      }											

      free(mod_dest_path);

      free(str_options);

    }

  }

// Drag_source = 3 : drag from directory tree window, used button 2 (change path)

  if (drag_source == 3 && drag_target == 1) {

    ((class_mfm_window *) drag_target_ptr)->set_dir(((class_mfm_dir_browser *) drag_source_ptr)->get_dir(0));
    ((class_mfm_window *) drag_target_ptr)->load_dir(false);

  }

// Execute command

  if (option >= 5) {

    system(command);

    free(command);

    start_timeout();

  }

  drag_source = 0;
  drag_target = 0;

} //dnd_cb
