static char rcsid[] = "@(#)$Id: a_sort.c,v 1.18 2006/04/09 07:37:17 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.18 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 * 			Copyright (c) 1988-1992 USENET Community Trust
 * 			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** Sort alias table by the field specified in the global
    variable "alias_sortby"...

**/

#include "def_elm.h"
#include "s_aliases.h"

DEBUG_VAR(Debug,__FILE__,"alias");

static void alias_old_current P_((long iindex, 
				  struct AliasView *aview));

static int compare_aliases P_((struct alias_rec *p1, struct alias_rec *p2));

static int s_compare_aliases P_((struct sort_data2 *s1,
				 struct sort_data2 *s2));
		       

static int s_compare_aliases(s1,s2)
     struct sort_data2 *s1;
     struct sort_data2 *s2;
{
    struct alias_rec *p1 = give_alias_s(s1); 
    struct alias_rec *p2 = give_alias_s(s2);

    return compare_aliases(p1,p2);
}

void sort_aliases(entries, visible, are_in_aliases, aview)
     int entries, visible, are_in_aliases;
     struct AliasView *aview;
{
    /** Sort the header_table definitions... If 'visible', then
	put the status lines etc **/
    
    long last_index = -1;
    int alias_current = get_alias_current(aview);

    
    DPRINT(Debug,2, (&Debug, "\n** sorting aliases by %s **\n\n", 
		     alias_sort_name(FULL)));
    
    /* Don't get last_index if no entries or no current. */
    /* There would be no current if we are sorting for the first time. */
    if (entries > 0 && alias_current > 0) {
	struct alias_rec *a  = give_alias(aview,alias_current-1);
	if (a)
	    last_index = a->length;
    }


    if ((entries > 30) && visible && are_in_aliases) {
	lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesSort,
			      "Sorting aliases by %s..."), 
		      alias_sort_name(FULL));
    }

    if (entries > 1)
	sort_aview(aview, s_compare_aliases);
  
    if (last_index > -1)
	alias_old_current(last_index,aview);
  
    if (are_in_aliases) {
	clear_error();
    }
}

static int compare_aliases(first, second)
     struct alias_rec *first, *second;
{
    /** compare two aliases according to the sortby value.
	
	Both are simple strcmp()'s on the alias or last_name
	components of the alias.
    **/
    
    int ret;
    long diff;

    
    /* If (only) one of the compares is a duplicate we want it
     * to go to the end of the list regardless of the sorting
     * method.
     */
    if ((first->type ^ second->type) & DUPLICATE) {
	if (first->type & DUPLICATE)
	    ret = 1;
	else			/* It must be second... */
	    ret = -1;
	return ret;
    }
    
    switch (abs(give_dt_sort_as_int(&alias_sortby))) {
    case ALIAS_SORT:
	ret = strcmp(first->alias, second->alias);
	break;
	
    case NAME_SORT:
	ret = strcmp(first->last_name, second->last_name);
	/*
	 * If equal on last name then compare on first name
	 * which is the first part of 'name'.
	 */
	if (ret == 0) {
	    ret = strcmp(first->name, second->name);
	}
	break;
	
    case TEXT_SORT:
	/* FIXME:    Is this still working??? */

	diff = (first - second);
	if ( diff < 0 )	ret = -1;
	else if ( diff > 0 ) ret = 1;
	else ret = 0;
	break;
	
    default:
	/* never get this! */
	ret = 0;
	break;
    }

    if (give_dt_sort_as_int(&alias_sortby) < 0)
	ret = -ret;
    
    return ret;
}

char *alias_sort_name(type)
     int type;
{
    /** return the name of the current sort option...
	type can be "FULL", "SHORT" or "PAD"
    **/
    int pad, abr;
	
    pad = (type == PAD);
    abr = (type == SHORT);
    
    if (give_dt_sort_as_int(&alias_sortby) < 0) {
	switch (- give_dt_sort_as_int(&alias_sortby)) {
	case ALIAS_SORT   : return(
				   pad?     "Reverse Alias Name      " :
				   abr?     "Reverse-Alias" :
				   "Reverse Alias Name");
	case NAME_SORT    : return(
				   pad?     "Reverse Full (Real) Name" :
				   abr?     "Reverse-Name" :
				   "Reverse Full (Real) Name");
	    case TEXT_SORT    : return(
				       pad?     "Reverse Text File       " :
				       abr?     "Reverse-Text" :
				       "Reverse Text File");
	}
    }
    else {
	switch (give_dt_sort_as_int(&alias_sortby)) {
	case ALIAS_SORT   : return(
				   pad?     "Alias Name              " :
				   abr?     "Alias" :
				       "Alias Name");
	case NAME_SORT    : return(
				   pad?     "Full (Real) Name        " :
				   abr?     "Name" :
				   "Full (Real) Name");
	case TEXT_SORT    : return(
				   pad?     "Text File               " :
				   abr?     "Text" :
				   "Text File");
	}
    }
    
    return("*UNKNOWN-SORT-PARAMETER*");
}

static void alias_old_current(iindex, aview)
     long iindex;
     struct AliasView *aview;
{
    /** Set current to the message that has "index" as it's 
	index number.  This is to track the current message
	when we resync... **/

    int i;
    int ac = get_alias_count(aview);
    
    DPRINT(Debug,4,
	   (&Debug, "alias-old-current(%ld)\n", iindex));
    
    for (i = 0; i < ac; i++) {
	struct alias_rec *a = give_alias(aview,i);

	if (a &&
	    a->length == iindex) {
	    set_alias_current(aview,i+1);
	    DPRINT(Debug,4,
		   (&Debug, "\tset current to %d!\n", i+1));
	    return;
	}
    }

    DPRINT(Debug,4,
	   (&Debug,
	    "\tcouldn't find current index.  Current left as %d\n",
	    get_alias_current(aview)));
    return;		/* can't be found.  Leave it alone, then */
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1