/* Program Name            : FILERDEL.C                                 */
/*   Original Author       : C. K. Hung					*/
/*   Date                  : 19-MAY-1991				*/
/*   Program Description   :                                            */
/*                         :                                            */
/* References                                                           */
/*   Files open for Input  :                                            */
/*   Files open for Output :                                            */
/*   Modules Referenced    :                                            */
/* Revision History follows                                             */
 
#include "global.h"
#include "directque.h"
#include "dx.h"
#include "filer.h"
#include "filerdel.h"
#include "filerenc.h"
#include "filerque.h"
#include "inquire.h"
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      tbs
**
**--
**/
int	filer_delete()
{
    if (DX_CURRENT_DIRECTORY.filemode == multiple)
	filer_multiple_delete();
    else
	filer_single_delete();
   return DX__NORMAL;
}
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_multiple_delete()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error deleting file");
    multi_get_userinput_and_exec(
	filer_delete$1,
	"Multiple Delete",
	"Are you sure? [YES/NO] ",
	"",
	errmsg);
   return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_single_delete()
{
    char errmsg[MAXFILESPEC+1];
    char fn[MAXFILESPEC+1];
 
    if (!strcmp(DX_CURRENT_FILE->fn, "[-]"))
    {
        signal_err("Delete a parent directory file not allowed", bell);
    }
    else
    {
	find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win);
	strcpy(errmsg, "Error deleting file");
	if (cntrl_info_block.user_pref.delete_confirm)
	{
	    get_userinput_and_execute(
		filer_delete$1,
		"Confirm Deletion",
		"Delete this file? [YES/NO] ",
		"YES",
		errmsg,
		fn);
	}
	else if (filer_delete$1("YES", fn, errmsg) == DX__ERROR)
	{
	    signal_err(errmsg, bell);
	}
    }
   return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_delete$1(confirm, fn, errmsg)
char *confirm;
char *fn;
char *errmsg;
{
    struct fil_dx_tag temp_entry;
    char *cp;
    int i;
 
    /*
    **	Verify that the user wants to continue with the
    **	deletion operation.  Return to calling
    **	routine if the user does not enter "YES".
    **/
 
    if (!strcmp(confirm, "NO") || !strcmp(confirm, "N"))
    {
	strcpy(errmsg, "DELETE canceled by request");
	return DX__DONTCARE;
    }
    else if (!strcmp(confirm, "YE") || !strcmp(confirm, "Y"))
    {
	strcpy(errmsg, "Abbreviation not allowed.  Please try again.");
	return DX__ERROR;
    }
    else if (strcmp(confirm, "YES"))
    {
	strcpy(errmsg, "Invalid input data");
	return DX__ERROR;
    }
 
    /*
    **	Make sure the file is not a directory file that is being
    **	used by the other window
    **/
 
    filestat(fn, &temp_entry, errmsg);
    if (strstr(temp_entry.fn, ".DIR;1"))
    {
	int i;
	struct filespec_list_tag *p;
	struct w_dids_tag *q;
 
 
	/**  Update other windows  **/
	for (i = 0;  i < cntrl_info_block.windows;  i++)
	{
	    if (i != cntrl_info_block.cur_win)
	    {
		for (p = cntrl_info_block.dir_dx[i].cur_filter.name_filespec_list;
		     p;  p = p->next)
		{
		    for (q = p->w_dids;  q;  q = q->next)
		    {
			if (q->did[0] == temp_entry.fid[0] &&
			    q->did[1] == temp_entry.fid[1] &&
			    q->did[2] == temp_entry.fid[2])
			{
			    strcpy(errmsg, "File in use by other window - deletion failed");
			    return DX__ERROR;
			}
		    }
		}
	    }
	}
    }
 
    if (remove(fn) != 0)
    {
	strcpy(errmsg, "Insufficient privilege for delete operation");
	return DX__ERROR;
    }
 
    /**  Delete it from the FILER  **/
    if (filer_delete$2(fn, errmsg, cntrl_info_block.cur_win) == DX__ERROR)
    {
        return DX__ERROR;
    }
 
    /**  Update other windows  **/
    for (i = 0;  i < cntrl_info_block.windows;  i++)
    {
        if (i != cntrl_info_block.cur_win)
        {
            if (filer_delete$2(fn, errmsg, i) == DX__ERROR)
            {
                 return DX__ERROR;
            }
        }
    }
 
    /*
    **  Update the cache queue.
    **	Must call it after filer_delete$2()
    **/
 
    update_filer_cache(temp_entry, delete_from_filer_cache, errmsg);
 
    /*
    **	Update the directory queue.
    **	Convert the file name to directory name.
    **/
 
    if (strlen(fn) > 6 && !strcmp(fn+strlen(fn)-6, ".DIR;1"))
    {
        cp = strchr (fn, ']');
	*cp = '.';
        cp = strrchr (fn, '.');
	*cp++ = ']';
	*cp = EOS;
        delete_from_direct_cache(fn, errmsg);
    }
 
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_delete$2(
		char *fn,
		char *errmsg,
		unsigned short int win)
{
    struct fil_dx_tag *MARKER;
    struct fil_dx_tag *f;
    int i;
    struct fil_dx_tag *p, *q;
    struct fil_dx_tag *newp;
    char buf[MAXFILESPEC+1];
    char str[MAXFILESPEC+1];
    $DESCRIPTOR (str_descrip, str);
 
    /*
    **	Find the file entry from the link-list
    **/
 
    for (p = cntrl_info_block.dir_dx[win].dir_filelist->forward;
	 p != cntrl_info_block.dir_dx[win].non_dir_filelist; p = p->forward)
    {
        if (p == cntrl_info_block.dir_dx[win].dir_filelist)
        {
            p = cntrl_info_block.dir_dx[win].non_dir_filelist;
        }
	else
	{
	    find_full_path_name(p->fn, buf, win);
	    if (!strcmp(buf, fn))
	    {
		break;
	    }
	}
    }
 
    if (p == cntrl_info_block.dir_dx[win].non_dir_filelist)
    {
        return DX__NORMAL;
    }
 
    if (p->state == ready)
    {	    /**  Update directory selection files and blocks  **/
	cntrl_info_block.dir_dx[win].sel_files--;
	cntrl_info_block.dir_dx[win].sel_blocks -= p->filesize;
    }
 
    cntrl_info_block.dir_dx[win].tot_files--;
    cntrl_info_block.dir_dx[win].tot_blocks -= p->filesize;
 
    /*
    **	Re-compute the position of the files that following
    **	the file being deleted
    **/
 
    recompute_filer_beg_xy(p->forward, p->beg_y, p->beg_x, win);
 
    cntrl_info_block.dir_dx[win].non_dir_filelist->beg_y =
	cntrl_info_block.dir_dx[win].dir_filelist->backward->beg_y;
    cntrl_info_block.dir_dx[win].non_dir_filelist->beg_x =
	cntrl_info_block.dir_dx[win].dir_filelist->backward->beg_x;
 
    if (p == cntrl_info_block.dir_dx[win].cur_file)
    {
	cntrl_info_block.dir_dx[win].cur_file = p->forward;
        if (cntrl_info_block.dir_dx[win].cur_file ==
		cntrl_info_block.dir_dx[win].dir_filelist)
        {
            if (cntrl_info_block.dir_dx[win].non_dir_filelist->forward !=
		cntrl_info_block.dir_dx[win].non_dir_filelist)
            {	    /**  At least one non-directory file presented  **/
                cntrl_info_block.dir_dx[win].cur_file =
		    cntrl_info_block.dir_dx[win].non_dir_filelist->forward;
            }
            else if (p->backward != cntrl_info_block.dir_dx[win].dir_filelist)
            {	    /**  At least one directory file still remaining  **/
                cntrl_info_block.dir_dx[win].cur_file = p->backward;
            }
	    else
	    {	    /**  No files in this directory  **/
		cntrl_info_block.dir_dx[win].cur_file =
		    cntrl_info_block.dir_dx[win].non_dir_filelist;
	    }
        }
        else if (cntrl_info_block.dir_dx[win].cur_file ==
		    cntrl_info_block.dir_dx[win].non_dir_filelist)
        {
            if (p->backward != cntrl_info_block.dir_dx[win].non_dir_filelist)
            {	    /**  At least one non_directory file still remaining  **/
                cntrl_info_block.dir_dx[win].cur_file = p->backward;
            }
            else if (cntrl_info_block.dir_dx[win].dir_filelist->backward !=
		cntrl_info_block.dir_dx[win].dir_filelist)
            {	    /**  At least one directory file presented  **/
                cntrl_info_block.dir_dx[win].cur_file =
		    cntrl_info_block.dir_dx[win].dir_filelist->backward;
            }
        }
    }
 
    /*
    **	Update the screen
    **/
 
    if (cntrl_info_block.dir_dx[win].form == long_form)
    {
        if (cntrl_info_block.dir_dx[win].non_dir_filelist->backward->beg_y <=
		cntrl_info_block.dir_dx[win].filer_display.view_rows ||
	    p->beg_y <=
		cntrl_info_block.dir_dx[win].non_dir_filelist->backward->beg_y)
        {
	    check_OK(smg$delete_line (
		      &cntrl_info_block.dir_dx[win].filer_display.id,
		      &p->beg_y,
		      &1))
        }
    }
    else
    {
	check_OK(smg$begin_display_update (
		     &cntrl_info_block.dir_dx[win].filer_display.id))
 
        check_OK(smg$erase_display (
                      &cntrl_info_block.dir_dx[win].filer_display.id,
                      &p->beg_y,
                      &p->beg_x,
                      &cntrl_info_block.dir_dx[win].filer_display.rows,
                      &cntrl_info_block.dir_dx[win].filer_display.width))
        for (q = p->forward;
	    q != cntrl_info_block.dir_dx[win].non_dir_filelist;
	    q = q->forward)
        {
            if (q == cntrl_info_block.dir_dx[win].dir_filelist)
            {
                q = cntrl_info_block.dir_dx[win].non_dir_filelist;
            }
            else
            {
                format_filer_entry(q, str, win);
		LENGTH(str_descrip) = strlen(str);
                if (q->fn[ strlen(q->fn)-1 ] == ']')
                {
		    check_OK(smg$put_chars (
				 &cntrl_info_block.dir_dx[win].filer_display.id,
				 &str_descrip,
				 &q->beg_y,
				 &q->beg_x,
				 0,
				 &SMG$M_BOLD,
				 0,
				 0))
                }
                else
                {
		    check_OK(smg$put_chars (
				 &cntrl_info_block.dir_dx[win].filer_display.id,
				 &str_descrip,
				 &q->beg_y,
				 &q->beg_x,
				 0,
				 0,
				 0,
				 0))
                }
            }
        }
	check_OK(smg$end_display_update (
		     &cntrl_info_block.dir_dx[win].filer_display.id))
    }
 
    remove_filelist_entry(&p);
 
    cntrl_info_block.dir_dx[win].filer_display.rows =
	max (cntrl_info_block.dir_dx[win].non_dir_filelist->backward->beg_y,
	     cntrl_info_block.dir_dx[win].filer_display.view_rows);
    if (cntrl_info_block.dir_dx[win].filer_display.rows <
	 cntrl_info_block.dir_dx[win].filer_display.view_rows)
    {
	cntrl_info_block.dir_dx[win].filer_display.rows =
	    cntrl_info_block.dir_dx[win].filer_display.view_rows;
    }
 
    if (cntrl_info_block.dir_dx[win].filer_display.view_beg_y +
	    cntrl_info_block.dir_dx[win].filer_display.view_rows - 1 >
	cntrl_info_block.dir_dx[win].filer_display.rows)
    {
	cntrl_info_block.dir_dx[win].filer_display.view_beg_y--;
	check_OK(smg$change_viewport (
		     &cntrl_info_block.dir_dx[win].filer_display.id,
		     &cntrl_info_block.dir_dx[win].filer_display.view_beg_y,
		     0,
		     0,
		     0))
    }
    check_OK(smg$change_virtual_display (
		 &cntrl_info_block.dir_dx[win].filer_display.id,
		 &cntrl_info_block.dir_dx[win].filer_display.rows,
		 &cntrl_info_block.dir_dx[win].filer_display.width,
		 0,
		 0,
		 0))
 
    put_filer_stat(win);
 
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	recompute_filer_beg_xy(
		struct fil_dx_tag *l,
		int row,int col,
		unsigned short int win)
{
    struct fil_dx_tag *p;
    int len;
 
    for (p = l; p != cntrl_info_block.dir_dx[win].non_dir_filelist; p = p->forward)
    {
        if (p == cntrl_info_block.dir_dx[win].dir_filelist)
        {
            p = cntrl_info_block.dir_dx[win].non_dir_filelist;
        }
	else if (cntrl_info_block.dir_dx[win].form == long_form)
	{
	    p->beg_y = row;
	    p->beg_x = col;
	    row++;
	}
	else
	{
	    len = strlen(p->fn);
	    if (len <= FILER_COLUMN_WIDTH-2)
	    {
		p->beg_y = row;
		p->beg_x = col;
		col += FILER_COLUMN_WIDTH;
	    }
	    else if (len <= 2*FILER_COLUMN_WIDTH-2)
	    {
		if (col > 2*FILER_COLUMN_WIDTH+1)
		{
		    row++;
		    col = 1;
		}
		p->beg_y = row;
		p->beg_x = col;
		col += 2*FILER_COLUMN_WIDTH;
	    }
	    else if (len <= 3*FILER_COLUMN_WIDTH-2)
	    {
		if (col > FILER_COLUMN_WIDTH+1)
		{
		    row++;
		    col = 1;
		}
		p->beg_y = row;
		p->beg_x = col;
		col += 3*FILER_COLUMN_WIDTH;
	    }
	    else
	    {
		if (col > 1)
		{
		    row++;
		    col = 1;
		}
		p->beg_y = row;
		p->beg_x = col;
		col += 4*FILER_COLUMN_WIDTH;
	    }
	    if (col > 4*FILER_COLUMN_WIDTH)
	    {
		row++;
		col = 1;
	    }
	}
    }
    return DX__NORMAL;
}
