/******************************************************************************
*
*  NSSDC/CDF						CDFlist.  Part 2 of 4.
*
*  Version 2.6f, 17-May-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.6f 17-May-96, J Love	Linux `gcc' warnings.
*
******************************************************************************/

#define CDFLIST2
#include "cdflist.h"

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		*possible;
long int		num_vars;
long int		num_poss;
struct VAR		**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		*VN;
struct VAR		*SN;
struct VAR		*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 *) malloc (sizeof (struct VAR))) == 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));
	     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		*select;
long int		num_select;
union mixed		data_values[];
int			output;
{
int			i;
double			value;
struct VAR		*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		*select;
long int		num_select;
union  mixed		data_values[];
{
int			i;
CDFstatus 		rcode;
struct VAR		*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		*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,
		   Zq(VN->Z,zVAR_,rVAR_), VN->out_var_num,
		   Zq(VN->Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_),	record_num,
		   Zq(VN->Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_), indices,
	     PUT_, Zq(VN->Z,zVAR_DATA_,rVAR_DATA_), data_values->string,
		    NULL_);
      else
/*
PUT VARIABLES INTO CDF
*/
         rcode = CDFlib (SELECT_, CDF_, NC.CDF_id,
		   Zq(VN->Z,zVAR_,rVAR_), VN->out_var_num,
		   Zq(VN->Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_), record_num,
		   Zq(VN->Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_), indices,
	     PUT_, Zq(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		*select;
long int		record_num;
{
CDFstatus 		rcode;
struct VAR		*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		*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,
		 Zq(VN->Z, zVAR_, rVAR_),  VN->out_var_num,
		 Zq(VN->Z, zVAR_RECNUMBER_,rVARs_RECNUMBER_),record_num,
		 Zq(VN->Z, zVAR_RECCOUNT_, rVARs_RECCOUNT_), recCount,
		 Zq(VN->Z, zVAR_RECINTERVAL_, rVARs_RECINTERVAL_),  recInterval,
		 Zq(VN->Z, zVAR_DIMINDICES_, rVARs_DIMINDICES_), x,
		 Zq(VN->Z, zVAR_DIMCOUNTS_, rVARs_DIMCOUNTS_), 
		 	SO.list_mode == ZMODE ? VN->act_dim_sizes : 
		 				NC.curr_group->dim_sizes,
		 Zq(VN->Z, zVAR_DIMINTERVALS_, rVARs_DIMINTERVALS_), intervals,
	PUT_,    Zq(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,
			  Zq(Z,zVAR_,rVAR_), var_id,
			  Zq(Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_),
				record_num,
			  Zq(Z,zVAR_DIMINDICES_,rVARs_DIMINDICES_),
				indices,
		 GET_, 	  Zq(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		*select;
long int		num_select;
FILE			*fptr;
{
int			i;
double			value;
char			string[30];
struct VAR		*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(!IsGraphChr(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		*possible;
struct  VAR		*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();
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		*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		*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		*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	*variables;
{
struct VAR	*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	*variables;
{
struct VAR	*VN;
struct VAR	*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,
			 Zq(Z,zENTRY_,rENTRY_),field_num,
		 GET_, 	 Zq(Z,zENTRY_DATATYPE_,rENTRY_DATATYPE_), &data_type,
		 Zq(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,
				     Zq(Z,zENTRY_,rENTRY_),field_num,
			     GET_,   Zq(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);
}

