/*********************************************************************
 *
 *            EZFM---EZWGL based file manager for X11
 *
 *             Copyright (C) 1998  Maorong Zou
 *
 *
 *  This file is part of EZFM.
 *
 *  EZFM 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, or (at your option)
 * any later version.
 *
 * EZFM 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 EZFM; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 *************************************************************************/




/***************************************************************************
 *
 *         Encoders/decoders registered to file items/icons.
 * 
 */
#define _DNDD_C_
#include "ezfm.h"

/****************************************************************************/

int ezfmEncodeFileName MY_ANSIARGS((void *obj, void *data, char **message_ret,
				    int *length_ret, int *needFree));
int ezfmEncodeFileContent MY_ANSIARGS((void *obj, void *data, char **message_ret,
				       int *length_ret, int *needFree));
int ezfmEncodeTaredFileContent MY_ANSIARGS((void *obj, void *data, char **message_ret,
					    int *length_ret, int *needFree));

int  ezfmEncodeFileInfo    MY_ANSIARGS((void *obj, void *data, char **message_ret,
					int *length_ret, int *needFree));

int ezfmMoveToDirByName MY_ANSIARGS((void *obj, void *data, char *message, int length));

int ezfmCopyToDirByName MY_ANSIARGS((void *obj, void *data, char *message, int length));
int ezfmCopyToDirByContent MY_ANSIARGS((void *obj, void *data, char *message, int length));
int ezfmCopyToDirByTar MY_ANSIARGS((void *obj, void *data, char *message, int length));

int ezfmLinkToDirByName MY_ANSIARGS((void *obj, void *data, char *message, int length));


int ezfmEncodeMultipleFileNames  MY_ANSIARGS((void *obj, void *data, char **message_ret,
                                              int *length_ret, int *needFree));

int ezfmMoveMultipleFilesD MY_ANSIARGS((void *obj, void *data, char *message, int length));
int ezfmCopyMultipleFilesD MY_ANSIARGS((void *obj, void *data, char *message, int length));
int ezfmLinkMultipleFilesD MY_ANSIARGS((void *obj, void *data, char *message, int length));

/***********************************************************************
 *
 *    The following are registered to all items.
 */

int ezfmEncodeFileName(obj, data, message_ret, length_ret, needFree)
     void *obj; void *data; char **message_ret;
     int *length_ret; int *needFree;
{
  FileInfo *finfo = (FileInfo *)data;
  return(finfoEncodeFileName(finfo, message_ret, length_ret, needFree));
}

int ezfmEncodeFileContent(obj, data, message_ret, length_ret, needFree)
     void *obj; void *data; char **message_ret;
     int *length_ret; int *needFree;
{
  FileInfo *finfo = (FileInfo *)data;
  return(finfoEncodeFileContent(finfo, message_ret, length_ret, needFree));
}

int ezfmEncodeTaredFileContent(obj, data, message_ret, length_ret, needFree)
     void *obj; void *data; char **message_ret;
     int *length_ret; int *needFree;
{
  FileInfo *finfo = (FileInfo *)data;
  return(finfoEncodeTaredFileContent(finfo, message_ret, length_ret, needFree));
}

/**************************************************************************
 *
 *    The following decoders are registered to all DIR items; DIR icons 
 *    and opened folders;
 */
int ezfmMoveToDirByName(obj,data,message,length)
     void *obj; void *data; char *message; int length;
{
  FileInfo *finfo = (FileInfo *)data;

  if(finfo)
    {
      char *destDir = finfo->pathname;
      return(moveToDirByName(destDir, message, length));
    }
  return(EZ_DND_FAILURE);
}

int ezfmCopyToDirByName(obj,data,message,length)
     void *obj; void *data; char *message; int length;
{
  FileInfo *finfo = (FileInfo *)data;

  if(finfo)
    {
      char *destDir = finfo->pathname;
      return(copyToDirByName(destDir, message, length));
    }
  return(EZ_DND_FAILURE);
}

int ezfmCopyToDirByContent(obj,data,message,length)
     void *obj; void *data; char *message; int length;
{
  FileInfo *finfo = (FileInfo *)data;

  if(finfo)
    {
      char *destDir = finfo->pathname;
      return(copyToDirByContent(destDir, message, length));
    }
  return(EZ_DND_FAILURE);      
}

int ezfmCopyToDirByTar(obj,data,message,length)
     void *obj; void *data; char *message; int length;
{
  FileInfo *finfo = (FileInfo *)data;

  if(finfo)
    {
      char *destDir = finfo->pathname;
      return(copyToDirByTar(destDir, message, length));
    }
  return(EZ_DND_FAILURE);      
}


int ezfmLinkToDirByName(obj,data,message,length)
     void *obj; void *data; char *message; int length;
{
  FileInfo *finfo = (FileInfo *)data;

  if(finfo)
    {
      char *destDir = finfo->pathname;
      return(linkToDirByName(destDir, message, length));
    }
  return(EZ_DND_FAILURE);
}


/**************************************************************************
 *
 *  encode fileInfo
 */
int ezfmEncodeFileInfo(obj, data, message_ret, length_ret, needFree)
     void *obj; void *data; char **message_ret;
     int *length_ret; int *needFree;
{
  FileInfo *finfo = (FileInfo *)data;
  return(finfoEncodeFileInfo(finfo, message_ret, length_ret, needFree));
}
/**************************************************************************
 *
 * DnD multiple files 
 */
int ezfmEncodeMultipleFileNames(obj, data, message_ret, length_ret, needFree)
     void *obj; void *data; char **message_ret; int *length_ret; int *needFree;
{
  Folder *folder = (Folder *)data;
  if(folder)
    {
      EZ_Widget *widget;
      EZ_Item   **items = NULL;
      char      *ptr, *msg;
      int i, length, bd, cnt = 0, type = folder->type; 

      switch(type)
        {
        case ICON_FOLDER:
          items = EZ_WorkAreaGetHighlightedItemsA(folder->workarea, &cnt);
          break;
        case ICON_FOLDER_SMALL:
          items = EZ_WorkAreaGetHighlightedItemsA(folder->workareaS, &cnt);
          break;
        case LIST_FOLDER:
          items =EZ_FancyListBoxGetHighlightedItemsA(folder->flistbox, &cnt);
          break;
	case TREE_FOLDER:
          items = EZ_ListTreeGetHighlightedItemsA(folder->listtree, &cnt);
          break;
        }
      if(items) 
        {
          struct stat   stat_buf;
          FileInfo      *firstFileInfo = EZ_GetItemPtrData(items[0]);
          if((stat(firstFileInfo->pathname, &stat_buf) >= 0))
            {
              bd = 128 * cnt + 1 + PATHNAME_OFFSET;
              msg = (char *)malloc(bd * sizeof(char));
              ptr=msg; length = 0;
              for(i = 0; i < cnt; i++)
                {
                  FileInfo *finfo = EZ_GetItemPtrData(items[i]);
                  int tlen = strlen(finfo->pathname);
                  if(i == 0)
                    {
                      finfoEncodeStatInfoAndPathname(finfo->pathname, &stat_buf, msg);
                      ptr = msg + PATHNAME_OFFSET;
                      length = PATHNAME_OFFSET;
                    }
                  if(length + tlen+1 >= bd)
                    {
                      bd += bd;
                      msg = (char *)realloc(msg, bd*sizeof(char));
                      ptr = msg + length;
                    }
                  strcpy(ptr, finfo->pathname);
                  ptr[tlen] = 0;
                  ptr += (tlen+1);
                  length += (tlen+1);
                }
              free(items);          
              *message_ret = msg;
              *length_ret = length;
              *needFree = 1;
              return(EZ_DND_SUCCESS);
            }
        }
    }
  return(EZ_DND_FAILURE);
}

/***********************************************************
 *
 * Message Type:  info-of-file1  file1 file2 ...
 */
#define   MF_CP "/bin/cp -rp  "
#define   MF_MV "/bin/mv -f   "
#define   MF_LN "/bin/ln -s   "
#define   MF_CML_LEN      13

static int doDnDMultipleFiles(obj, data, message, length, shcmd)
     void *obj; void *data; char *message; int length; char *shcmd;
{
  FileInfo *finfo = (FileInfo *)data;
  if(finfo)
    {
      char cmd[20480];
      char *q, *destDir = finfo->pathname;
      char *ptr = message + PATHNAME_OFFSET;
      int  len = PATHNAME_OFFSET;
      if(length > 20000 || canSeeTheFile(ptr, message) == 0)
        return(EZ_DND_FAILURE);

      strcpy(cmd, shcmd);
      q =cmd + MF_CML_LEN;
      
      *q++ = '\"';        /* " */
      while(len < length)
        {
          if(*ptr == 0)
            {
              *q++ = '\"';   /* " */
              if(len + 2 < length) { *q++ = ' '; *q++ = '\"';}   /* " */
            }
          else if(IS_SH_ESCAPE_C(*ptr)) { *q++ = '\\'; *q++ = *ptr;} 
          else *q++ = *ptr;
          ptr++;
          len++;
        }
      *q++ = ' '; *q++ = '\"'; /* " */
      ptr = destDir;
      while(*ptr)
        {
          if(IS_SH_ESCAPE_C(*ptr)) { *q++ = '\\'; *q++ = *ptr;} 
          else *q++ = *ptr;
          ptr++;
        }
      *q++ = '\"'; *q++ = 0;

      executeShCmd(cmd, NULL, 0, NULL);
      return(EZ_DND_SUCCESS);
    }
  return(EZ_DND_FAILURE);
}
   
int ezfmMoveMultipleFilesD(obj, data, message, length)
     void *obj; void *data; char *message; int length;
{
  return(doDnDMultipleFiles(obj, data, message, length, MF_MV));
}
int ezfmCopyMultipleFilesD(obj, data, message, length)
     void *obj; void *data; char *message; int length;
{
  return(doDnDMultipleFiles(obj, data, message, length, MF_CP));
}
int ezfmLinkMultipleFilesD(obj, data, message, length)
     void *obj; void *data; char *message; int length;
{
  return(doDnDMultipleFiles(obj, data, message, length, MF_LN));
}

/**************************************************************************/
#undef _DNDD_C_
