/* Program Name            : FILERSRT.C                                 */
/*   Original Author       : C. K. Hung					*/
/*   Date                  : 3-AUG-1990					*/
/*   Program Description   :                                            */
/*                         :                                            */
/* Revision History follows                                             */
 
#include "global.h"
#include "filerque.h"
#include "filer.h"
#include "filersrt.h"
#include "findfile.h"
#include <libdef.h>
 
/*
**  MACRO DEFINITIONS
**/
 
/*
**
**  EXTERNAL GLOBAL DECLARATIONS
**
**/
 
/*
**
**  INTERNAL FUNCTION PROTOTYPING
**
**/
 
static int		    filer_sort$2(enum sortbys, enum sortorders, char *);
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort_name()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error sorting files by name");
    get_userinput_and_execute(
	filer_sort$1,
	"Sort By Name",
	"By what? [ASCENDING or DESCENDING] ",
	"",
	errmsg,
	"Name");
     return DX__NORMAL;
}
 
 
/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort_type()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error sorting files by type");
    get_userinput_and_execute(
	filer_sort$1,
	"Sort By Type",
	"By what? [ASCENDING or DESCENDING] ",
	"",
	errmsg,
	"Type");
     return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort_date()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error sorting files by date");
    get_userinput_and_execute(
	filer_sort$1,
	"Sort By Date",
	"By what? [ASCENDING or DESCENDING] ",
	"",
	errmsg,
	"Date");
     return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort_size()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error sorting files by size");
    get_userinput_and_execute(
	filer_sort$1,
	"Sort By Size",
	"By what? [ASCENDING or DESCENDING] ",
	"",
	errmsg,
	"Size");
     return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort_mark()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error sorting files by marked");
    get_userinput_and_execute(
	filer_sort$1,
	"Sort By Marked",
	"By what? [ASCENDING or DESCENDING] ",
	"",
	errmsg,
	"Mark");
     return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_sort$1(criteria, sortby, errmsg)
char *criteria;
char *sortby;
char *errmsg;
{
    int len;
    int status;
 
    len = strlen(criteria);
    if (!strncmp("ASCENDING", criteria, len))
    {
	DX_CURRENT_DIRECTORY.sortorder = ascending;
    }
    else if (!strncmp("DESCENDING", criteria, len))
    {
	DX_CURRENT_DIRECTORY.sortorder = descending;
    }
    else
    {
	strcpy(errmsg, "Incorrect response, re-specify sorting order.");
	return DX__ERROR;
    }
 
    switch (sortby[0])
    {
	case 'N':
	    DX_CURRENT_DIRECTORY.sortby = sortname;
	    break;
	case 'T':
	    DX_CURRENT_DIRECTORY.sortby = sorttype;
	    break;
	case 'D':
	    switch (DX_CURRENT_DIRECTORY.cur_filter.date)
	    {
	    	 case DX_CREDATE:
		     DX_CURRENT_DIRECTORY.sortby = sortcredate;
		     break;
	    	 case DX_REVDATE:
		     DX_CURRENT_DIRECTORY.sortby = sortrevdate;
		     break;
	    	 case DX_EXPDATE:
		     DX_CURRENT_DIRECTORY.sortby = sortexpdate;
		     break;
	    	 case DX_BAKDATE:
		     DX_CURRENT_DIRECTORY.sortby = sortbakdate;
		     break;
		default:
		    strcpy(errmsg, "Invalid sort date key");
		    return DX__ERROR;
	    }
	    break;
	case 'S':
	    DX_CURRENT_DIRECTORY.sortby = sortsize;
	    break;
	case 'M':
	    DX_CURRENT_DIRECTORY.sortby = sortmark;
	    break;
	default:
	    strcpy(errmsg, "Invalid sort key");
	    return DX__ERROR;
    }
 
    return filer_sort$2(
		DX_CURRENT_DIRECTORY.sortby,
		DX_CURRENT_DIRECTORY.sortorder,
		errmsg);
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
static int	filer_sort$2(sortby, sortorder, errmsg)
enum sortbys sortby;
enum sortorders sortorder;
char *errmsg;
{
    struct fil_dx_tag *MARKER;
    struct fil_dx_tag *f, *g, *n;
    int indx;
    int allocate_size = sizeof (struct fil_dx_tag);
    int row, col;
 
    if ((MARKER = create_MARKER()) == (struct fil_dx_tag *)NULL)
    {
	strcpy(errmsg, "Insufficient virtual memory, SORT operation aborted");
	return DX__ERROR;
    }
 
    /*
    **  Reorder the list (directory filelist will not be changed)
    **/
    for (f = DX_CURRENT_DIRECTORY.non_dir_filelist->forward;
	 f != DX_CURRENT_DIRECTORY.non_dir_filelist; f = f->forward)
    {
	insert_filelist_entry(
		MARKER,
		*f,
		sortby,
		sortorder);
    }
 
    /*
    **	    Free up dynamic memory used
    **/
    free_filelist(&DX_CURRENT_DIRECTORY.non_dir_filelist);
 
    DX_CURRENT_DIRECTORY.non_dir_filelist = MARKER;
 
    /*
    **	Compute the position of each file
    **/
 
    DX_CURRENT_DIRECTORY.dir_filelist->beg_y =
	DX_CURRENT_DIRECTORY.dir_filelist->beg_x = 1;
    row = col = 1;
    compute_filer_begin_xy (
	DX_CURRENT_DIRECTORY.dir_filelist, &row, &col, cntrl_info_block.cur_win);
    DX_CURRENT_DIRECTORY.non_dir_filelist->beg_y =
	DX_CURRENT_DIRECTORY.dir_filelist->backward->beg_y;
    DX_CURRENT_DIRECTORY.non_dir_filelist->beg_x =
	DX_CURRENT_DIRECTORY.dir_filelist->backward->beg_x;
    compute_filer_begin_xy (
	DX_CURRENT_DIRECTORY.non_dir_filelist, &row, &col, cntrl_info_block.cur_win);
 
    /*
    **	Re-disply the screen
    **/
 
    check_OK(smg$unpaste_virtual_display (
	      &DX_CURRENT_DIRECTORY.filer_display.id,
	      &cntrl_info_block.pasteboard_id))
 
    check_OK(smg$erase_display (
	      &DX_CURRENT_DIRECTORY.filer_display.id,
	      0,
	      0,
	      0,
	      0))
 
    DX_CURRENT_DIRECTORY.filer_display.rows =
	max (DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y,
	     DX_CURRENT_DIRECTORY.filer_display.view_rows);
 
    check_OK(smg$change_virtual_display (
                 &DX_CURRENT_DIRECTORY.filer_display.id,
                 &DX_CURRENT_DIRECTORY.filer_display.rows,
                 &DX_CURRENT_DIRECTORY.filer_display.width,
                 0,
                 0,
                 0))
 
    DX_CURRENT_DIRECTORY.filer_display.view_beg_y = 1;
    DX_CURRENT_DIRECTORY.filer_display.view_beg_x = 1;
 
    check_OK(smg$change_viewport (
		&DX_CURRENT_DIRECTORY.filer_display.id,
		&DX_CURRENT_DIRECTORY.filer_display.view_beg_y,
		&DX_CURRENT_DIRECTORY.filer_display.view_beg_x,
		0,
		0))
 
    /*
    **	Set current file pointer.  Make sure at least one file exists
    **	in the directory file list
    **/
 
    DX_CURRENT_DIRECTORY.cur_file =
	(DX_CURRENT_DIRECTORY.dir_filelist->forward !=
	    DX_CURRENT_DIRECTORY.dir_filelist?
		DX_CURRENT_DIRECTORY.dir_filelist->forward :
		DX_CURRENT_DIRECTORY.non_dir_filelist->forward);
 
    /*
    **  Write all the files to screen
    **/
 
    write_to_filer(DX_CURRENT_DIRECTORY.dir_filelist);
    write_to_filer(DX_CURRENT_DIRECTORY.non_dir_filelist);
    highlight_filer_current_file();
 
    check_OK(smg$paste_virtual_display (
		&DX_CURRENT_DIRECTORY.filer_display.id,
		&cntrl_info_block.pasteboard_id,
		&DX_CURRENT_DIRECTORY.filer_display.beg_y,
		&DX_CURRENT_DIRECTORY.filer_display.beg_x,
		0))
 
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_dir(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    return (sortorder == ascending?
		strcmp(f->fn, g->fn) : strcmp(g->fn, f->fn));
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_name(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp;
 
    strcpy(s, f->fn);
    if ((cp = strchr(s, ';')) != NULL)
	*cp = EOS;
 
    strcpy(t, g->fn);
    if ((cp = strchr(t, ';')) != NULL)
	*cp = EOS;
 
    if ((cmp = strcmp(s, t)) != 0)
	return cmp;
 
    if (sortorder == ascending)
	return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
    else
	return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_type(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    char s[MAXVMSFILETYPE+1];
    char t[MAXVMSFILETYPE+1];
    char *cp;
    int cmp;
 
    strcpy(s, strchr(f->fn, '.')+1);
    if ((cp = strchr(s, ';')) != NULL)
	*cp = EOS;
 
    strcpy(t, strchr(g->fn, '.')+1);
    if ((cp = strchr(t, ';')) != NULL)
	*cp = EOS;
 
    if ((cmp = strcmp(s, t)) != 0)
	return cmp;
 
    strcpy(s, f->fn);
    cp = strchr(s, '.');
    *cp = EOS;
 
    strcpy(t, g->fn);
    cp = strchr(t, '.');
    *cp = EOS;
 
    if ((cmp = strcmp(s, t)) != 0)
	return cmp;
 
    if (sortorder == ascending)
	return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
    else
	return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
 
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_size(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp;
 
    if ((cmp = f->filesize - g->filesize) != 0)
	return cmp;
 
    /*
    **	    Both have the same file size, compare file name
    **/
    strcpy(s, f->fn);
    if ((cp = strchr(s, ';')) != NULL)
	*cp = EOS;
 
    strcpy(t, g->fn);
    if ((cp = strchr(t, ';')) != NULL)
	*cp = EOS;
 
    if ((cmp = strcmp(s, t)) != 0)
	return cmp;
 
    if (sortorder == ascending)
	return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
    else
	return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_credate(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    DATE_TIME cmp;
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp1;
 
    if (memcmp (&f->cdat, &g->cdat, sizeof (DATE_TIME)))
    {
	return (lib$sub_times(
		    &f->cdat,
		    &g->cdat,
		    &cmp) == LIB$_NEGTIM? -1 : 1);
    }
    else
    {
	/*
	**    Both have the same date, compare file name
	**/
	strcpy(s, f->fn);
	if ((cp = strchr(s, ';')) != NULL)
	    *cp = EOS;
 
	strcpy(t, g->fn);
	if ((cp = strchr(t, ';')) != NULL)
	    *cp = EOS;
 
	if ((cmp1 = strcmp(s, t)) != 0)
	    return cmp1;
 
	if (sortorder == ascending)
	    return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
	else
	    return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
    }
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_revdate(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    DATE_TIME cmp;
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp1;
 
    if (memcmp (&f->rdat, &g->rdat, sizeof (DATE_TIME)))
    {
	return (lib$sub_times(
		    &f->rdat,
		    &g->rdat,
		    &cmp) == LIB$_NEGTIM? -1 : 1);
    }
    else
    {
	/*
	**    Both have the same date, compare file name
	**/
	strcpy(s, f->fn);
	if ((cp = strchr(s, ';')) != NULL)
	    *cp = EOS;
 
	strcpy(t, g->fn);
	if ((cp = strchr(t, ';')) != NULL)
	    *cp = EOS;
 
	if ((cmp1 = strcmp(s, t)) != 0)
	    return cmp1;
 
	if (sortorder == ascending)
	    return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
	else
	    return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
    }
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_expdate(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    DATE_TIME cmp;
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp1;
 
    if (memcmp (&f->edat, &g->edat, sizeof (DATE_TIME)))
    {
	return (lib$sub_times(
		    &f->edat,
		    &g->edat,
		    &cmp) == LIB$_NEGTIM? -1 : 1);
    }
    else
    {
	/*
	**    Both have the same date, compare file name
	**/
	strcpy(s, f->fn);
	if ((cp = strchr(s, ';')) != NULL)
	    *cp = EOS;
 
	strcpy(t, g->fn);
	if ((cp = strchr(t, ';')) != NULL)
	    *cp = EOS;
 
	if ((cmp1 = strcmp(s, t)) != 0)
	    return cmp1;
 
	if (sortorder == ascending)
	    return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
	else
	    return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
    }
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_bakdate(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    DATE_TIME cmp;
    char s[MAXVMSFULLNAME+1];
    char t[MAXVMSFULLNAME+1];
    char *cp;
    int cmp1;
 
    if (memcmp (&f->bdat, &g->bdat, sizeof (DATE_TIME)))
    {
	return (lib$sub_times(
		    &f->bdat,
		    &g->bdat,
		    &cmp) == LIB$_NEGTIM? -1 : 1);
    }
    else
    {
	/*
	**    Both have the same date, compare file name
	**/
	strcpy(s, f->fn);
	if ((cp = strchr(s, ';')) != NULL)
	    *cp = EOS;
 
	strcpy(t, g->fn);
	if ((cp = strchr(t, ';')) != NULL)
	    *cp = EOS;
 
	if ((cmp1 = strcmp(s, t)) != 0)
	    return cmp1;
 
	if (sortorder == ascending)
	    return atoi(strchr(g->fn, ';')+1) - atoi(strchr(f->fn, ';')+1);
	else
	    return atoi(strchr(f->fn, ';')+1) - atoi(strchr(g->fn, ';')+1);
    }
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	sort_by_mark(f, g, sortorder)
struct fil_dx_tag *f;
struct fil_dx_tag *g;
enum sortorders sortorder;
{
    if (sortorder == ascending)
 
	if (f->state != ready)
	    return 1;
	else if (g->state == ready)
	    return 1;
	else
	    return DX__ERROR;
 
    else
 
	if (f->state == ready)
	    return DX__ERROR;
	else if (g->state != ready)
	    return DX__ERROR;
	else
	    return 1;
}
