/*********************************************************************
 *
 *            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. 
 *
 *************************************************************************/




#define _TRASH_BTN_C_
#include "ezfm.h"

/**********************************************************************************/
void setupTrashButton MY_ANSIARGS((void *btn, void *data));
void move2Trashcan MY_ANSIARGS((char *pathname));
/**********************************************************************************/
static int targetStartFilter MY_ANSIARGS((void *obj, void *data, char *msg, int len));
static int decodeFileName   MY_ANSIARGS((void *obj, void *data, char *message, int length));
static void trashBtnCallback MY_ANSIARGS((void *widget, void *data));
static void trashEHandler MY_ANSIARGS ((EZ_Widget* widget,void *data, int etype, XEvent *xev));
/**********************************************************************************
 *
 * setup the trashcan button
 */
void setupTrashButton(widget, data)
     void *widget; void *data;
{
  EZ_Widget *ibtn = (EZ_Widget *)widget;
  EZ_Widget *frame = (EZ_Widget *)data; /* parent frame */
  Toplevel  *toplevel;
  if(frame && (toplevel = (Toplevel *)EZ_GetWidgetPtrData(frame)) != NULL)
    EZ_AddWidgetCallBack(ibtn, EZ_CALLBACK, trashBtnCallback, toplevel, 0);
  
  EZ_AddEventHandler(ibtn, trashEHandler, NULL, 0);
  EZ_WidgetAddDnDDataDecoder(ibtn, EZ_DND_DROP_START_ATOM, /* drop setup    */
			     0, targetStartFilter, NULL, NULL, NULL);
  EZ_WidgetAddDnDDataDecoder(ibtn, ezfmFileNameAtom, 0,
			     decodeFileName, NULL, NULL, NULL);
}
/***************************************************************************
 *
 * decode start filter.
 */
static int targetStartFilter(obj, data, msg, len)
     void *obj; void *data; char *msg; int len;
{
  Atom          *atomsInOut, theAtom = None;
  int           *natomsInOut;
  unsigned int  *atypeOut;
  int           i, j, answer;
  char          *src = msg + PATHNAME_OFFSET;

  EZ_DnDGetMatchedConversionTargets(&atomsInOut,&natomsInOut, &atypeOut);  

  if(canSeeTheFile(src, msg)) theAtom = ezfmFileNameAtom;
  for(j = 0, i = 0; i < *natomsInOut; i++)
    {
      Atom atom = atomsInOut[i]; 
      if(atom == theAtom) { atomsInOut[j++] = atom; break; }
    }
  *natomsInOut = j;
  return(0);
}

/***************************************************************************
 *
 * local file name
 */
static int decodeFileName(obj, data, message, length)
     void *obj; void *data; char *message; int length;
{
  if(length > PATHNAME_OFFSET)
    {
      char *pathname = message + PATHNAME_OFFSET;
      move2Trashcan(pathname);
      return(EZ_DND_SUCCESS);      
    }
  return(EZ_DND_FAILURE);
}
/*********************************************************************************
 *
 *    info button dialogue.
 */
static void trashBtnCallback(widget, data)
     EZ_Widget *widget; void *data;
{
  if(data)
    {
      Toplevel  *tp = (Toplevel *)data;
      Folder    **flds = tp->folder;
      EZ_Item   *item = NULL;

      item = getFolderSelection(flds[0]);
      if(item == NULL) item = getFolderSelection(flds[1]);

  /* display file info */
      if(item != NULL)
	{
	  FileInfo *p = (FileInfo *)EZ_GetItemPtrData(item);
	  if(p)
	    {
	      char info_str[512];
	      struct stat statbuf;
	      char *pathname = p->pathname;
	      move2Trashcan(pathname);
	    }
	}
      else ezfmWarning("Delete File", "You have to select a file first");
    }
}

/**************************************************************************/
void move2Trashcan(pathname)
     char *pathname;
{
  char command[1024];
  char trash[256], tfname[1024], *home = getenv("HOME");
  char timeStr[20];
  struct stat stat_buf;
  int status, err = 0;
  time_t ctm = time(NULL);
  struct tm *ltm = localtime(&ctm);
  strftime(timeStr, 15, "%Y%m%d%H%M", ltm);  

  sprintf(trash, "%s/%s", home, ".ezfmtrash");
  status = stat(trash, &stat_buf);
  if(status == 0 && !S_ISDIR(stat_buf.st_mode))
    {
      sprintf(command, "%s-%s", trash, timeStr);
      if(rename(trash, command) < 0) 
	err = 1;
      status = -1;
    }
  if(status != 0 && err == 0) /* mkdir */
    err = mkdir(trash, 0755);
  if(err == 0)
    {
      char *ptr, tmp[512], path[512];
      ptr = path;
      while(*pathname) 
        {
          if(*pathname == '"') { *ptr++ ='\\'; *ptr++='\"'; pathname++;} /* " */
          else *ptr++ = *pathname++;
        }
      *ptr = 0;
      strcpy(tmp, path);
      ptr = tmp; 
      while(*ptr) { if(*ptr == '/') *ptr = '-'; ptr++;}
      sprintf(tfname, "%s/%s%s", trash, timeStr, tmp);
      sprintf(command, MOVE_CMD, path, tfname);
      oneCommandDialogue("Delete", "Please Confirm", command, 'c',
			 NULL, 0, NULL );
    }
  else
    {
      char *err = (errno >= 0 && errno <sys_nerr)? 
	sys_errlist[errno] : "Unknown error";
      ezfmWarning("Error Deleting File", err);
    }
}
/**************************************************************************************/
static void openTrashcan(widget, data)
     EZ_Widget *widget; void *data;
{
  char trash[512], *home = getenv("HOME");
  sprintf(trash, "%s/%s", home, ".ezfmtrash");
  OpenFolder(trash, NULL, 1, 0);
}

static void emptyTrashcan(widget, data)
     EZ_Widget *widget; void *data;
{
  char cmd[1024], *home = getenv("HOME");
  sprintf(cmd, "/bin/rm -rf %s/%s", home, ".ezfmtrash");
  oneCommandDialogue("Empty Trashcan",  "Please confirm ...",   cmd, 'c',
		     NULL, 0, NULL);  
}

  
static void trashEHandler(widget, data, etype, xev)
     EZ_Widget *widget; void *data; int etype; XEvent *xev;
{
  if(xev->type == ButtonPress && xev->xbutton.button == EZ_Btn2)
    {
      EZ_Widget *menu = (EZ_Widget *)EZ_GetWidgetPtrData(widget);
      if(menu == NULL)
	{
	  menu = EZ_CreateSimpleMenu("Trashcan %t|%u0 Open %f|%u0 Empty trashcan %f", 
				     openTrashcan, NULL,
				     emptyTrashcan, NULL,
				     NULL);
	  EZ_SetWidgetPtrData(widget, menu);
	}
      EZ_DoPopupX(widget,menu, -1);
    }
}
/**************************************************************************************/
#undef _TRASH_BTN_C_


