/*---------------------------------------------------------------*/
/*   Copyright (c) 1992 Regents of the University of California  */
/*                 All Rights Reserved                           */
/*-------------------------- ------------------------------------*/
/*
      @(#)BufVarQSort.c	1.3  (UCLA, IGPP) 20 Apr 1994 
*/
/*---------------------------------------------------------------
  BufVarQSort(char* coulumn[])
  BufVarSort(colum1, column2, ..., NULL)
    Set Buffer with the first column named, and supplimental sorts
    on the other coulns given.  BufVarQSort take an array of columns
    terminaled by a NULL string. BufVarSort() is variable argumet
    and takes a list of columns.
 
  Return:
     
        
  Entry Requirements:
    NOne.
 
  Development History:
    Began: 09/17/93 - Gilbert Hyatt.
    Edited:04/14/94 - Gilbert Hyatt 
      Now uses pipec.h as entry point into the library.
  ---------------------------------------------------------------*/
#include <malloc.h>
#include "pipec.h"

#define  MAXARGS     100

char   *ColList[MAXARGS];
int    ColNumb[MAXARGS];
extern  BUFFER_HEAD  _Rbuffer;
extern  char         *Rbuffer;

double buffgetcolval();

/******************************** comrae needed by BufVarSort **************************/
compareQ(entry1, entry2)
RECPTR **entry1;
RECPTR **entry2;
{
  int         index;
  extern char *ColList[];
  extern DESC Desc[];
  double      value1, value2;
  extern char *Rbuffer;
  static int  test = 0;
  RECPTR      *ptr;

  
  int i,dnum;
 
  union pair {  
    int ival;
    float fval;
    double dval;
    char text[sizeof(double)];
  } pairs;
  test++;


  for (index = 0; ColList[index] != NULL; index++) { 
    if (! exists(ColList[index]) )      continue;
    if (coltype(ColList[index]) == 'A') continue;
    dnum = ColNumb[index] -1;
    if (*entry1 == NULL || *entry1 == _Rbuffer.end)  return(1);
    if (*entry2 == NULL || *entry2 == _Rbuffer.end)  return(-1);

    Rbuffer = BufMapData(*entry1);
    if (isflag(ColList[index])) return(1);
    value1 = buffgetcolval(Rbuffer, ColList[index]);

    Rbuffer = BufMapData(*entry2);
    if (isflag(ColList[index])) return(-1);  
    value2 = buffgetcolval(Rbuffer, ColList[index]);
			   
    if (value1 > value2) return(1);
    if (value1 < value2) return(-1);
  }  /* end of for */
  return(0);
}  /* end of compareQ */


/**************************************** BufVarSort *************************************/
BufVarQSort (columns) 
char *columns[];
{
  RECPTR  *last_next, *ptr, *ptr2, *ptr_old;
  RECPTR  **sortlist;
  int     index, nrecs;
  char    *TMP_Rbuffer;

  _Rbuffer.num_current = _Rbuffer.num_last_req = _Rbuffer.num_lastVMrec = BufNoValue;

  for (index = 0; columns[index] != NULL; index++) {
    ColList[index] = columns[index];
    ColNumb[index] = colnum(columns[index]);
  }

  if((sortlist = (RECPTR **) BufMalloc(sizeof(RECPTR*) * _Rbuffer.nrecs)) == NULL) return(FALSE);

  ptr = _Rbuffer.first;
  for (nrecs = 0; nrecs < _Rbuffer.nrecs; nrecs++) {
    sortlist[nrecs] = ptr;
    ptr = ptr->next;
  }  /* end of for */

  last_next = _Rbuffer.last->next;
  TMP_Rbuffer = Rbuffer;
  qsort((char *) sortlist, _Rbuffer.nrecs, (sizeof(RECPTR*)), compareQ);
  Rbuffer     = TMP_Rbuffer;
  _Rbuffer.first     = sortlist[0];
  _Rbuffer.end->next = sortlist[0];

  ptr = sortlist[0];
  for (nrecs = 1; nrecs < _Rbuffer.nrecs; nrecs++) {
    ptr->next = sortlist[nrecs];
    ptr       = ptr->next;
  }  /* end of for */
  _Rbuffer.last       = ptr;
  _Rbuffer.last->next = last_next;

  free(sortlist);
  return(TRUE);
}  /* end of BufVarSort() */


/**************************************** BufVarSort *************************************/
BufVarQSortSublist (start, stop, columns)
int   start;
int   stop;
char *columns[];
{
  RECPTR  *lastnext, *before, *last;
  int     index, nrecs;
  RECPTR  **sortlist, *ptr;
  char    *TMP_Rbuffer;

  if (start == stop) return(TRUE);
  if (start >  stop) return(FALSE);
  start = (start < 1)?1:start;
  stop  = (stop > _Rbuffer.nrecs)?_Rbuffer.nrecs:stop;
  nrecs = (stop - start +1);


  for (index = 0; columns[index] != NULL; index++) {
    ColList[index] = columns[index];
    ColNumb[index] = colnum(columns[index]);
  }

  if((sortlist = (RECPTR **) BufMalloc(sizeof(RECPTR*) * nrecs)) == NULL) return(FALSE);

  before = BufGetRecPtrOf((start -1));
  if (_Rbuffer.num_current   <= stop) _Rbuffer.num_current   = BufNoValue;
  if (_Rbuffer.num_last_req  <= stop) _Rbuffer.num_last_req  = BufNoValue;
  if (_Rbuffer.num_lastVMrec <= stop) _Rbuffer.num_lastVMrec = BufNoValue;

  ptr    = before;
  for (index = 0; index < nrecs; index++) {
    ptr = ptr->next;
    sortlist[index] = ptr;
  }  /* end of for */
  lastnext = ptr->next;

  TMP_Rbuffer = Rbuffer;
  qsort((char *) sortlist, nrecs, (sizeof(RECPTR*)), compareQ);
  Rbuffer     = TMP_Rbuffer;

  ptr = before;
  for (index = 0; index < nrecs; index++) {
    ptr           = ptr->next;
    ptr->data     = sortlist[index]->data;
    ptr->vmrecnum = sortlist[index]->vmrecnum;
  }

  if (start == 1)              _Rbuffer.first = before->next;
  if (stop  == _Rbuffer.nrecs) _Rbuffer.last  = ptr;

  return(TRUE);
}  /* end of BufVarQSortSublist() */
  
  
  


