/******************************************************************************
*
*  NSSDC/CDF						CDFlist.  Part 2 of 4.
*
*  Version 2.7, 12-Aug-96, Hughes STX.
*
*  Modification history:
*
*   V1.0  29-Jan-91, H Leckner	Original version (for CDF V2.0).
*   V1.1   5-Feb-91, J Love	Modified error handling.
*   V1.2  12-Feb-91, H Leckner	Fixed variable name handling.
*   V1.3  13-Mar-91, H Leckner	Fixed attribute entry problem.
*   V1.4  20-Mar-91, H Leckner	Fixed problem with large dimension sizes.
*   V1.5  26-Mar-91, J Love	Cast malloc calls to proper type.  Fix for
*				possible char array overwrite.
*   V1.6   4-Apr-91, H Leckner	Fixed problem with filtering REAL8 values.
*   V1.7   5-Jun-91, S Sudarsan Enhanced file/directory input handling
*                               along with file_names.c.  Changed logical
*				name for HELP directory.
*   V1.8  25-Jun-91, J Love	Added QOP.  Added CDF_EPOCH as a data type.
*		     H Leckner	Added #include <sys/types.h>.
*   V1.9  12-Jul-91, J Love	TRUE/FALSE.  Changed for Cray/UNICOS port.
*		     H Leckner	Added use of VALIDMIN/VALIDMAX for initial
*				filters (if NSSDC_STANDARD).  Use 'Exit' &
*				'ExitBAD'.
*   V1.10 20-Sep-91, H Leckner	Fixed window labeling.  Modified for IBM-PC
*		     J Love	port.
*   V1.11 11-Oct-91, H Leckner	Added ability to select more than 8
*				variables.
*   V2.0  13-May-92, H Leckner  Changed for IBM-RS6000 port.  IBM PC port.
*				CDF V2.2.
*   V2.1   9-Jun-92, H Leckner	Output file fix.  `Dump' option.
*   V2.2  21-Aug-92, H Leckner  CDF V2.3 (shareable/zVar/NeXT).
*		     J Love
*   V2.3   2-Dec-93, H Leckner  CDF V2.4.
*   V2.3a  4-Feb-94, J Love	DEC Alpha/OpenVMS port.
*   V2.4   5-Apr-94, H Leckner  Use CDF Hyper call for CDF output.
*   V2.4a  8-Sep-94, J Love	Solaris 2.3 & Macintosh port.
*   V2.5  12-Dec-94, J Love	CDF V2.5.
*   V2.5a  8-Feb-95, H Leckner  The last change, who cares, it won't work
*		     J Love	anyway.  Use `IsGraphChr'.
*   V2.6   4-Apr-95, J Love	POSIX.
*   V2.6a 17-Apr-95, J Love	More POSIX.
*   V2.6b  9-May-95, J Love	EPOCH styles.
*   V2.6c 13-Jun-95, J Love	Linux.
*   V2.6d 17-Jul-95, J Love	CDFexport-related changes.
*   V2.6e 18-Sep-95, J Love	Macintosh event handling.
*   V2.7  12-Aug-96, J Love	CDF V2.6.
*
******************************************************************************/

#define CDFLIST2
#include "cdflist.h"

/******************************************************************************
* DisplayRIP.
******************************************************************************/

static void DisplayRIP PROTOARGs((void));
static void DisplayRIP () {
  static char text[] = { "\
CDFlist has been replaced by CDFexport.  You should begin\n\
using CDFexport instead of CDFlist immediately.  CDFexport\n\
provides the same functionality as CDFlist in addition to\n\
some new features.  CDFlist is no longer being maintained\n\
and will eventually be removed from the CDF distribution.\n\
\n\
Enter any key to continue.\n" };
  static int exitKeys[] = { NUL };
  static struct EditWindowStruct EW = {
    " Attention! ", 7, 10, 60, 0, NULL, text, 7, 0, NULL,
    FALSE, TRUE, exitKeys, REFRESHkey_FSI, NUL, NUL, NUL, NUL, NUL, NUL,
    NUL, NUL, NUL
  };
  EditWindow (NEWew, &EW, TRUE);
  EditWindow (READew, &EW);
  EditWindow (DELETEew, &EW);
  return;
}

/*****************************************************************************/

Logical is_blank(str)
char	*str;
{
while(*str != '\0')
      if(*str++ != ' ')return(FALSE);
return(TRUE);
}
void get_field(row_data, col, max_len, value, first_blank, value_entered)
char		row_data[];
int		col;
int		max_len;
char		value[];
int		*first_blank;
int		*value_entered;
{
int		i;
int		done;
*first_blank = NOTTHERE;
*value_entered = FALSE;

if(strlen(row_data) == 0 || is_blank(row_data))
   {
   value[0] = '\0';
   return;
   }
done = FALSE;
for (i=col; i<col+max_len && !done; i++)
     {
     value[i-col] = row_data[i-1];
     if(row_data[i-1] != ' ')
	*value_entered = TRUE;
     else
	 {
	 if(*first_blank == NOTTHERE)*first_blank = i-col;
	 }
     if(row_data[i-1] == 0)done = TRUE;
     }

/*
if there was a value entered and it is the maximum length tell the program
that the first blank is the maximum length;
*/
if(value_entered && *first_blank == NOTTHERE)*first_blank = max_len;
value[max_len] = '\0';
}
void next_field(col_field, select_num, start_page, row, scroll, num_poss)
int		*col_field;
int		*select_num;
int		*start_page;
int		*row;
int		*scroll;
long int	num_poss;
{
if(*col_field > NUM_HORIZ_FIELDS)
   {
   *col_field = 1;
   (*select_num)++;
   if(*select_num > num_poss)*select_num = 1;
   (*row)++;
   if(*row > 9)
      {
      *row = 9;
      if(num_poss > 8)
	 {
	 (*start_page)++;
	 if(*start_page > num_poss)*start_page = 1;
	 *scroll = TRUE;
	 }
      }
   }
else if(*col_field < 1)
	{
	*col_field = NUM_HORIZ_FIELDS;
	(*select_num)--;
	if(*select_num < 1)*select_num = (int) num_poss;
	(*row)--;
	if(*row < 2)
	   {
	   *row = 2;
	   if(num_poss > 8)
	      {
	      (*start_page)--;
	      if(*start_page < 1)*start_page = (int) num_poss;
	      *scroll = TRUE;
	      }
	   }
	}
}
int	 check_var(display, var, num_poss)
struct vid_struct	display[];
char			var[];
long int		num_poss;
{
char		mnemonic[CDFLIST_MAX_VAR_LENGTH+1];
int		first_blank;
int		check_len;					/* V1.2 */
int		value_entered;
int		i;
int		elem;
for(i=1; i <= num_poss; i++)
    {
    elem = i * NUM_HORIZ_FIELDS;
/*
Copy Mnemonic
*/
     get_field(display[elem].label, 6, CDFLIST_MAX_VAR_LENGTH, mnemonic,
		&first_blank, &value_entered);
     check_len = strlen(var);					/* V1.2  */
     if(first_blank > check_len)check_len = first_blank;
     if(strncmp(var, mnemonic, check_len) == 0 && value_entered)
	return(DUPLICATE);
     }
return(OK_RESP);
}
void CDFLIST_special_keydef(screen)
struct			GLOBAL_struct	*screen;
{
AOSs2 (keydefs,
       "_____=Action  ____________=Up    ______=Select  ______=quit popup",
       "_____=Redraw  ____________=Down  Help=_____")

EncodeKeyDefinitions(2, keydefs,
	ACTIONkey_LIST, PREVITEMkey_LIST, SELECTkey_LIST, QUITkey_LIST, 
	REFRESHkey_FSI, NEXTITEMkey_LIST, ACTIONkey_LIST);
CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);

}
void CDFLIST_selectvar_keydef(screen, col_field)
struct	GLOBAL_struct	*screen;
int			col_field;
{
switch(col_field)
  { 
  case 1:
    {
    AOSs2 (keydefs,
"_____=Action ____________=Up   _____=Next Field ___/___= Out on/off ___=Delete",
"_____=Redraw ____________=Down _____=Back Field _____=Filter on/off Help=_____")
    EncodeKeyDefinitions(2, keydefs,
	ACTIONkey_LIST, PREVVARkey_LIST, NEXTFIELDkey_LIST, OUTPUTkey_LIST, NOOUTPUTkey_LIST, DELETEVARkey_LIST, 
	REFRESHkey_FSI, NEXTVARkey_LIST, PREVFIELDkey_LIST, FILTERTOGGLEkey_LIST, ACTIONkey_LIST);
        CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
    break;
    }
  case 2:
  case 3:
    {
    AOSs2 (keydefs,
	   "_____=Action  ____________=Up    ______=Next Field",
           "_____=Redraw  ____________=Down  ______=Back Field  Help=_____")
    EncodeKeyDefinitions(2, keydefs,
	ACTIONkey_LIST, PREVVARkey_LIST,  NEXTFIELDkey_LIST, 
	REFRESHkey_FSI, NEXTVARkey_LIST,  PREVFIELDkey_LIST, ACTIONkey_LIST);
    CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
    break;
    }
  case 4:
    {
    AOSs2 (keydefs,
     "_____=Action  ____________=Up    _____=Next Field  ___/___= Out on/off ",
     "_____=Redraw  ____________=Down  _____=Back Field  Help=_____")
    EncodeKeyDefinitions(2, keydefs,
	ACTIONkey_LIST, PREVVARkey_LIST, NEXTFIELDkey_LIST, OUTPUTkey_LIST, NOOUTPUTkey_LIST, 
	REFRESHkey_FSI, NEXTVARkey_LIST, PREVFIELDkey_LIST, ACTIONkey_LIST);
        CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
    }
  }
}
void CDFLIST_CDFname_keydef(screen)
struct GLOBAL_struct *screen;
{
AOSs2 (keydefs,
       "_____=Action  _____ = Move   to end-of-line   ______=Select",
       "_____=Redraw  _____ = Delete to end-of-line   HELP=_____   ")
EncodeKeyDefinitions(2, keydefs, ACTIONkey_LIST, EOLkey_LIST,   SELECTkey_LIST,
 	  	      	REFRESHkey_FSI, DELENDkey_LIST, ACTIONkey_LIST);
CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
}
void CDFLIST_help_keydef(screen)
struct			GLOBAL_struct	*screen;
{
AOSs2 (keydefs,
       "__________=Up    ______=page up    ______=Done",
       "__________=Down  ______=page down  _____ =Redraw")
EncodeKeyDefinitions(2, keydefs,
	PREVITEMkey_LIST, PAGEUPkey_LIST, SELECTkey_LIST, 
	NEXTITEMkey_LIST, PAGEDOWNkey_LIST, REFRESHkey_FSI);
CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
}
void CDFLIST_menu_keydef(screen)
struct			GLOBAL_struct	*screen;
{
/*
Load up keypad definitions for selecting a menu item
*/
AOSs2 (keydefs,
"_____=Action ____________=Up   _____=page up   ______=quit popup  HELP=_____",
"_____=Redraw ____________=Down _____=page down ______=Select")
EncodeKeyDefinitions(2, keydefs,
	ACTIONkey_LIST, PREVITEMkey_LIST, PAGEUPkey_LIST, QUITkey_LIST, ACTIONkey_LIST, 
	REFRESHkey_FSI, NEXTITEMkey_LIST, PAGEDOWNkey_LIST, SELECTkey_LIST);
CDFLIST_load_keydef(S.KEY_vid, keydefs[0], keydefs[1]);
}
void CDFLIST_load_discrete(values, num_values, col_field, DIS_display,
		   num_rows, paste_col)
char			values[];
long int		num_values;
int 			col_field;
struct vid_struct  	*DIS_display;
int			*num_rows;
int			*paste_col;
{
int			i;

for (i=0; i<num_values; i++)
     {
	DIS_display[i].row = 1;
	DIS_display[i].col = 1;
	strcpy(DIS_display[i].label,&values[i*MINMAX_SIZE]);
	DIS_display[i].field_col = 1;
     }
if(num_values > DIS_ROWS)
   *num_rows = DIS_ROWS;
else
   *num_rows = (int) num_values;

if(col_field == 3)
   *paste_col = DISMIN_COL_PASTE;
else
   *paste_col = DISMAX_COL_PASTE;
}
int CDFLIST_read_VAR(display, possible, num_vars, num_poss, select,
				num_select, filters)
struct vid_struct       display[];
struct VAR_struct		*possible;
long int		num_vars;
long int		num_poss;
struct VAR_struct		**select;
long int		*num_select;
int			*filters;
{
int			rcode;
int			i, j;
int			found;
int			len;
int			field_num;
double			min_max;
char			temp[CDF_VAR_NAME_LEN];
char			value[41];
int			first_blank, check_len;			/* V1.2 */
int			mnemonic_entered;
int			min_filter_entered;
int			max_filter_entered;
struct VAR_struct		*VN;
struct VAR_struct		*SN;
struct VAR_struct		*first = NULL;
rcode = 0;
*num_select = 0;
field_num = 0;
VN=possible;
for (j=1; j<=num_poss; j++)
    {
    field_num = field_num + NUM_HORIZ_FIELDS;
/*
EXTRACT the VARIABLE name
*/
    get_field(display[field_num].label+display[field_num].field_col-1, 1,
	      CDFLIST_MAX_VAR_LENGTH, value, &first_blank, &mnemonic_entered);
    if(mnemonic_entered)
       {
/*
VARIABLE NAME WAS ENTERED
*/
/*
LOOK in the array of possible variables for the column number
*/
       if((SN = (struct VAR_struct *) malloc (sizeof (struct VAR_struct))) == NULL)
	   return(BAD_MALLOC_READ_VAR);


       found = FALSE;
       for(i=0; i<num_vars && !found; i++)
	  {
	  VN = var_load(possible, i);
	  strcpy(temp, VN->var_mnemonic);
	  remove_trail(temp);
	  check_len = strlen(temp);		/* V1.2 */
	  if(first_blank > check_len ||
	     first_blank == CDFLIST_MAX_VAR_LENGTH)check_len = first_blank;
	  if((strncmp(temp, value, check_len) == 0) ||
	     (strcmp("**RECORD_NUM**", value) == 0))
	     {
	     memmove(SN, VN, sizeof(struct VAR_struct));
	     found = TRUE;
	     }
	  }

/*
RETRIEVE MINIMUM VALUES
*/
       if(SN->data_type != CDF_EPOCH)
	  len = MINMAX_SIZE;
       else
	  len = EPOCH_WIDTH;
       get_field(display[field_num+1].label,
		 display[field_num+1].field_col-display[field_num+1].col+1,
		 len,value,&first_blank, &min_filter_entered);
       if(min_filter_entered)
	  {
	  if(SN->data_type != CDF_EPOCH)
	     sscanf(value,"%lf",&min_max);
	  else
	     min_max = check_epoch(value);
	  SN->min = min_max;
	  }
/*
NOW RETRIEVE MAXIMUM VALUE
*/
       get_field(display[field_num+2].label,
		 display[field_num+2].field_col-display[field_num+2].col+1,
			len,value,&first_blank, &max_filter_entered);
       if(max_filter_entered)
	  {
	  if(SN->data_type != CDF_EPOCH)
	     sscanf(value,"%lf",&min_max);
	  else
	     min_max = check_epoch(value);
	  if(min_max != -1.0)SN->max = min_max;
	  }

       SN->out_select_num = (field_num-1)/NUM_HORIZ_FIELDS;
/*
Check to see if a filter was entered for this variable or
if only 1 value was entered
*/
	  if(min_filter_entered && !max_filter_entered)
		{
		SN->max = SN->min;
		SN->filter = MIN_ONLY;
		SN->restore = MIN_ONLY;
		}
	  else if(!min_filter_entered && max_filter_entered)
		{
		SN->min = SN->max;
		SN->filter = MAX_ONLY;
		SN->restore = MAX_ONLY;
		}
	  else if(!min_filter_entered && !max_filter_entered)
		{
/*		SN->min = SN->max;*/
		SN->filter = FALSE;
		SN->restore = FALSE;
		filters[SN->out_select_num] = FALSE;
		}
	  else
		{
		SN->filter = MIN_MAX;
		SN->restore = MIN_MAX;
		}
/*
DISPLAY current variable?
*/
       if(display[field_num+3].label[1] == 'Y')
	  SN->display = DISPLAY;
       else
	  SN->display = NONDISPLAY;
/*
Make sure the USER hasn't toggled the filter off for this variable
*/
       if(filters[SN->out_select_num] != FILTER_ON)
	  SN->filter = FALSE;
/*
If there was a filter entered see if the USER entered a
Minimum value  > Maximum value
*/

       if(SN->filter == MIN_MAX &&
	  SN->min > SN->max)
	  {
	  *num_select = 0;
	  rcode = MIN_GT_MAX;
	  free_vars(*select);
	  *select = NULL;
	  return(rcode);
	  }
       else
	  *num_select = *num_select + 1;

       SN->next_var = NULL;
       if(*select == NULL)
	  {
	  first = SN;
	  *select = SN;
	  }
       else
	  {
	  (*select)->next_var=SN;
	  *select = SN;
	  }
     }
  }
*select = first;
return(rcode);
}
int CDFLIST_filter(select, num_select, data_values, output)
struct VAR_struct		*select;
long int		num_select;
union mixed		data_values[];
int			output;
{
int			i;
double			value;
struct VAR_struct		*VN;
int			valid;
valid = TRUE;
VN = select;
for (i = 0; i < num_select && valid == TRUE; i++)
 {
 if(!VN->scalar && !VN->monoton)
     {
     switch(VN->data_type)
	       {
	       case CDF_REAL4:
	       case CDF_FLOAT:
		    value = (double) data_values[i].r4;
	       break;
	       case CDF_REAL8:
	       case CDF_DOUBLE:
	       case CDF_EPOCH:
		    value = data_values[i].r8;
	       break;
	       case CDF_INT4:
		    value = (double) data_values[i].i4;
	       break;
	       case CDF_UINT4:
		    value = (double) data_values[i].ui4;
	       break;
	       case CDF_INT2:
		    value = (double) data_values[i].i2;
	       break;
	       case CDF_UINT2:
		    value = (double) data_values[i].ui2;
	       break;
	       case CDF_BYTE:
	       case CDF_INT1:
		    value = (double) data_values[i].byte;
	       break;
	       case CDF_UINT1:
		    value = (double) data_values[i].ubyte;
	       }
/*
Now filter depending on what was entered by the USER
*/
     switch (VN->filter)
	       {
	       case MIN_MAX:
		    {
		    if(value < VN->filter_min ||
		       value > VN->filter_max)valid = FALSE;
		    break;
		    }
	       case MIN_ONLY:
		    {
		    if(value < VN->filter_min)valid = FALSE;
		    break;
		    }
	       case MAX_ONLY:
		    {
		    if(value > VN->filter_max)valid = FALSE;
		    break;
		    }
	       }
/*
Are we checking for the fill value
*/
	       if(SO.fill_values == CHECK_FILL)
		  {
 /*
 Yes, but make sure the value was out of range to begin with
 */
		  if(valid == FALSE)
		     {
 /*
 Was there a entry for value and was the current value a fill value
 */
		     if((VN->fillval) &&
			(value >= VN->fill_value_min &&
			 value <= VN->fill_value_max))
/*
The value was a fill value, keep this value is still valid
*/
			valid = TRUE;
		     }
		  }
/*
Possible whole in new output CDF, do not let a multi-dimensional variable
kill this set off values, fill it with the pad value
*/
	       if(output == CDFOUT && !valid && VN->multidim) {
		  memmove(&data_values[i], VN->pad_value, VN->bytes_value);
		  valid = TRUE;
		  }
     } /* not scalar */
     VN=VN->next_var;
  } /* end of var loop */
  return(valid);
}

CDFstatus CDFLIST_put_CDF(new_CDF, cnt, record_num, indices, select,
			num_select, data_values)
struct CDF_struct  	*new_CDF;
long int		cnt;
long int		record_num;
long int		*indices;
struct VAR_struct		*select;
long int		num_select;
union  mixed		data_values[];
{
int			i;
CDFstatus 		rcode;
struct VAR_struct		*VN;
/*
PUT VARIABLES INTO CDF
*/
VN=select;
for (i = 0; i < num_select; i++)
  {
  if(VN->var_num != RECORD_VAR_NUM) {
     rcode = put_CDF(new_CDF, cnt, record_num, indices, VN, &data_values[i]);
     if(rcode < CDF_WARN)return(rcode);
     }	
  VN=VN->next_var;
  }
return(rcode);
}
CDFstatus put_CDF(new_CDF, cnt, record_num, indices, VN, data_values)
struct CDF_struct  	*new_CDF;
long int		cnt;
long int		record_num;
long int		*indices;
struct VAR_struct		*VN;
union  mixed		*data_values;
{
CDFstatus 	rcode;
rcode = CDF_OK;
if(VN->rcode >= CDF_OK && VN->display == DISPLAY)
   {
   if(VN->multidim && SO.hyper_out) 
      memmove((Byte *) VN->data_array_out+((int) cnt-1)*VN->bytes_value, data_values,
		    VN->bytes_value);
   else if((VN->discrete && record_num == 0) ||
	   (VN->scalar && cnt == 1) ||
	   (!SO.hyper_out)) {
      if(VN->data_type == CDF_CHAR || VN->data_type == CDF_UCHAR)
         rcode = CDFlib (SELECT_, CDF_, NC.CDF_id,
		   BOO(VN->Z,zVAR_,rVAR_), VN->out_var_num,
		   BOO(VN->Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_),	record_num,
		   BOO(VN->Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_), indices,
	     PUT_, BOO(VN->Z,zVAR_DATA_,rVAR_DATA_), data_values->string,
		    NULL_);
      else
/*
PUT VARIABLES INTO CDF
*/
         rcode = CDFlib (SELECT_, CDF_, NC.CDF_id,
		   BOO(VN->Z,zVAR_,rVAR_), VN->out_var_num,
		   BOO(VN->Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_), record_num,
		   BOO(VN->Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_), indices,
	     PUT_, BOO(VN->Z,zVAR_DATA_,rVAR_DATA_), data_values,
		     NULL_);
      } /* !multidim */
   } /* Good rcode and display */
return(rcode);
}
CDFstatus CDFLIST_write_multidim_to_CDF(new_CDF, select, record_num)
struct CDF_struct  	*new_CDF;
struct VAR_struct		*select;
long int		record_num;
{
CDFstatus 		rcode;
struct VAR_struct		*VN;
/*
PUT VARIABLES INTO CDF
*/
VN=select;
while(VN != NULL)
  {
  if(VN->multidim) {
     rcode = write_multidim_to_CDF(new_CDF, VN, record_num);
     if(rcode < CDF_WARN)return(rcode);
  }
  VN=VN->next_var;
  }
return(rcode);
}
CDFstatus write_multidim_to_CDF(new_CDF, VN, record_num)
struct CDF_struct	*new_CDF;
struct VAR_struct		*VN;
long			record_num;
{
CDFstatus		rcode;
long recInterval = 1;
long recCount = 1;
static long intervals[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static long x[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
rcode = CDFlib (SELECT_, CDF_, NC.CDF_id,
		 BOO(VN->Z, zVAR_, rVAR_),  VN->out_var_num,
		 BOO(VN->Z, zVAR_RECNUMBER_,rVARs_RECNUMBER_),record_num,
		 BOO(VN->Z, zVAR_RECCOUNT_, rVARs_RECCOUNT_), recCount,
		 BOO(VN->Z, zVAR_RECINTERVAL_, rVARs_RECINTERVAL_),  recInterval,
		 BOO(VN->Z, zVAR_DIMINDICES_, rVARs_DIMINDICES_), x,
		 BOO(VN->Z, zVAR_DIMCOUNTS_, rVARs_DIMCOUNTS_), 
		 	SO.list_mode == ZMODE ? VN->act_dim_sizes : 
		 				NC.curr_group->dim_sizes,
		 BOO(VN->Z, zVAR_DIMINTERVALS_, rVARs_DIMINTERVALS_), intervals,
	PUT_,    BOO(VN->Z, zVAR_HYPERDATA_, rVAR_HYPERDATA_), VN->data_array_out,
		    NULL_);
return(rcode);
}

CDFstatus CDFLIST_get_discrete(CDF_id, Z, dim_num, var_id, data_type,
		num_values, bin_values, char_values)
CDFid			CDF_id;
int			Z;
int			dim_num;
long int		var_id;
long int		data_type;
long int		num_values;
double			bin_values[];
char			*char_values;
{
long int		indices[10];
char			temp_val[50];
int			i;
long int		record_num;
CDFstatus		rcode;
union 	mixed 		temp;

record_num = 0;
for (i=0; i < 10; i++)
     indices[i] = 0;
for (i=0; i < num_values; i++)
  {
  indices[dim_num-1]=i;
  rcode = CDFlib (SELECT_, CDF_, CDF_id,
			  BOO(Z,zVAR_,rVAR_), var_id,
			  BOO(Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_),
				record_num,
			  BOO(Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_),
				indices,
		 GET_, 	  BOO(Z,zVAR_DATA_,rVAR_DATA_),
				  &temp,
		 NULL_);
  if(rcode >= CDF_OK)
     {
     switch(data_type)

	{
	case CDF_REAL4:
	case CDF_FLOAT:
	     bin_values[i] = r4_r8(&temp.r4);
	     if(bin_values[i] < -1.e12 ||
		bin_values[i] >  1.e12)
		{
		if(num_values <= MAX_VALUES)sprintf(temp_val,"%e",bin_values[i]);
		}
	     else
		{
		if(num_values <= MAX_VALUES)sprintf(temp_val,"%f",bin_values[i]);
		}
	     break;
	case CDF_REAL8:
	case CDF_DOUBLE:
	case CDF_EPOCH:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%f",temp.r8);
	     bin_values[i] = temp.r8;
	     if(bin_values[i] < -1.e12 ||
		bin_values[i] >  1.e12)
		{
		if(num_values <= MAX_VALUES)sprintf(temp_val,"%e",bin_values[i]);
		}
	     else
		{
		if(num_values <= MAX_VALUES)sprintf(temp_val,"%f",bin_values[i]);
		}
	     break;
	case CDF_INT4:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%ld",temp.i4);
	     bin_values[i] = (double) temp.i4;
	     break;
	case CDF_UINT4:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%lu",temp.ui4);
	     bin_values[i] = (double) temp.ui4;
	     break;
	case CDF_INT2:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%d",temp.i2);
	     bin_values[i] = (double) temp.i2;
	     break;
	case CDF_UINT2:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%u",temp.ui2);
	     bin_values[i] = (double) temp.ui2;
	     break;
	case CDF_BYTE:
	case CDF_INT1:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%d",temp.byte);
	     bin_values[i] = (double) temp.byte;
	     break;
	case CDF_UINT1:
	     if(num_values <= MAX_VALUES)sprintf(temp_val,"%u",temp.ubyte);
	     bin_values[i] = (double) temp.ubyte;
	}
       if(num_values <= MAX_VALUES)
	  {
	  temp_val[MINMAX_SIZE-1] = '\0';
	  zero_replace(temp_val);
	  strcpy(&char_values[i*MINMAX_SIZE], temp_val);
	  }
     }
  }
return(rcode);
}
void CDFLIST_output(screen, CDF, out_file, field_num)
struct		GLOBAL_struct	*screen;
struct		CDF_struct	*CDF;
FILE		**out_file;
int		*field_num;
{
int		i, len;
int 		status;
int		ok;
int		termcode;
char		default_name[MAX_FILE_NAME_LEN+1];
char		display_name[MAX_FILE_NAME_DISPLAY_LEN+1];
char		mes[MES_COLUMNS+1];
/*AOSs1 (file_mes, "Enter File Name w/ NO EXTENSION or hit _____ for default ")*/
static char	file_mes[] = "Enter File Name w/ NO EXTENSION: ";
static char		CDF_mes[]  = "Enter CDF  Name w/ NO EXTENSION: ";
static char	file_close_mes[] =
"Error closing output file, possible disk quota problem";
static		char dot_lis[] = ".lis";
static		char file_error[] =
"Error opening output file, using output to TERMINAL";
static int	exit_keys[] = { SELECTkey_LIST, ACTIONkey_LIST, NUL };
/*EncodeKeyDefinitions(1, file_mes, SELECTkey_LIST);*/
CDFLIST_menu_keydef(screen);
CDFLIST_select_menu_item(S.OUT_vid, S.MES_vid, &C.output,
OUT_display, OUT_NUM_ELEMENTS, OUT_ROWS, OUT_COLUMNS, OUT_ROW_PASTE,
OUT_COL_PASTE, MENU, &termcode);
if(termcode != ACTIONkey_LIST && termcode != QUITkey_LIST)
   {
   CDFLIST_put_selection(S.CDF_vid, CDF_display, OUT_ELEMENT_NUM-1,
   OUT_display[C.output-1].label, OUT_COLUMNS, REVERSE);
   if(C.output != TERMIN)
      {
      if(C.output != CDFOUT)
	 strcpy(CDF_display[CDF_NUM_ELEMENTS-1].label, "File Name ");
      else
	 strcpy(CDF_display[CDF_NUM_ELEMENTS-1].label, "CDF  Name ");
      for(i=0; i < MAX_FILE_NAME_DISPLAY_LEN; i++)
	     display_name[i] = 32;
      if(C.output != CDFOUT)
	 CDFLIST_default_name(C.CDF_name, default_name);
     else
	 default_name[0] = '\0';
      mes[0] = '\0';
      if(C.output == CDFOUT)
	 strcpy(mes, CDF_mes);
      else
	 {
	 strcpy(mes, file_mes);
	 strcat(mes, default_name);
/*	 strcat(mes, dot_lis);*/
	 }
      CDFLIST_put_message(S.MES_vid, mes, NOBELL, NORMAL, NOPAUSE);
      strcpy(C.file_name, default_name);
      ok = FALSE;
      while(!ok)
	{
	input_field(S.MES_vid, C.file_name, OUT_NAME_ROW, OUT_NAME_COL,
	   OUT_NAME_LEN, exit_keys, &termcode, INSERTTOGGLEkey_LIST, 
	   SOLkey_LIST, EOLkey_LIST, NOTTHERE, DELENDkey_LIST, REFRESHkey_FSI);
	len = strlen(C.file_name);
	if(len > 0)
	   {
/*	   change_rendition(S.CDF_vid, OUT_NAME_ROW, OUT_NAME_COL, 1, len,
			REVERSE);*/
	   ok = TRUE;
	   }
	}
      CDFLIST_check_name(C.file_name);
      len = strlen(C.file_name);
      if(len > MAX_FILE_NAME_DISPLAY_LEN) {
	 strncpy(display_name, C.file_name, MAX_FILE_NAME_DISPLAY_LEN-3);
         display_name[MAX_FILE_NAME_DISPLAY_LEN-3] = '\0';
	 strcat(display_name, "...");
         }
      else 
         strcpy(display_name, C.file_name);
      load_vid_element(S.CDF_vid, CDF_display, CDF_NUM_ELEMENTS);
      CDFLIST_put_selection(S.CDF_vid, CDF_display, OUT_ELEMENT_NUM+1-1,
      display_name, MAX_FILE_NAME_DISPLAY_LEN, REVERSE); 
      if(C.output != CDFOUT)
	 {
	 strcat(C.file_name, dot_lis);
/*
OPEN THE FILE
*/
	 if(FILE_is_OPEN) /* Make sure there was not another file open */
	    {
	    status = fclose(*out_file);
	    if(status == EOF)
	       CDFLIST_put_message(S.MES_vid, file_close_mes, RINGBELL, NORMAL,
		PAUSE);
	    FILE_is_OPEN = FALSE;
	    }
	 *out_file = fopen(C.file_name, "w");
	  if(*out_file == NULL)
	     {
	     CDFLIST_put_message(S.MES_vid, file_error, RINGBELL, NORMAL,
				NOPAUSE);
	     C.output = TERMIN;
	     CDFLIST_put_selection(S.CDF_vid, CDF_display, OUT_ELEMENT_NUM-1,
	     OUT_display[C.output-1].label, 14, REVERSE);
	     }
	 else
	     FILE_is_OPEN = TRUE;
	 }
      }
      else
	{
	  begin_pasteboard_update();
	  erase_display(S.CDF_vid,
		CDF_display[CDF_NUM_ELEMENTS-1].row,
		CDF_display[CDF_NUM_ELEMENTS-1].col,
		CDF_display[CDF_NUM_ELEMENTS-1].row, CDF_COLUMNS);
	 end_pasteboard_update();
	}
      (*field_num)++;
   }
   else
      CDFLIST_field_menu(screen, CDF, field_num);
}

void CDFLIST_default_name(string, default_name)
char		string[];
char		default_name[];
{

#if defined(unix) || defined(posixSHELL)
/*
UNIX/POSIXshell check for slash to see if a directory name is part of the CDF
name
*/
if(strchr(string, '/') != NULL)
/*
Copy from last occurence of the slash to end of string to pick out just CDF name
*/
   strcpy(default_name, strrchr(string, '/')+1);
else
/*
No directory found in string
*/
   strcpy(default_name, string);
#endif

#if defined(vms)
/*
VMS first check for Right Bracket to see if a directory name
is part of the CDF name
*/
if(strchr(string, ']') != NULL)
   strcpy(default_name, strrchr(string, ']')+1);
/*
VMS No right bracket check for a logical name with a colen to see if a
directory name is part of the CDF name
*/
else if(strchr(string, ':') != NULL)
   strcpy(default_name, strrchr(string, ':')+1);
else
/*
No directory found in string
*/
   strcpy(default_name, string);
#endif

#if defined(dos)
if(strchr(string, '\\') != NULL)
   strcpy(default_name, strrchr(string, '\\')+1);
else if(strchr(string, ':') != NULL)
   strcpy(default_name, strrchr(string, ':')+1);
else
   strcpy(default_name, string);
#endif

#if defined(mac)
if (strchr(string,':') != NULL)
  strcpy (default_name, strrchr(string,':') + 1);
else
  strcpy (default_name, string);
#endif

/*
Default name will be 31 (MAX_FILE_NAME_LEN) characters or less to allow for 
output device specific extension
*/
if (strlen(default_name) > (size_t) MAX_FILE_NAME_LEN) 
    default_name[MAX_FILE_NAME_LEN] = '\0';
}

void CDFLIST_clear_row(vid, display, start_elem, end_elem, end_col)
WINDOWid 		vid;
struct	vid_struct	display[];
int			start_elem;
int			end_elem;
int			end_col;
{
int			i;

int			row, col;
for (i=start_elem; i<=end_elem; i++)
     {
     row = display[i-1].row;
     col = display[i-1].field_col;
     erase_display(vid, row, col, row, end_col);
     }
}
void CDFLIST_file_header(CDF, select, num_select, fptr)
struct	CDF_struct	*CDF;
struct  VAR_struct		*select;
long int		num_select;
FILE			*fptr;
{
int			i;
double			value;
char			string[30];
struct VAR_struct		*VN;
fprintf(fptr," CDF NAME = %s\n\n",C.CDF_name);
fprintf(fptr," VARIABLES AND SPECIFIED RANGES %38c Output\n",' ');
fprintf(fptr,
" ----------------------------------------------------------------------");
fprintf(fptr,"------\n");
VN=select;
for (i = 0; i < num_select; i++)
     {
     fprintf(fptr," %-19s ",VN->var_mnemonic);
       if(VN->filter)
	 {
	 if(VN->data_type == CDF_EPOCH)
	    {
	    char epString[EPOCH_STRING_LEN+1];
	    char epString1[EPOCH1_STRING_LEN+1];
	    if(VN->filter != MAX_ONLY)
	       {
	       if(SO.EPOCH_format == EPOCHFORM_DEF)
		  {
		  encodeEPOCH(VN->min, epString);
		  fprintf (fptr, " %s", epString);
		  }
	       else
		  {
		  encodeEPOCH1 (VN->min, epString1);
		  fprintf (fptr, " %s", epString1);
		  }
	       }
	    else if(SO.EPOCH_format == EPOCHFORM_DEF)
		    fprintf(fptr, " %*c",EPOCH_STRING_LEN, ' ');
	    else
		    fprintf(fptr, " %*c",EPOCH1_STRING_LEN,' ');
	    if(VN->filter != MIN_ONLY)
	       {
	       if(SO.EPOCH_format == EPOCHFORM_DEF)
		  {
		  encodeEPOCH (VN->max, epString);
		  fprintf (fptr, " %s", epString);
		  }
	       else
		  {
		  encodeEPOCH1 (VN->max, epString1);
		  fprintf (fptr, " %s", epString1);
		  }
	       }
	    else if(SO.EPOCH_format == EPOCHFORM_DEF)
		    fprintf(fptr, " %*c",EPOCH_STRING_LEN,' ');
	    else
		    fprintf(fptr, " %*c",EPOCH1_STRING_LEN,' ');

	    }
	 else
	    {
	    if(VN->filter != MAX_ONLY)
	       {
	       if(SO.variable_format == FORMAT && VN->format)
		  EncodeValueFormat(CDF_REAL8, &VN->min,
		       string, VN->format_value, 24, 24, EPOCH0_STYLE);
	       else
		  {
		  value = VN->min;
		  if(value < -1.e12 || value >  1.e12)
		    sprintf(string,"           %13.6e",value);
		  else
		    sprintf(string,"           %13.*f",precision(value),value);
		  }
	       fprintf(fptr, " %s",string);
	       }
	    else
	       fprintf(fptr, " %24c",' ');

	    if(VN->filter != MIN_ONLY)
	       {
	       if(SO.variable_format == FORMAT && VN->format)
		  EncodeValueFormat(CDF_REAL8, &VN->max,
				     string, VN->format_value, 24, 24,
				    EPOCH0_STYLE);
	       else
		  {
		  value = VN->max;
		  if(value < -1.e12 || value >  1.e12)
		     sprintf(string,"           %13.6e",value);
		  else
		     sprintf(string,"           %13.*f",precision(value),value);
		   }
	       fprintf(fptr, " %s",string);
	       }
	    else
	       fprintf(fptr, " %24c",' ');
	    }
       }
     else
	fprintf(fptr, " %49c",' ');
     if(VN->display == DISPLAY)
	fprintf(fptr, "  Y \n");
     else
	fprintf(fptr, "  N \n");
       VN=VN->next_var;
     }/* end of loop */

}
void CDFLIST_help(screen)
struct		GLOBAL_struct	*screen;
{
int	 		dummy=0;
struct vid_struct  	*HELP_display;
int			help_num_elements = 0;
int			i, len;
int			tcode;
AOSs1 (help_mes, "Press ______ key when done")
static char		help_error_mes[] = "Help not available ";
static char		help_error_mal[] = "Help not available, malloc error ";
char			temp[80];
int			help_rows, help_columns, paste_col;
int			max_len;
EncodeKeyDefinitions(1, help_mes, HELPDONEkey_LIST);
if(HELP_ptr != NULL)
   {
/*
READ text until complete and load into a vid structure
*/
   max_len = 0;
   fseek(HELP_ptr, 0l, SEEK_SET);
   while (fgets(temp,80,HELP_ptr) != NULL)
	  {
	  help_num_elements++;
	  len = lastc(temp);
	  if(len > max_len)max_len = len;
	  }
   if(help_num_elements > HELP_ROWS)
      help_rows = HELP_ROWS;
   else
      help_rows = help_num_elements;

   if(max_len > HELP_COLUMNS)
      help_columns = HELP_COLUMNS;
   else
      help_columns = max_len;

   paste_col = (80-(help_columns+BORDER_COLUMNS))/2;
   create_virtual_display(help_rows+BORDER_ROWS, help_columns+BORDER_COLUMNS,
		 &S.HELP_vid, BORDER, NORMAL);
   HELP_display = (struct vid_struct *)
		  malloc(help_num_elements * sizeof(struct vid_struct));
   if(HELP_display == NULL)
      {
      CDFLIST_put_message(S.MES_vid, help_error_mal, RINGBELL, NORMAL,
		NOPAUSE);
      return;
      }
   fseek(HELP_ptr, 0l, SEEK_SET);
   i=0;
   for(i=0; i <help_num_elements; i++)
	{
	fgets(temp,80,HELP_ptr);
	HELP_display[i].row = 1;
	HELP_display[i].col = 1;
	len = lastc(temp) - 1;
	strncpy(HELP_display[i].label,temp,len);
	HELP_display[i].label[len] = '\0';
	}
/*
LOAD in the keypad definitions for this option
*/
	CDFLIST_help_keydef(screen);
	CDFLIST_put_message(S.MES_vid, help_mes[0], NOBELL, NORMAL, NOPAUSE);
/*
Display the HELP screen
*/
	CDFLIST_select_menu_item(S.HELP_vid, S.MES_vid,
	&dummy, HELP_display, help_num_elements, help_rows, help_columns,
	HELP_ROW_PASTE, paste_col, HELP_MENU, &tcode);
	delete_virtual_display(S.HELP_vid);
	free(HELP_display);
   }
else
   CDFLIST_put_message(S.MES_vid, help_error_mes, RINGBELL, NORMAL, NOPAUSE);
}
int lastc(buf)
char	*buf;
{
int done = FALSE;
int i,j;
int end;
i = strlen(buf) + 1;
end = i;
j = 0;
while(j < end && !done)
      {
      if(!Visible(buf[i-1]))
	 done = TRUE;
      else
	 j++; i--;
      }
return(i);
}
void CDFLIST_field_menu(screen, CDF, option)
struct		GLOBAL_struct	*screen;
struct 		CDF_struct	*CDF;
int		*option;
{
int		cont;
int		tcode;
int		temp;
static char CDF_not_open_mes[] = 
"You must first open a CDF before selecting this option";
temp = *option+1;
cont = CONTINUEkey_LIST;
while(cont != DONE)
      {
/*
Choose the particular field you wish to be in
*/
      CDFLIST_menu_keydef(screen);
      CDFLIST_select_menu_item(S.FIELD_vid, S.MES_vid, &temp,
      FIELD_display, FIELD_NUM_ELEMENTS, FIELD_ROWS, FIELD_COLUMNS,
      FIELD_ROW_PASTE, FIELD_COL_PASTE, MENU, &tcode);
      *option = temp-1;
      if(*option == HELP_FIELD)
	 CDFLIST_help(screen);
      else if(*option == MONOTON_FIELD) {
	      if(C.CDF_id != NULL)
		 CDFLIST_specify_monoton(screen, CDF);	
	      else
	         CDFLIST_put_message(S.MES_vid, CDF_not_open_mes, RINGBELL, NORMAL,
					NOPAUSE);
	    }
      else if(*option >= INOPT_FIELD && *option <= LISTOPT_FIELD)
	      CDFLIST_special_options(screen, CDF->CDF_id, *option);
      else
	 cont = DONE;
       }
}
void CDFLIST_specify_monoton(screen, CDF)
struct	GLOBAL_struct	*screen;
struct  CDF_struct	*CDF;
{
struct  vid_struct	*SELECT_display;
struct  VAR_struct		*possible;
struct  VAR_struct		*VN;
long			num_vars;
int			var_rows;
int			var_columns;
int			var_num = 1;
int			tcode;
int			exit_code;
int			i,j;
static char		truncation[] = "...";
possible = CDF->curr_group->first_var;
num_vars = CDF->curr_group->num_vars;

CDFLIST_var_menus_monoton(screen, CDF, &var_rows, &var_columns);

SELECT_display = (struct vid_struct *)
   malloc((size_t) (num_vars*sizeof(struct vid_struct)));
if(SELECT_display == NULL)
   {
   exit_code = print_error(screen, BAD_MALLOC);
   if(exit_code == NOCONTINUE)ExitBAD;
   }

VN=possible;
for(i=0; i<num_vars; i++)
    {
    SELECT_display[i].row = i;
    SELECT_display[i].col = 1;
    SELECT_display[i].field_col = 1;
    for(j=0; j<var_columns; j++)SELECT_display[i].label[j] = ' ';
    if(i == 0) {
       strncpy(SELECT_display[i].label,"**RECORD_NUM**",14);
       strcpy(SELECT_display[i].label+var_columns-3," I ");
       VN=VN->next_var;
       }
    else {
       if(VN->var_mnemonic_len+6 < var_columns)
	   strncpy(SELECT_display[i].label, VN->var_mnemonic,
					   VN->var_mnemonic_len);
       else
	   {
	   strncpy(SELECT_display[i].label,VN->var_mnemonic,
		   var_columns-3);
	   strcat(SELECT_display[i].label,truncation);
	   }
       if(VN->scalar || VN->discrete) {
	  if(VN->monoton == INCREASE)
	     strcpy(SELECT_display[i].label+var_columns-3," I ");
	  else if(VN->monoton == DECREASE)
	     strcpy(SELECT_display[i].label+var_columns-3," D ");
	  else
	     strcpy(SELECT_display[i].label+var_columns-3," F ");
	  }
       else
	  strcpy(SELECT_display[i].label+var_columns-3,"N/A");
       VN=VN->next_var;
       }
    }
CDFLIST_menu_keydef(screen);
CDFLIST_select_menu_item(S.VAR_MONOTON_vid,
S.MES_vid, &var_num, SELECT_display, num_vars, var_rows,
var_columns, VARSELECT_ROW_PASTE, VARSELECT_COL_PASTE,
MONOTONIC, &tcode);
delete_virtual_display(S.VAR_MONOTON_vid);

for(i=0, VN=possible; i<num_vars; i++) {
    if(strcmp(SELECT_display[i].label+var_columns-3," I ") == 0)
       VN->monoton = INCREASE;
    else if(strcmp(SELECT_display[i].label+var_columns-3," D ") == 0)
       VN->monoton = DECREASE;
    else
       VN->monoton = FALSE;
    VN=VN->next_var;
    }
free(SELECT_display);
}
void CDFLIST_open_screen(screen)
struct	GLOBAL_struct	*screen;
{
create_pasteboard();
DisplayRIP();
begin_pasteboard_update();
create_virtual_display(CDF_ROWS+BORDER_ROWS, CDF_COLUMNS+BORDER_COLUMNS,
			&S.CDF_vid, BORDER, NORMAL);
paste_virtual_display(S.CDF_vid, CDF_ROW_PASTE, CDF_COL_PASTE);
load_vid(S.CDF_vid, CDF_display, 0, CDF_NUM_ELEMENTS-1, NO_label);
create_virtual_display(VAR_ROWS+BORDER_ROWS, VAR_COLUMNS+BORDER_COLUMNS,
			&S.VAR_vid, BORDER, NORMAL);
paste_virtual_display(S.VAR_vid, VAR_ROW_PASTE, VAR_COL_PASTE);
create_virtual_display(KEY_ROWS+BORDER_ROWS, KEY_COLUMNS+BORDER_COLUMNS,
			&S.KEY_vid, BORDER, NORMAL);
paste_virtual_display(S.KEY_vid, KEY_ROW_PASTE, KEY_COL_PASTE);
create_virtual_display(MES_ROWS+BORDER_ROWS, MES_COLUMNS+BORDER_COLUMNS,
			&S.MES_vid, BORDER, NORMAL);
paste_virtual_display(S.MES_vid, MES_ROW_PASTE, MES_COL_PASTE);
create_virtual_display(OUT_ROWS+BORDER_ROWS, OUT_COLUMNS+BORDER_COLUMNS,
			&S.OUT_vid, BORDER, NORMAL);
create_virtual_display(FIELD_ROWS+BORDER_ROWS, FIELD_COLUMNS+BORDER_COLUMNS,
			&S.FIELD_vid, BORDER, NORMAL);

create_virtual_display(SCREEN_ROWS,SCREEN_COLUMNS,&S.SCREEN_vid,NOBORDER,NORMAL);

create_virtual_display(SPECIAL_ROWS+BORDER_ROWS,SPECIAL_COLUMNS+BORDER_COLUMNS,
			&S.SPECIAL_vid, BORDER, NORMAL);
create_virtual_display(EPOCHFORMAT_ROWS+BORDER_ROWS,
		       EPOCHFORMAT_COLUMNS+BORDER_COLUMNS,
			&S.EPOCHFORMAT_vid, BORDER, NORMAL);
create_virtual_display(VARFORMAT_ROWS+BORDER_ROWS,
		       VARFORMAT_COLUMNS+BORDER_COLUMNS,
			&S.VARFORMAT_vid, BORDER, NORMAL);
create_virtual_display(FILTER_ROWS+BORDER_ROWS, FILTER_COLUMNS+BORDER_COLUMNS,
			 &S.FILTER_vid,	BORDER, NORMAL);
create_virtual_display(FILLVALUE_ROWS+BORDER_ROWS,
		       FILLVALUE_COLUMNS+BORDER_COLUMNS,
			&S.FILLVALUE_vid, BORDER, NORMAL);
create_virtual_display(ERASEVAR_ROWS+BORDER_ROWS,
		       ERASEVAR_COLUMNS+BORDER_COLUMNS,
			&S.ERASEVAR_vid, BORDER, NORMAL);
create_virtual_display(PRINTMODE_ROWS+BORDER_ROWS,
		       PRINTMODE_COLUMNS+BORDER_COLUMNS,
			&S.PRINTMODE_vid, BORDER, NORMAL);
create_virtual_display(FILEFORM_ROWS+BORDER_ROWS,
		       FILEFORM_COLUMNS+BORDER_COLUMNS,
			&S.FILEFORM_vid, BORDER, NORMAL);
create_virtual_display(ENCODING_ROWS+BORDER_ROWS,
		       ENCODING_COLUMNS+BORDER_COLUMNS,
			&S.ENCODING_vid, BORDER, NORMAL);
create_virtual_display(ZERO_ROWS+BORDER_ROWS,
		       ZERO_COLUMNS+BORDER_COLUMNS,
			&S.ZERO_vid, BORDER, NORMAL);
create_virtual_display(VARSELECT_ROWS+BORDER_ROWS,
		       VARSELECT_COLUMNS+BORDER_COLUMNS, &S.VARSELECT_vid,
			BORDER, NORMAL);
load_vid(S.VAR_vid, init_display, 0, VAR_NUM_ELEMENTS, VAR_label);
load_vid(S.KEY_vid, KEY_display, 0, KEY_NUM_ELEMENTS, KEY_label);
load_vid(S.MES_vid, MES_display, 0, MES_NUM_ELEMENTS, MES_label);
/*enable_trap(S.MES_vid);*/
end_pasteboard_update();

}
void CDFLIST_special_options(screen, CDF_id, menu_option)
struct	GLOBAL_struct	*screen;
CDFid			CDF_id;
int			menu_option;
{
char	*label;
begin_pasteboard_update();
paste_virtual_display(S.SPECIAL_vid, SPECIAL_ROW_PASTE, SPECIAL_COL_PASTE);
switch (menu_option)
	{
       case INOPT_FIELD:
	    label = INOPT_label;
	    break;
       case OUTOPT_FIELD:
	    label = OUTOPT_label;
	    break;
       case LISTOPT_FIELD:
	    label = LISTOPT_label;
	}
label_border(S.SPECIAL_vid, label, REVERSE);

switch(menu_option)
       {
       case INOPT_FIELD:
	    CDFLIST_input_options(screen);
	    break;
       case OUTOPT_FIELD:
	    CDFLIST_output_options(screen);
	    break;
       case LISTOPT_FIELD:
	    CDFLIST_listing_options(screen, CDF_id);
       }

unpaste_virtual_display(S.SPECIAL_vid);
CDFLIST_clear_row(S.MES_vid, MES_display, 1, 1, MES_COLUMNS);
end_pasteboard_update();

}
void CDFLIST_output_options(screen)
struct	GLOBAL_struct	*screen;
{
int 	tcode;
int	field_num;
static char star[]  = "*";
AOSs1 (FILEFORM_mes,
   "Single or Multi file format when creating a new CDF, ___ to quit window")
AOSs1A (ENCODING_mes,
"Host or Network encoding when creating a new CDF, ___ to quit window")

EncodeKeyDefinitions(1, FILEFORM_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, ENCODING_mes, QUITkey_LIST);

paste_virtual_display(S.FILEFORM_vid, FILEFORM_ROW_PASTE,
FILEFORM_COL_PASTE);
load_vid(S.FILEFORM_vid, FILEFORM_display, 0, FILEFORM_NUM_ELEMENTS,
	FILEFORM_label);
paste_virtual_display(S.ENCODING_vid, ENCODING_ROW_PASTE,
ENCODING_COL_PASTE);
load_vid(S.ENCODING_vid, ENCODING_display, 0, ENCODING_NUM_ELEMENTS,
	ENCODING_label);
end_pasteboard_update();

put_chars(S.FILEFORM_vid, star, 1, SO.file_form, 2, NOERASE, NORMAL);
put_chars(S.ENCODING_vid, star, 1, SO.encoding, 2, NOERASE, NORMAL);

CDFLIST_special_keydef(screen);
tcode = CONTINUEkey_LIST;
field_num = FILEFORM_FIELD;
while(tcode != QUITkey_LIST)
  {
  switch(field_num)
	 {
	 case FILEFORM_FIELD:
	      CDFLIST_put_message(S.MES_vid, FILEFORM_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.FILEFORM_vid,
			&SO.file_form, FILEFORM_NUM_ELEMENTS);
	      break;
	 case ENCODING_FIELD:
	      CDFLIST_put_message(S.MES_vid, ENCODING_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.ENCODING_vid,
			&SO.encoding, ENCODING_NUM_ELEMENTS);
	      break;
	 }
	 field_num++;
	 if(field_num > ENCODING_FIELD)
	    field_num = FILEFORM_FIELD;
   }

begin_pasteboard_update();
unpaste_virtual_display(S.FILEFORM_vid);
unpaste_virtual_display(S.ENCODING_vid);

}
void CDFLIST_input_options(screen)
struct	GLOBAL_struct	*screen;
{
int 	tcode;
int	field_num;
static char star[]  = "*";
AOSs1 (ERASEVAR_mes,
"Erase/Don't Erase selected variables before opening new CDF,___ to quit")

EncodeKeyDefinitions(1, ERASEVAR_mes, QUITkey_LIST);

paste_virtual_display(S.ERASEVAR_vid, ERASEVAR_ROW_PASTE,
ERASEVAR_COL_PASTE);
load_vid(S.ERASEVAR_vid, ERASEVAR_display, 0, ERASEVAR_NUM_ELEMENTS,
	ERASEVAR_label);
end_pasteboard_update();

put_chars(S.ERASEVAR_vid, star, 1, SO.erasevars, 2, NOERASE, NORMAL);

CDFLIST_special_keydef(screen);
tcode = CONTINUEkey_LIST;
field_num = ERASEVAR_FIELD;
while(tcode != QUITkey_LIST)
  {
  switch(field_num)
	 {
	 case ERASEVAR_FIELD:
	      CDFLIST_put_message(S.MES_vid, ERASEVAR_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.ERASEVAR_vid,
			&SO.erasevars, ERASEVAR_NUM_ELEMENTS);
	      break;
	 }

   }

begin_pasteboard_update();
unpaste_virtual_display(S.ERASEVAR_vid);

}
void CDFLIST_listing_options(screen, CDF_id)
struct	GLOBAL_struct	*screen;
CDFid			CDF_id;
{
int 	tcode;
int	field_num;
int	save;
static char star[]  = "*";
AOSs1 (EPFORM_mes,
"Select desired EPOCH display format, ___ to quit Special Option Window")
AOSs1A (VARFORM_mes,
"USE CDF FORMAT attribute to display data, ___ to quit Options Window")
AOSs1B (FILTER_mes,
"USE/IGNORE current filters?? ___ to leave Special Option Window")
AOSs1C (FILLVAL_mes,
"Display/non-display fill values(requires FILLVAL attribute), ___ to quit ")
AOSs1D (PRINTMODE_mes,
"Listing type for all data in record for variable (zMODE only), ___ to quit")
AOSs1E (ZERO_mes,
"CONVERT -0.0 to +0.0 or IGNORE -0.0, ___ to quit")
static char noformat_mes[] =
"This CDF does not a contain the attribute FORMAT, switching to default";
static char nofillval_mes[] =
"This CDF does not a contain the attribute FILLVAL, switching to default";
static char filter_fillval_mes[] =
"You have selected no filtering for this query, fill values will be displayed";

EncodeKeyDefinitions(1, EPFORM_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, VARFORM_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, FILTER_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, FILLVAL_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, PRINTMODE_mes, QUITkey_LIST);
EncodeKeyDefinitions(1, ZERO_mes, QUITkey_LIST);

paste_virtual_display(S.EPOCHFORMAT_vid, EPOCHFORMAT_ROW_PASTE,
		EPOCHFORMAT_COL_PASTE);
load_vid(S.EPOCHFORMAT_vid, EPOCHFORMAT_display, 0,
	EPOCHFORMAT_NUM_ELEMENTS, EPOCHFORMAT_label);
paste_virtual_display(S.VARFORMAT_vid, VARFORMAT_ROW_PASTE,
			VARFORMAT_COL_PASTE);
load_vid(S.VARFORMAT_vid, VARFORMAT_display, 0,
	VARFORMAT_NUM_ELEMENTS, VARFORMAT_label);
paste_virtual_display(S.FILTER_vid, FILTER_ROW_PASTE, FILTER_COL_PASTE);
load_vid(S.FILTER_vid, FILTER_display, 0, FILTER_NUM_ELEMENTS, FILTER_label);
paste_virtual_display(S.FILLVALUE_vid, FILLVALUE_ROW_PASTE,
FILLVALUE_COL_PASTE);
load_vid(S.FILLVALUE_vid, FILLVALUE_display, 0, FILLVALUE_NUM_ELEMENTS,
	FILLVALUE_label);
paste_virtual_display(S.PRINTMODE_vid, PRINTMODE_ROW_PASTE,
PRINTMODE_COL_PASTE);
load_vid(S.PRINTMODE_vid, PRINTMODE_display, 0, PRINTMODE_NUM_ELEMENTS,
	PRINTMODE_label);
paste_virtual_display(S.ZERO_vid, ZERO_ROW_PASTE, ZERO_COL_PASTE);
load_vid(S.ZERO_vid, ZERO_display, 0, ZERO_NUM_ELEMENTS,
	ZERO_label);
end_pasteboard_update();

put_chars(S.EPOCHFORMAT_vid, star, 1, SO.EPOCH_format, 2, NOERASE, NORMAL);
put_chars(S.VARFORMAT_vid, star, 1, SO.variable_format, 2, NOERASE, NORMAL);
put_chars(S.FILTER_vid, star, 1, SO.filters, 2, NOERASE, NORMAL);
put_chars(S.FILLVALUE_vid, star, 1, SO.fill_values, 2, NOERASE, NORMAL);
put_chars(S.PRINTMODE_vid, star, 1, SO.print_mode, 2, NOERASE, NORMAL);
put_chars(S.ZERO_vid, star, 1, SO.zero, 2, NOERASE, NORMAL);

CDFLIST_special_keydef(screen);
tcode = CONTINUEkey_LIST;
field_num = EPOCHFORMAT_FIELD;
while(tcode != QUITkey_LIST)
  {
  switch(field_num)
	 {
	 case EPOCHFORMAT_FIELD:
	      CDFLIST_put_message(S.MES_vid, EPFORM_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.EPOCHFORMAT_vid,
			&SO.EPOCH_format, EPOCHFORMAT_NUM_ELEMENTS);
	      break;
	 case VARFORMAT_FIELD:
	      CDFLIST_put_message(S.MES_vid, VARFORM_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.VARFORMAT_vid,
			&SO.variable_format, VARFORMAT_NUM_ELEMENTS);
	      if(!SO.format && SO.variable_format == FORMAT)
		 {
		 SO.variable_format = NOFORMAT;
		 CDFLIST_put_message(S.MES_vid, noformat_mes, RINGBELL, NORMAL,
					PAUSE);
		 CDFLIST_disp_opt(S.VARFORMAT_vid, SO.variable_format,
				VARFORMAT_NUM_ELEMENTS);
		 }
	      break;
	 case FILTER_FIELD:
	      CDFLIST_put_message(S.MES_vid, FILTER_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.FILTER_vid,
			&SO.filters, FILTER_NUM_ELEMENTS);
	      break;
	 case FILLVALUE_FIELD:
	      CDFLIST_put_message(S.MES_vid, FILLVAL_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.FILLVALUE_vid,
			&SO.fill_values, FILLVALUE_NUM_ELEMENTS);
	      if(!SO.fillval && SO.fill_values == CHECK_FILL)
		 {
		 SO.fill_values = NOCHECK_FILL;
		 CDFLIST_put_message(S.MES_vid, nofillval_mes, RINGBELL,
				NORMAL, PAUSE);
		 CDFLIST_disp_opt(S.FILLVALUE_vid, SO.fill_values,
				FILLVALUE_NUM_ELEMENTS);
		 }
	      else if(SO.fill_values == NOCHECK_FILL && SO.filters == NOFILTER)
		 CDFLIST_put_message(S.MES_vid, filter_fillval_mes, RINGBELL,
				NORMAL, PAUSE);

	      break;
	 case PRINTMODE_FIELD:
	      CDFLIST_put_message(S.MES_vid, PRINTMODE_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      tcode = CDFLIST_special_option_menu(S.PRINTMODE_vid,
			&SO.print_mode, PRINTMODE_NUM_ELEMENTS);
	      break;

	 case ZERO_FIELD:
	      CDFLIST_put_message(S.MES_vid, ZERO_mes[0], NOBELL, NORMAL,
					NOPAUSE);
	      save = SO.zero;
	      tcode = CDFLIST_special_option_menu(S.ZERO_vid,
			&SO.zero, ZERO_NUM_ELEMENTS);
	      if(SO.zero != save)NEG_to_POS(CDF_id);
	      break;

	 }
	 field_num++;
	 if(field_num > ZERO_FIELD)
	    field_num = EPOCHFORMAT_FIELD;
	 else if(field_num < EPOCHFORMAT_FIELD)
		 field_num = ZERO_FIELD;

   }

begin_pasteboard_update();
unpaste_virtual_display(S.FILLVALUE_vid);
unpaste_virtual_display(S.FILTER_vid);
unpaste_virtual_display(S.VARFORMAT_vid);
unpaste_virtual_display(S.EPOCHFORMAT_vid);
unpaste_virtual_display(S.PRINTMODE_vid);
unpaste_virtual_display(S.ZERO_vid);

}
int CDFLIST_special_option_menu(vid, value, num_rows)
WINDOWid	vid;
int		*value;
int		num_rows;
{
int		done;
int		row,col;
int		tcode;

done = FALSE;
row = *value;
col = 2;
while(!done)
  {
  set_cursor_abs(vid, row, col);
  read_input(
#if defined(CURSESui)
	     vid,
#endif
		 &tcode, PASSTHRUri, TRUE);
  switch(tcode)
	 {
	 case QUITkey_LIST:
	 case ACTIONkey_LIST:
	      tcode = QUITkey_LIST;
	      done = TRUE;
	      break;
	 case SELECTkey_LIST:
	      tcode = SELECTkey_LIST;
	      done = TRUE;
	      break;
	 case PREVITEMkey_LIST:
	      row--;
	      if(row < 1)row = num_rows;
	      break;
	 case NEXTITEMkey_LIST:
	      row++;
	      if(row > num_rows)row = 1;
	      break;
	 case REFRESHkey_FSI:
	      repaint_screen();
	      break;
	  }
  CDFLIST_disp_opt(vid, row, num_rows);
  }

*value = row;
return(tcode);
}
void CDFLIST_disp_opt(vid, row, num_rows)
WINDOWid	vid;
int		row;
int		num_rows;
{
int		i;
static char star[]  = "*";
static char blank[] = " ";

for(i=1; i<=num_rows;i++)
      {
      if(i == row)
	 put_chars(vid, star, 1, i, 2, NOERASE, NORMAL);
      else
	 put_chars(vid, blank, 1, i, 2, NOERASE, NORMAL);
      }
}

void CDFLIST_select_menu_item(vid, MES_vid, rvalue, display,
num_elements, num_rows, num_columns, row_start, col_start, mode, termcode)
WINDOWid	vid;
WINDOWid	MES_vid;
int		*rvalue;
struct		vid_struct	display[];
long int	num_elements;
int		num_rows;
int		num_columns;
int		row_start;
int		col_start;
int		mode;
int		*termcode;
{
int		in_value;
int		row, col;
int		tcode;
int		done;
int		num_screen;
int		start_page;
int		end;
int		value;
char		mon_str[4];
int		row1 = 1;
int		col1 = 1;
static char	top[]    = "Top of menu";
static char	bottom[] = "Bottom of menu";
static char	illegal_monotonic_mes[] = 
"This variable is not eligible to be specified Monotonic";
static char     record_monotonic_mes[]="The Record Number is always Monotonic";
AOSs1 (monotonic_mes,
"Enter ___ if variable values increase, ___ decrease, or ___ non-monotonic")
EncodeKeyDefinitions(1, monotonic_mes, MONOTONINCkey_LIST,
				       MONOTONDECkey_LIST,
				       MONOTONFALSEkey_LIST);
in_value = *rvalue;
/*
Find out the number of rows to be on the screen at one time
*/
if(num_elements > num_rows)
   num_screen = num_rows;
else
   num_screen = (int) num_elements;
/*
Erase and load data into the menu for selection
*/
value = 1;
row = 1;
col = mode == MONOTONIC ? num_columns-1 : 1;

paste_virtual_display(vid, row_start, col_start);
begin_pasteboard_update();
erase_display(vid, 1, 1, num_rows, num_columns);
load_menu(vid, display, num_screen, NO_label);
change_rendition(vid,1,1,num_rows,num_columns,NORMAL);
end_pasteboard_update();

start_page = 1;
if(mode == MENU)change_rendition(vid, row, col, 1, num_columns, REVERSE);
done = FALSE;
while(!done)
     {
     if(mode == MONOTONIC)
        CDFLIST_put_message(MES_vid, monotonic_mes[0], 
			    NOBELL, NORMAL, NOPAUSE);
     set_cursor_abs(vid, row, col);
     read_input(
#if defined(CURSESui)
		vid,
#endif
		    &tcode, PASSTHRUri, TRUE);
     erase_display(MES_vid, 1, 1, 1, MES_COLUMNS);
     switch (tcode)
	  {
	  case NEXTITEMkey_LIST:
	       if(row == num_rows || value == num_elements)
		  if(value < num_elements)
		     {
/*
SCROLL UP
*/
		     value++; start_page++;
		     begin_pasteboard_update();
		     erase_display(vid, row1, col1, num_rows, num_columns);
		     load_menu(vid, display+(start_page-1),
		     num_screen, NO_label);
		     end_pasteboard_update();

		     }
		  else
		     {
		     value = 1;
		     row = 1;
		     start_page = 1;
		     begin_pasteboard_update();
		     erase_display(vid, 1, 1, num_rows, num_columns);
		     load_menu(vid, display, num_screen, NO_label);
		     end_pasteboard_update();
		     }
	       else
		  {
		  row++; value++;
		  if(row == num_rows && value == num_elements)
	      	     CDFLIST_put_message(MES_vid, bottom, NOBELL, 
					NORMAL, NOPAUSE);
		  }
	       break;
	  case PREVITEMkey_LIST:
	       if(row > 1)
		  {
		     row--;
		     value--;
		  }
	       else if(value > 1)
		  {
/*
SCROLL DOWN
*/
		     value--; start_page--;
		     begin_pasteboard_update();
		     erase_display(vid, row1, col1, num_rows, num_columns);
		     load_menu(vid, display+(start_page-1),
		     num_screen, NO_label);
		     end_pasteboard_update();
		  }
	       else
		  {
		     start_page = (int) (num_elements - num_screen + 1);
		     value = (int) num_elements;
		     row = num_screen;
		     begin_pasteboard_update();
		     erase_display(vid, row1, col1, num_rows, num_columns);
		     load_menu(vid, display+(start_page-1),
		     num_screen, NO_label);
		     end_pasteboard_update();
		  }
	       break;
/*
PAGE DOWN
*/
	  case PAGEDOWNkey_LIST:
	       start_page = start_page + num_screen;
	       end = start_page + num_screen - 1;
	       value = value + num_screen;
	       if(end > num_elements)
		  {
/*
Display the next page down
*/
		  end = (int) num_elements;
		  start_page = end - num_screen + 1;
		  value = (int) num_elements;
		  row = num_rows;
	      	  CDFLIST_put_message(MES_vid, bottom, NOBELL, NORMAL, NOPAUSE);
		  }
	       begin_pasteboard_update();
	       erase_display(vid, row1, col1, num_rows, num_columns);
	       load_menu(vid, display+(start_page-1), num_screen, NO_label);
	       end_pasteboard_update();
	       break;
/*
PAGE UP
*/
	  case PAGEUPkey_LIST:
	       start_page = start_page - num_screen;
	       value = value - num_screen;
	       if(start_page < 1)
		  {
		  start_page = 1;
		  value = 1;
		  row = 1;
		  CDFLIST_put_message(MES_vid, top, NOBELL, NORMAL, NOPAUSE);
		  }
	       begin_pasteboard_update();
/*
Display the next page up
*/
	       erase_display(vid, row1, col1, num_rows, num_columns);
	       load_menu(vid, display+(start_page-1), num_screen, NO_label);
	       end_pasteboard_update();
	       break;
	  case MONOTONINCkey_LIST:
	  case MONOTONDECkey_LIST:
	  case MONOTONFALSEkey_LIST:
	       if(mode == MONOTONIC) {
		  if(strstr(display[value-1].label,"N/A") != NULL)
	      	     CDFLIST_put_message(MES_vid, illegal_monotonic_mes, 
			RINGBELL, NORMAL, PAUSE);
		  else {
		     if(value > 1) {
			switch (tcode)
			   {
			   case MONOTONINCkey_LIST:
				strcpy(mon_str, " I ");
				break;
			   case MONOTONDECkey_LIST:
				strcpy(mon_str, " D ");
				break;
			   case MONOTONFALSEkey_LIST:
				strcpy(mon_str, " F ");
				break;
			   }			   
       		        strcpy(display[value-1].label+num_columns-3, mon_str);
		        put_chars(vid, mon_str,
			3, row, num_columns-2, NOERASE, NORMAL);
		     }
		     else
	      	        CDFLIST_put_message(MES_vid, record_monotonic_mes, 
			    RINGBELL, NORMAL, PAUSE);
		  }
	       }
	       break;
	  case SELECTkey_LIST:
	       done = TRUE;
	       *rvalue = value;
	       *termcode = SELECTkey_LIST;
	       break;
	  case QUITkey_LIST:
	       done = TRUE;
	       *rvalue = in_value;
	       *termcode = QUITkey_LIST;
	       break;
	  case ACTIONkey_LIST:
	       done = TRUE;
	       *rvalue = value;
	       *termcode = ACTIONkey_LIST;
	       break;
	  case REFRESHkey_FSI:
	       repaint_screen();
	       break;
	  default:
		break;
	  }
	  if(mode == MENU)
	     {
	     change_rendition(vid, 1, 1, num_rows, num_columns, NORMAL);
	     change_rendition(vid, row, 1, 1, num_columns, REVERSE);
	     }
      }
unpaste_virtual_display(vid);
}
void CDFLIST_CDF_info(screen, CDF, CDF_display, OUT_display)
struct	GLOBAL_struct	*screen;
struct	CDF_struct	*CDF;
struct  vid_struct	CDF_display[];
struct  vid_struct	OUT_display[];
{
char 		string[21];					/* V1.4 */
char		temp[7];					/* V1.4 */
int		i;
sprintf(string, "%ld ", C.curr_group->num_dims);
CDFLIST_clear_row(S.CDF_vid, CDF_display, 2, 2, 28);
CDFLIST_put_selection(S.CDF_vid, CDF_display, NUMDIM_ELEMENT_NUM-1, string,
	2, REVERSE);
string[0] = '\0';
CDFLIST_clear_row(S.CDF_vid, CDF_display, 3, 3, 28);
if(C.curr_group->num_dims > 0)
   {
   for (i=0; i < C.curr_group->num_dims; i++)
	{
	sprintf(temp, "%ld ", C.curr_group->dim_sizes[i]);
	strcat(string, temp);
	}
   }
else
    string[0] = '\0';
CDFLIST_put_selection(S.CDF_vid, CDF_display, DIMSIZ_ELEMENT_NUM-1, string,
	10, REVERSE);
sprintf(string, "%ld ", C.curr_group->num_vars-1);
CDFLIST_clear_row(S.CDF_vid, CDF_display, 4, 4, 56);
CDFLIST_put_selection(S.CDF_vid, CDF_display, NUMVAR_ELEMENT_NUM-1, string,
	6, REVERSE);
sprintf(string, "%ld ", C.curr_group->max_record_num+1);
CDFLIST_clear_row(S.CDF_vid, CDF_display, 5, 5, 53);
CDFLIST_put_selection(S.CDF_vid, CDF_display, NUMREC_ELEMENT_NUM-1, string,
	6, REVERSE);
CDFLIST_put_selection(S.CDF_vid, CDF_display, OUT_ELEMENT_NUM-1,
OUT_display[C.output-1].label, 8, REVERSE);
}
void load_vid(vid, display, start_elem, num_elements, label)
WINDOWid 		vid;
struct	vid_struct	display[];
int			start_elem;
int			num_elements;
char			label[];
{
int			i;
int			len;
int			end_elem;
int			erase_mode = NOERASE;
int			video_type = NORMAL;

len = strlen(label);
if(len > 0)label_border(vid, label, REVERSE);
end_elem = start_elem + num_elements;
for(i=start_elem; i< end_elem; i++)
    {
    len = strlen(display[i].label);
    put_chars(vid, display[i].label, len,
    display[i].row, display[i].col, erase_mode, video_type);
    }
}
void load_vars(vid, display, start_num, max_vars, filters)
WINDOWid 		vid;
struct	vid_struct	display[];
int			start_num;
long int		max_vars;
int			filters[];
{
int			i;
int			len;
int			erase_mode = NOERASE;
int			elem;
int			row;
int			bump;
int			end_num;
int			video_type;

end_num = start_num + 8;
begin_pasteboard_update();
erase_display(vid, 2, 6, 9, VAR_COLUMNS);
bump = 0;
row = 1;
for(i=start_num; i< end_num; i++)
    {
    elem = i<=max_vars ? i*NUM_HORIZ_FIELDS :
			 (int) ((i-max_vars)*NUM_HORIZ_FIELDS);
    if(elem >= 0 && elem <= 2)bump = NUM_HORIZ_FIELDS;

    row++;
    len = strlen(display[elem+bump].label);
    if(len > 0)
       {
       put_chars(vid, display[elem+bump].label, len,
       row, display[elem+bump].col, erase_mode, REVERSE);
       change_rendition ( vid, row, 1, 1, 5, NORMAL);
       if(filters[(elem+bump)/NUM_HORIZ_FIELDS-1])
	  {

	  if(filters[(elem+bump)/NUM_HORIZ_FIELDS-1] == FILTER_ON)
/*
Filter is on for this variable, display min/max as reverse video
*/
	     video_type = REVERSE;
	  else
	     video_type = NORMAL;

	  len = strlen(display[elem+bump+1].label);
	  put_chars(vid, display[elem+bump+1].label, len,
	  row, display[elem+bump+1].col, erase_mode, NORMAL);
	  if(len > MINMAX_SIZE)
	     len = EPOCH_WIDTH-1;
	  else
	     len = MINMAX_SIZE-1;
	  change_rendition(vid,row,display[elem+bump+1].col,
		1,len,video_type);
	  len = strlen(display[elem+bump+2].label);
	  put_chars(vid, display[elem+bump+2].label, len,
	     row, display[elem+bump+2].col, erase_mode, NORMAL);
	  if(len > MINMAX_SIZE)
	     len = EPOCH_WIDTH-1;
	  else
	     len = MINMAX_SIZE-1;
	  change_rendition(vid,row,display[elem+bump+2].col,
		1,len,video_type);
	  }
       else
	  erase_display(vid, row, display[elem+bump+1].col, row,
		VAR_COLUMNS);
       len = strlen(display[elem+bump+3].label);
       put_chars(vid, display[elem+bump+3].label, len, row,
		display[elem+bump+3].col, erase_mode, NORMAL);
       }
    }
    end_pasteboard_update();
}
void load_vid_element(vid, display, element_num)
WINDOWid 		vid;
struct	vid_struct	display[];
int			element_num;
{

int			len;

int			erase_mode = NOERASE;
int			video_type = NORMAL;

len = strlen(display[element_num-1].label);
put_chars(vid, display[element_num-1].label, len,
display[element_num-1].row, display[element_num-1].col, erase_mode, video_type);
}
void CDFLIST_load_keydef(vid, line1, line2)
WINDOWid 		vid;
char			line1[];
char			line2[];
{
int			row, col;
int			erase_mode;
int			video_type;
int			len;
begin_pasteboard_update();
erase_display(vid, 1, 1, KEY_ROWS, KEY_COLUMNS);
row = 1; col = 1; erase_mode = ERASE; video_type = NORMAL;
len = strlen(line1);
if(len > KEY_COLUMNS)len = KEY_COLUMNS;
put_chars(vid, line1, len, row, col, erase_mode, video_type);
len = strlen(line2);
row = 2; col = 1; erase_mode = ERASE; video_type = NORMAL;
if(len > KEY_COLUMNS)len = KEY_COLUMNS;
put_chars(vid, line2, len, row, col, erase_mode, video_type);
end_pasteboard_update();
}
void CDFLIST_put_selection(vid, display, element_num, selection,
			field_len, video_type)
WINDOWid 		vid;
struct	vid_struct	display[];
int			element_num;
char			selection[];
int			field_len;
int			video_type;
{
int			len;

int			erase_mode = NOERASE;
int			row, col, end_col;

len = strlen(display[element_num].label);
row = display[element_num].row;
col = display[element_num].field_col;
len = strlen(selection);
end_col = col + field_len - 1;
erase_display(vid, row, col, row, end_col);
put_chars(vid, selection, len, row, col, erase_mode, video_type);
}
void CDFLIST_put_select_row(vid, display, row, element_num, selection,
		field_len, video_type)
WINDOWid 		vid;
struct	vid_struct	display[];
int			row;
int			element_num;
char			selection[];
int			field_len;
int			video_type;
{
int		erase_mode = NOERASE;
int		col, end_col;

col = display[element_num].field_col;
end_col = col + field_len - 1;
erase_display(vid, row, col, row, end_col);
put_chars(vid, selection, field_len, row, col, erase_mode, video_type);
}
void CDFLIST_put_value(vid, display, row, element_num, bin_value, video_type,
		mode)
WINDOWid 		vid;
struct	vid_struct	display[];
int			row;
int			element_num;
double			bin_value;
int			video_type;
int			mode;
{
char			value[20];
int			i;
int			len;

int			erase_mode = NOERASE;
int			col, end_col;

if(bin_value < -1.e12 || bin_value >  1.e12)
   {
   sprintf(value,"%14.6e",bin_value);
   CDFLIST_left_justify(value);
   }
else
   {
   sprintf(value,"%f",bin_value);
   zero_replace(value);
   }
if(mode == DISPLAY)
   {
   len = strlen(display[element_num].label);
   col = display[element_num].col;
   end_col = col + 20;
   erase_display(vid, row, col, row, end_col);
   }
   len = strlen(value);
   for(i = len; i<14; i++)
    value[i] = ' ';
   value[14] = '\0';
if(mode == DISPLAY)
   {
   len = 14;
   put_chars(vid, value, len, row, col, erase_mode, video_type);
   }
strcpy(display[element_num].label, value);
}
void CDFLIST_put_TIME(vid, display, row, element_num, time, video_type, mode)
WINDOWid 		vid;
struct	vid_struct	display[];
int			row;
int			element_num;
double			time;
int			video_type;
int			mode;
{
char			value[80];
int			len;

int			erase_mode = NOERASE;
int			col, end_col;

if(mode == DISPLAY)
   {
   len = EPOCH_WIDTH-1;
   col = display[element_num].col;
   end_col = col + EPOCH_WIDTH;
   erase_display(vid, row, col, row, end_col);
   }
encodeEPOCH (time, value);

if(mode == DISPLAY)put_chars(vid, value, len, row, col, erase_mode, video_type);
strcpy(display[element_num].label, value);
}
void CDFLIST_put_message(vid, message, rbell, video_type, pause)
WINDOWid 		vid;
char			message[];
int			rbell;
int			video_type;
int			pause;
{
int			len;

int			erase_mode = ERASE;
int			row, col;
#if defined (vms)
float			wait = 3.; /*jtl*/
float			short_wait = 1.;
#endif

len = strlen(message);
row = 1;
col = 1;
if(rbell == RINGBELL)
    ring_bell();
if(len > MES_COLUMNS)len = MES_COLUMNS;
put_chars(vid, message, len, row, col, erase_mode, video_type);
if(pause == PAUSE)
#if 0
#if defined(vms)
		     lib$wait(&wait);
#endif

#if defined(unix) || defined(dos)
		     sleep(3);
#endif
#else
                    zzzzz (3.0);
#endif
else if(pause == SHORTPAUSE)
#if 0
#if defined(vms)
		     lib$wait(&short_wait);
#endif

#if defined(unix) | defined(dos)
		     sleep(1);
#endif
#else
                              zzzzz (1.0);
#endif
}
void load_menu(vid, display, num_elements, label)
WINDOWid 		vid;
struct	vid_struct	display[];
int			num_elements;
char			label[];
{
int			i;
int			len;

int			erase_mode = NOERASE;
int			video_type = NORMAL;
int			row;
int			col = 1;

len = strlen(label);
if(len > 0)label_border(vid, label, REVERSE);

for(i=0; i< num_elements; i++)
    {
    row = i + 1;
    len = strlen(display[i].label);
    put_chars(vid, display[i].label, len, row, col,
    erase_mode, video_type);
    }
}
void zero_replace(string)
char		string[];
{
int		zero_index;
int		byte;
int		found = FALSE;
int		len;

CDFLIST_left_justify(string);
byte = 0;
len = strlen(string);
while(byte < len && !found)
      {
      if(string[byte] == PERIOD)found = TRUE;
      byte++;
      }
if(found)
   {
   zero_index = byte;
   while(byte < len)
      {
      if(string[byte] == '0')
	  {
	  if(zero_index == 0)zero_index = byte;
	  }
      else
	 zero_index = 0;
      byte++;
      }
   if(zero_index > 0)
     {
     for (byte=zero_index; byte<len; byte++)
	  string[byte] = ' ';
     }
   }
}
void CDFLIST_check_name(string)
char		string[];
{
char		temp_name[MAX_FILE_NAME_LEN+1];
int		byte;
int		found;
CDFLIST_left_justify(string);
byte = 0;
while(string[byte] != '\0')
      {
      if(string[byte] == 32)string[byte] = '\0';
 byte++;
      }
byte = 0;

found = FALSE;
while(string[byte] != '\0' && !found)
      {
      if(string[byte] == PERIOD)
	    {
	    found = TRUE;
	    temp_name[byte] = '\0';
	    }
      else
	    temp_name[byte] = string[byte];
      byte++;
      }

temp_name[byte] = '\0';
strcpy(string, temp_name);
}
void CDFLIST_left_justify (field)
	char		field[];
{
	int		i;
	int		index;
	int		done;
	char		*temp;
	int		len;
	len = strlen(field);
	temp = (char *) malloc(len);				/* V1.5 */
	if(temp == NULL)return;
/* Blank out temporary hold area */

	for (i = 0; i < len; i++)
		temp[i] = ' ';


		done = FALSE;
		for (index = 0; done != TRUE && index <= len; index++)

			{
/* Look for a non-blank character */

			if(field[index] != ' ')
				{
/* Left Justify by copying from the non-blank character to the end of field */

				strncpy(temp,field+index,len-index);
				for (i = 0; i < len; i++)
					field[i] = ' ';

/* Now copy from the temporary field back to the permanent field */

				strncpy(field, temp, len);
				done = TRUE;
				}
			}
free(temp);
}
void CDFLIST_print_header(vid, row, select, num_select, output, fptr, first_valid)
WINDOWid		vid;
int		        *row;
struct VAR_struct		*select;
long int		num_select;
int			output;
FILE			*fptr;
int			first_valid;
{
int			i;
int  			col = 1;
int 			end_col = 1;
int  			len;
struct VAR_struct		*VN;
VN=select;
for (i = 0; i < num_select; i++)
  {
  if(VN->display == DISPLAY)
    {
    if(output == TERMIN || output == TERMFILE)
       {
       len = strlen(VN->header_name);
       end_col = col + len - 1;
       if(end_col > 80)
	  {
	  (*row)++;
	  col=1;
	  }
       put_chars(vid, VN->header_name, len, *row, col,
		    NOERASE, NORMAL);
       col +=len+1;
       }
    if((output == FILEOUT || output == TERMFILE) && (first_valid))
       fprintf(fptr," %s",VN->header_name);
    } /* DISPLAY */
    VN=VN->next_var;
  }/* end-of-loop */
  if((output == FILEOUT || output == TERMFILE) && (first_valid))
	fprintf(fptr,"\n");
(*row)++;

}
void CDFLIST_print_data(vid, row, col, output, fptr)
WINDOWid	vid;
int		row;
int		*col;
int		output;
FILE		*fptr;
{
int 		len;
if(output == TERMIN || output == TERMFILE)
   {
   len = strlen(print_string);
   put_chars(vid, print_string, len, row, *col, NOERASE, NORMAL);
   (*col) +=len+1;
   }

if(output == TERMFILE || output == FILEOUT)
   fprintf(fptr, " %s", print_string);
}

void CDFLIST_print_string(VN, flag, data_values)
struct VAR_struct		*VN;
int			flag;
union mixed		*data_values;
{
double			value;
    if(VN->data_type == CDF_EPOCH)
	 {
	 if(SO.EPOCH_format == EPOCHFORM_DEF)
	    {
	    if(flag == NORMAL_PRINT)
	       encodeEPOCH (data_values->r8, print_string);
	    else
	       load_fill(flag, EPOCH_STRING_LEN);
	    }
	 else
	    {
	    if(flag == NORMAL_PRINT)
	       encodeEPOCH1 (data_values->r8, print_string);
	    else
	       load_fill(flag, EPOCH1_STRING_LEN);
	    }
	 }
    else if(VN->data_type == CDF_CHAR ||
	    VN->data_type == CDF_UCHAR)
	    {
	    if(flag == NORMAL_PRINT)
	       {
	       if(SO.variable_format == FORMAT && VN->format)
		  EncodeString(VN->num_bytes, data_values->string,
			 print_string,VN->field_width, VN->field_width);
	       else
		  strcpy(print_string, data_values->string);
	       }
	    }
    else
      {
      if(flag == NORMAL_PRINT)
	 {
	 switch(VN->data_type)
	   {
	   case CDF_REAL4:
	   case CDF_FLOAT:
		if(SO.variable_format == FORMAT && VN->format) 
		   EncodeValueFormat(VN->data_type, &data_values->r4,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   {
		   value = (double) data_values->r4;
		   if(value < -1.e12 || value >  1.e12)
		      sprintf(print_string," %13.6e",value);
		   else
		      sprintf(print_string," %13.*f",precision(value),value);
		   }
		break;
	   case CDF_REAL8:
	   case CDF_DOUBLE:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->r8,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   {
		   value = data_values->r8;
		   if(value < -1.e12 || value >  1.e12)
		      sprintf(print_string," %13.6e",value);
		   else
		      sprintf(print_string," %13.*f",precision(value),value);
		   }
		break;
	   case CDF_INT4:
		if((SO.variable_format == FORMAT && VN->format) ||
		   (VN->var_num == RECORD_VAR_NUM))
		   EncodeValueFormat(VN->data_type, &data_values->i4,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string," %11ld  ",data_values->i4);
		break;
	   case CDF_UINT4:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->ui4,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string,"  %10lu  ",data_values->ui4);
		break;
	   case CDF_INT2:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->i2,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string,"      %6d  ",data_values->i2);
		break;
	   case CDF_UINT2:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->ui2,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string,"      %6u  ",data_values->ui2);
		break;
	   case CDF_BYTE:
	   case CDF_INT1:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->byte,
				     print_string, VN->format_value, 13, 13,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string,"       %4d   ",data_values->byte);
		break;
	   case CDF_UINT1:
		if(SO.variable_format == FORMAT && VN->format)
		   EncodeValueFormat(VN->data_type, &data_values->ubyte,
				     print_string, VN->format_value,
				     VN->field_width, VN->field_width,
				     EPOCH0_STYLE);
		else
		   sprintf(print_string,"        %3u   ",data_values->ubyte);
	   } /* end switch */
        } /* NORMAL_PRINT */
     else
        {
/*
Fill data needed for zmode listing types
*/
        if(SO.variable_format == FORMAT && VN->format)
	   load_fill(flag, VN->field_width);
	else
	   load_fill(flag, 14);
        }
       }/* end else */
}
void CDFLIST_var_menus_monoton(screen, CDF, var_rows, var_columns)
struct	GLOBAL_struct	*screen;
struct	CDF_struct	*CDF;
int			*var_rows;
int			*var_columns;
{
/*
create the virtual display for the variables in the CDF, number of rows
depends on the the number of variables.
*/
if(C.curr_group->num_vars > VARSELECT_ROWS)
   *var_rows = VARSELECT_ROWS;
else
   *var_rows = (int) C.curr_group->num_vars;
if((C.max_var_len+6) > VARSELECT_COLUMNS)
   *var_columns = VARSELECT_COLUMNS;
else
   *var_columns = (int) C.max_var_len+6;
create_virtual_display(*var_rows+BORDER_ROWS, *var_columns+BORDER_COLUMNS,
		       &S.VAR_MONOTON_vid, BORDER, NORMAL);
}
void CDFLIST_var_menus(screen, CDF, var_rows, var_columns)
struct	GLOBAL_struct	*screen;
struct	CDF_struct	*CDF;
int			*var_rows;
int			*var_columns;
{
/*
create the virtual display for the variables in the CDF, number of rows
depends on the the number of variables, add 1 for select_var option
*/
if((C.curr_group->num_vars+1) > VARSELECT_ROWS)
   *var_rows = VARSELECT_ROWS;
else
   *var_rows = (int) (C.curr_group->num_vars + 1);
if(C.max_var_len > VARSELECT_COLUMNS)
   *var_columns = VARSELECT_COLUMNS;
else
   *var_columns = (int) C.max_var_len;
create_virtual_display(*var_rows+BORDER_ROWS, *var_columns+BORDER_COLUMNS,
		       &S.VARSELECT_vid, BORDER, NORMAL);
}
void free_discrete(variables)
struct VAR_struct	*variables;
{
struct VAR_struct	*VN;

VN=variables;
while(VN != NULL)
      {
      if(VN->bin_value != NULL)
	 {
         free(VN->bin_value);
	 VN->bin_value = NULL;
	 }
      if(VN->char_value != NULL)
	 {
         free(VN->char_value);
	 VN->char_value = NULL;
	 }
      if(VN->monoton_value != NULL)
	 {
	 free(VN->monoton_value);
	 VN->monoton_value = NULL;
	 }
      if(VN->format_value != NULL)
	 {
	 free(VN->format_value);
	 VN->format_value = NULL;
	 }
      if(VN->pad_value != NULL)
	 {
	 free(VN->pad_value);
	 VN->pad_value = NULL;
	 }
      VN=VN->next_var;
      }
}
void free_vars(variables)
struct VAR_struct	*variables;
{
struct VAR_struct	*VN;
struct VAR_struct	*save;

VN=variables;
while(VN != NULL)
      {
      save = VN->next_var;
      free(VN);
      VN=save;
      }
}

void CDFLIST_free_vars(CDF)
struct CDF_struct		*CDF;
{
int				k;
struct group			*all;

all = C.first_group;
for(k=0; k<C.num_groups; k++)
    {
    free_discrete(all->first_var);
    free_vars(all->first_var);
    all = all->next_group;
    }
}

CDFstatus CDFLIST_close(CDF)
struct	CDF_struct	*CDF;
{
CDFstatus		rcode;
struct group		*all;
struct group		*save_group;

if(C.CDF_id != NUL)
   rcode = CDFlib(SELECT_, CDF_, C.CDF_id,
		CLOSE_, CDF_,
		NULL_);
else
   rcode = CDF_OK;
if (C.num_attrs > 0 && C.attr != NULL)
    {
    free(C.attr);
    C.attr = NULL;
    }

all = C.first_group;
while(all != NULL)
      {
      save_group = all->next_group;
      free(all);
      all = save_group;
      }
return(rcode);
}

void CDFLIST_close_screen()
{
delete_pasteboard(ERASE);
}
double r4_r8(r4_ptr)
float	*r4_ptr;
{
float	r4;
/*
Convert float to double
Based on assumption that float contains 7 significant digits
*/
double		r4r8;
double 		fracr8;
float  		realexp,temp,rfrac,x;
double		base, power,exp;
long int 	frac;
long int 	evalue;
r4 = *r4_ptr;
/*
If the REAL*4 value is 0 then just set the REAL*8 value to 0 and return
*/
if(r4 == 0.) return(0.);

temp = r4;
evalue  = 0;
/*
Calculate the exponent of the incoming REAL*4 value
If absolute value ge 10 exponent is positive
If absolute value lt 1  exponent is negative
*/
if(fabs(temp) >= 10.)
	{
	while(fabs(temp) >= 10.)
	      {
	      evalue = evalue + 1;
	      temp = temp / 10.;
	      }
	}
else if(fabs(temp) < 1.)

	{
	while(fabs(temp) < 1.)
	      {
	      evalue = evalue - 1;
	      temp = temp * 10.;
	      }

	}
/*
Extract out the fractional portion of the real value
*/
/*
exp = (long int) r4;
realexp =  (float) exp;
rfrac = r4-realexp;
*/
if(r4 > 0.)
   exp = floor(r4);
else
   exp = ceil(r4);
realexp = (float) exp;
rfrac = r4 - realexp;
/*
Convert significant digits of fraction portion to integer by multiplying.
*/
base = 10.;
power = (double) (6-evalue);
x = rfrac*pow(base,power);
if(x > 0.)
   frac = (long int) (x + .5);
else
   frac = (long int) (x - .5);
fracr8 = (double) frac;
r4r8 = exp;
/*
Convert the integer back into a fraction by diving.
then ADD back in the integer portion.
*/
r4r8 = r4r8 + fracr8/(pow(base, power));
return(r4r8);
}
void CDFLIST_get_double_attr (CDF_id, Z, attr_num, field_num, scale, rcode)

	CDFid	  CDF_id;
	int 	  Z;
	long 	  attr_num;
	long 	  field_num;
	double	  *scale;
	CDFstatus *rcode;
{
	long 			data_type;
	long 			num_elements=0;
	union mixed		temp;

	*rcode = CDFlib (SELECT_, CDF_, CDF_id,
		 ATTR_,  attr_num,
			 BOO(Z,zENTRY_,rENTRY_),field_num,
		 GET_, 	 BOO(Z,zENTRY_DATATYPE_,rENTRY_DATATYPE_), &data_type,
		 BOO(Z,zENTRY_NUMELEMS_,rENTRY_NUMELEMS_), &num_elements,
		 NULL_);
	if(num_elements > 1)*rcode = NO_SUCH_ENTRY;
	if(*rcode < CDF_OK) return;
	*rcode = CDFlib (SELECT_, CDF_, CDF_id,
			     ATTR_,  attr_num,
				     BOO(Z,zENTRY_,rENTRY_),field_num,
			     GET_,   BOO(Z,zENTRY_DATA_,rENTRY_DATA_), &temp,
			     NULL_);
	if(*rcode < CDF_OK) return;
	switch(data_type)
	       {
	       case CDF_REAL4:
	       case CDF_FLOAT:
		    *scale = r4_r8(&temp.r4);
	       break;
	       case CDF_REAL8:
	       case CDF_DOUBLE:
	       case CDF_EPOCH:
		    *scale = temp.r8;
	       break;
	       case CDF_INT4:
		    *scale = (double) temp.i4;
	       break;
	       case CDF_UINT4:
		    *scale = (double) temp.ui4;
	       break;
	       case CDF_INT2:
		    *scale = (double) temp.i2;
	       break;
	       case CDF_UINT2:
		    *scale = (double) temp.ui2;
	       break;
	       case CDF_BYTE:
	       case CDF_INT1:
		    *scale = (double) temp.byte;
	       break;
	       case CDF_UINT1:
		    *scale = (double) temp.ubyte;
	       }
}
void init_var_display(display, num_vars)
struct	vid_struct 	*display;
long int		 num_vars;
{
int		i;
int		num;
int		index;
char		temp[10];
display[0].row = 1;
display[0].col = 6;
strcpy(display[0].label, "Variable");
display[0].field_col = 6;
display[1].row = 1;
display[1].col = 26;
strcpy(display[1].label, "Minimum");
display[1].field_col = 26;
display[2].row = 1;
display[2].col = 51;
strcpy(display[2].label, "Maximum");
display[2].field_col = 51;
display[3].row = 1;
display[3].col = 75;
strcpy(display[3].label, "Out");
display[3].field_col = 75;
if(num_vars < 8)
   num = 8;
else
   num = (int) num_vars;

for(i=1; i<=num; i++)
    {
    index = (i-1)*NUM_HORIZ_FIELDS;
    display[index+NUM_HORIZ_FIELDS].row = i+1;
    display[index+NUM_HORIZ_FIELDS].col = 1;
    sprintf(temp, "%3d) ",i);
    strcpy(display[index+NUM_HORIZ_FIELDS].label, temp);
    display[index+NUM_HORIZ_FIELDS].field_col = 6;
    display[index+NUM_HORIZ_FIELDS+1].row = i+1;
    display[index+NUM_HORIZ_FIELDS+1].col = 26;
    display[index+NUM_HORIZ_FIELDS+1].label[0] = '\0';
    display[index+NUM_HORIZ_FIELDS+1].field_col = 26;
    display[index+NUM_HORIZ_FIELDS+2].row = i+1;
    display[index+NUM_HORIZ_FIELDS+2].col = 51;
    display[index+NUM_HORIZ_FIELDS+2].label[0] = '\0';
    display[index+NUM_HORIZ_FIELDS+2].field_col = 51;
    display[index+NUM_HORIZ_FIELDS+3].row = i+1;
    display[index+NUM_HORIZ_FIELDS+3].col = 75;
    strcpy(display[index+NUM_HORIZ_FIELDS+3].label, " Y ");
    display[index+NUM_HORIZ_FIELDS+3].field_col = 75;
    }
}

CDFstatus     CDFLIST_select_RZ(screen, CDF, tcode)
struct	GLOBAL_struct	*screen;
struct	CDF_struct	*CDF;
int 			*tcode;
{
int			ok;
int			tempcode;
int			temp_val=0;
int			k,i;
CDFstatus		status;
char			buf[80],temp[10];
int     		len;
int			RZ_rows, RZ_columns;
struct vid_struct  	*RZ_display;
static char		noRvar_mes[] = "There are no rVariables in this CDF";
static char		select_RZ_mes[] = 
"Select rVariables, a zGroup, or zMODE";
struct group		*all;

if(C.num_groups > RZ_ROWS)
   RZ_rows = RZ_ROWS;
else
   RZ_rows = C.num_groups;
RZ_columns = 0;
RZ_display = (struct vid_struct *)
		  malloc(C.num_groups * sizeof(struct vid_struct));
if(RZ_display == NULL)return(BAD_MALLOC);
CDFLIST_put_message(S.MES_vid, select_RZ_mes, NOBELL,
					NORMAL, NOPAUSE);
all = C.first_group;
for(k=0; k<C.num_groups; k++)
    {
    for(i=0; i<80; i++)buf[i] = ' ';
    if(k == 0)
	    strcpy(buf, "rVariables");
    else if(k == C.num_groups-1)
	    strcpy(buf, "zMODE");
    else if(all->num_dims == 0)
	    strcpy(buf, "Z  0:[]");
    else
	    {
	    buf[0] = 'Z';
	    sprintf(buf+2,"%2d:[",(int)all->num_dims);
	    if(all->num_dims > 0)
	       {
	       for (i=0; i < all->num_dims; i++)
		    {
		    sprintf(temp, "%ld", all->dim_sizes[i]);
		    if(i < all->num_dims-1)
		       strcat(temp, ",");
		    else
		       strcat(temp,"]");
		    strcat(buf, temp);
		    }
	       }
	    }
    len = strlen(buf);
    if(len > RZ_columns)RZ_columns = len;
    RZ_display[k].row = k+1;
    RZ_display[k].col = 1;
    strcpy(RZ_display[k].label,buf);
    RZ_display[k].field_col = 1;
    all=all->next_group;

   }
   if(RZ_columns > RZ_COLUMNS)
       RZ_columns = RZ_COLUMNS;
   create_virtual_display(RZ_rows+BORDER_ROWS, RZ_columns+BORDER_COLUMNS,
				&S.RZ_vid, BORDER, NORMAL);
   ok = FALSE;
   while(!ok)
      {
      CDFLIST_select_menu_item(S.RZ_vid, S.MES_vid,
	   &temp_val, RZ_display, C.num_groups, RZ_rows, RZ_columns,
	   RZ_ROW_PASTE, RZ_COL_PASTE, MENU, &tempcode);
      if(tempcode == QUITkey_LIST)
	      {
	      *tcode = QUITkey_LIST;
	      ok = TRUE;
	      }
      else if(temp_val == 1 && C.numRvars ==  0)
	      CDFLIST_put_message(S.MES_vid, noRvar_mes, RINGBELL,
					NORMAL, PAUSE);
      else
	      {
	      *tcode = tempcode;
	      SO.curr_CDF = temp_val-1;
	      C.curr_group = load_group(C.first_group, SO.curr_CDF, C.num_groups);
	      ok = TRUE;
	      }
      }
   free(RZ_display);
   delete_virtual_display(S.RZ_vid);
  if(*tcode == QUITkey_LIST)return(CDF_OK);
  if(temp_val < C.num_groups)
     {
     status = zmode_off(C.CDF_id);
     SO.list_mode = REGMODE;
     }
  else
     {
     status = zmode_on(C.CDF_id);
     SO.list_mode = ZMODE;
     }
  zmode_label(S.CDF_vid);
  return (status);
}

void zmode_label(vid)
WINDOWid vid;
{
int	len = 5;
if(SO.list_mode == ZMODE)
   put_chars(vid, "zMODE",len , ZMODE_ROW, ZMODE_COL, NOERASE, REVERSE);
else
   erase_display(vid, ZMODE_ROW, ZMODE_COL, ZMODE_ROW, CDF_COLUMNS);
}
void NEG_to_POS(CDF_id)
CDFid	CDF_id;
{
CDFstatus rcode;
long convert0;
convert0 = SO.zero == CONVERT ? NEGtoPOSfp0on : NEGtoPOSfp0off; 
rcode = CDFlib (SELECT_, CDF_, CDF_id,
		         CDF_NEGtoPOSfp0_MODE_, convert0, 
		 NULL_);
if(rcode != CDF_OK)rcode = CDF_OK; /* Don't want this to be a killer */
return;
}
CDFstatus zmode_on(CDF_id)
CDFid	CDF_id;
{
CDFstatus rcode;
rcode = CDFlib (SELECT_, CDF_, CDF_id,
			CDF_zMODE_, zMODEon2,
			NULL_);
return(rcode);
}
CDFstatus zmode_off(CDF_id)
CDFid	CDF_id;
{
CDFstatus rcode;
rcode = CDFlib(SELECT_, CDF_, CDF_id,
			CDF_zMODE_, zMODEoff,
			NULL_);
return(rcode);
}

