/******************************************************************************
*
*  NSSDC/CDF                                    CDFedit, part 2 (variables).
*
*  Version 1.2c, 6-Sep-95, Hughes STX.
*
*  Modification history:
*
*   V1.0  24-Jan-94, J Love	Original version.
*   V1.0a  8-Feb-94, J Love     DEC Alpha/OpenVMS port.
*   V1.1  15-Dec-94, J Love	CDF V2.5.
*   V1.1a  9-Jan-95, J Love	Window positioning.
*   V1.1b 23-Jan-95, J Love	IRIX 6.x (64-bit).
*   V1.1c 28-Feb-95, J Love	Pass `char' as `int'.
*   V1.2  11-Apr-95, J Love	POSIX.
*   V1.2a 11-May-95, J Love	EPOCH styles.
*   V1.2b  9-Jun-95, J Love	catchrX.
*   V1.2c  6-Sep-95, J Love	CDFexport-related changes.  FSI key
*				definitions.
*
******************************************************************************/

#include "cdfedit.h"

/******************************************************************************
* EditVars.  This function handles both rVariables and zVariables.
******************************************************************************/

Logical EditVars (Z, CDFname, useFormat)
Logical Z;
char *CDFname;
Logical useFormat;
{
   CDFstatus status;
   long varN;
   AOSs2 (header, BLANKSforHEADER, BLANKSforHEADER)
   AOSs2A (trailer,
    "Modify: ________   Create variable: ________   Delete variable: ________",
    "Exit:   ________   Help:            ________")
   static int exitChars[] = { MODIFYkey_EDIT, EXITkey_FSI, CREATEVARkey_EDIT,
			      HELPkey_FSI, DELETEVARkey_EDIT, NUL };
   static char label[6+DU_MAX_NAME_LEN+13+1];
   STATIC_ struct ItemWindowStruct IW = {
      0, 0, 80, label, 2, header, 0, NULL, 0, NULL, NULL, NULL, 13, 2, trailer,
      exitChars, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI
   };
   int varJump = Zq(Z,7,6);
   Logical change;

   /***************************************************************************
   * Build variable lines.
   ***************************************************************************/

   EncodeKeyDefinitions (2, trailer, MODIFYkey_EDIT, CREATEVARkey_EDIT,
			 DELETEVARkey_EDIT, EXITkey_FSI, HELPkey_FSI);
   if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;

   /***************************************************************************
   * Display window.
   ***************************************************************************/

   ItemWindow (NEWiw, &IW, 0);

   /***************************************************************************
   * Read/process keystrokes until request to exit menu.
   ***************************************************************************/

   for (;;) {
     ItemWindow (READiw, &IW);
     switch (IW.key) {
       /***********************************************************************
       * Item selected.
       ***********************************************************************/
       case MODIFYkey_EDIT: {
	 int fieldN;

	 /*********************************************************************
	 * Check if any variables exist.
	 *********************************************************************/

	 if (IW.nItems == 0) {
	   InputErrorWindow (Zq(Z,"Nothing selected (no zVariables exist).",
				  "Nothing selected (no rVariables exist)."),
			     FALSE);
	   break;
	 }

	 /*********************************************************************
	 * Calculate variable number and field number.
	 *********************************************************************/

	 fieldN = IW.itemN % varJump;
	 varN = IW.itemN / varJump;

	 /*********************************************************************
	 * Modify variable name.
	 *********************************************************************/
	 if (fieldN == 0) {
	   static char *header[] = {
	     "Enter new name (with delimiters)...",
	     "Syntax: <delim><char1><char2>...<charN><delim>",
	     "Example: \"SeaSurfaceTemperature\""
	   };
	   AOSs1 (trailer, "Enter: ________   Exit: ________  Help: ________")
	   static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
				      HELPkey_FSI, NUL };
	   static char value[1+CDF_VAR_NAME_LEN+1+1];
	   static char label[14+CDF_VAR_NAME_LEN+1];
	   STATIC_ struct PromptWindowStruct PW = {
	      label, 7, 10, 60, 3, header, CDF_VAR_NAME_LEN+2, value,
	      1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
	      INSERTorOVERkey_FSI
	   };
	   char varName[CDF_VAR_NAME_LEN+1], delim;
	   EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				 HELPkey_FSI);
	   status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
			    GET_, Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
			    NULL_);
	   ReportStatus (status);
	   if (StatusBAD(status)) return FALSE;
	   delim = PickDelimiter(varName, strlen(varName));
	   sprintf (value, "%c%s%c", delim, varName, delim);
	   sprintf (label, " %cVariable %c%s%c ", Zq(Z,'z','r'),
		    delim, varName, delim);
	   PromptWindow (NEWpw, &PW, (int) (strlen(PW.value) - 1),
			 (Logical) TRUE);
	   for (;;) {
	      if (EnterPW(&PW,VARRENAMEhelpID)) {
		char varName[CDF_VAR_NAME_LEN+1];
		if (DecodeDelimitedString(PW.value,varName)) {
		  status = CDFlib (PUT_, Zq(Z,zVAR_NAME_,
					      rVAR_NAME_), varName,
				   NULL_);
		  ReportStatus (status);
		  if (StatusOK(status)) {
		    FreeIW (&IW, FatalError);
		    if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
		    ItemWindow (UPDATEiw, &IW, IW.itemN);
		    break;
		  }
		}
		else
		  InputErrorWindow ("Illegal name (check delimiters).", FALSE);
	      }
	      else
		break;
	   }
	   PromptWindow (DELETEpw, &PW);
	   break;
	 }

	 /*********************************************************************
	 * Modify data specification (data type and number of elements).
	 *********************************************************************/
	 if (fieldN == 1) {
	   long numElems, dataType;
	   static char *header[] = { "Select data type..." };
	   static char *items[] = { DTiwSYMBOLS };
	   AOSs2 (trailer, "Select: ________   Exit: ________",
			   "Help:   ________")
	   static int iLineNs[] = { DTiwLINEnS };
	   static int iCols[] = { DTiwCOLs };
	   static int iLens[] = { DTiwLENs };
	   static int exitChars[] = { SELECTkey_EDIT, EXITkey_FSI,
				      HELPkey_FSI, NUL };
	   static char label[14+CDF_VAR_NAME_LEN+1];
	   STATIC_ struct ItemWindowStruct IWt = {
	      5, 23, 35, label, 1, header, 7, items, 14, iLineNs, iCols,
	      iLens, 7, 2, trailer, exitChars, REFRESHkey_FSI, FALSE
	   };
	   char varName[CDF_VAR_NAME_LEN+1], delim;
	   EncodeKeyDefinitions (2, trailer, SELECTkey_EDIT, EXITkey_FSI,
				 HELPkey_FSI);
	   status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
			    GET_, Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
				  Zq(Z,zVAR_DATATYPE_,
				       rVAR_DATATYPE_), &dataType,
			    NULL_);
	   ReportStatus (status);
	   if (StatusBAD(status)) return FALSE;
	   delim = PickDelimiter(varName, strlen(varName));
	   sprintf (label, " %cVariable %c%s%c ", Zq(Z,'z','r'),
		    delim, varName, delim);
	   ItemWindow (NEWiw, &IWt, DataTypeItemN(dataType));
	   if (EnterIW(&IWt,VARDATATYPEhelpID)) {
	     dataType = WhichDataType(&items[iLineNs[IWt.itemN]]
					    [iCols[IWt.itemN]]);
	     if (STRINGdataType(dataType)) {
	       static char *header[] = {
		 "Enter number of elements (characters)..."
	       };
	       AOSs2 (trailer, "Enter: ________   Exit: ________",
			       "Help:  ________")
	       static char value[MAX_NUMELEMS_LEN+1];
	       static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					  HELPkey_FSI, NUL };
	       STATIC_ struct PromptWindowStruct PWt = {
		 NULL, 12, 37, 42, 1, header, MAX_NUMELEMS_LEN, value,
		 2, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
		 EOLkey_FSI, INSERTorOVERkey_FSI
	       };
	       EncodeKeyDefinitions (2, trailer, ENTERkey_EDIT, EXITkey_FSI,
				     HELPkey_FSI);
	       strcpyX (PWt.value, "", MAX_NUMELEMS_LEN);
	       PromptWindow (NEWpw, &PWt, 0, (Logical) TRUE);
	       for (;;) {
		  if (EnterPW(&PWt,VARNUMELEMShelpID)) {
		    if (sscanf(PWt.value,"%ld",&numElems) == 1) {
		      status = CDFlib (PUT_, Zq(Z,zVAR_DATASPEC_,
						  rVAR_DATASPEC_),
							dataType, numElems,
				       NULL_);
		      ReportStatus (status);
		      if (StatusOK(status)) {
			FreeIW (&IW, FatalError);
			if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
			ItemWindow (UPDATEiw, &IW, IW.itemN);
			break;
		      }
		    }
		    else
		      InputErrorWindow ("Error decoding number of elements.",
					FALSE);
		  }
		  else
		    break;
	       }
	       PromptWindow (DELETEpw, &PWt);
	     }
	     else {
	       status = CDFlib (PUT_, Zq(Z,zVAR_DATASPEC_,
					   rVAR_DATASPEC_), dataType, (long) 1,
				NULL_);
	       ReportStatus (status);
	       if (StatusOK(status)) {
		 FreeIW (&IW, FatalError);
		 if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
		 ItemWindow (UPDATEiw, &IW, IW.itemN);
	       }
	     }
	   }
	   ItemWindow (DELETEiw, &IWt);
	   break;
	 }

	 /*********************************************************************
	 * Dimensionality field.
	 *********************************************************************/
	 if (Z && fieldN == 2) {
	   InputErrorWindow ("Not supported.", FALSE);
	   break;
	 }

	 /*********************************************************************
	 * Modify variances.
	 *********************************************************************/
	 if (fieldN == Zq(Z,3,2)) {
	   long numDims;
	   long recVary, dimVarys[CDF_MAX_DIMS];
	   static char *header[] = {
	     "Enter variances...",
	     "Syntax: <recVary>/<dimVary1><dimVary2>...<dimVaryN>",
	     "Examples: T/, T/F, F/TF, T/TTT"
	   };
	   AOSs1 (trailer, "Enter: ________   Exit: ________  Help: ________")
	   static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
				      HELPkey_FSI, NUL };
	   static char value[2+CDF_MAX_DIMS+1];
	   static char label[14+CDF_VAR_NAME_LEN+1];
	   STATIC_ struct PromptWindowStruct PW = {
	      label, 7, 10, 60, 3, header, 0, value, 1, trailer, exitChars,
	      REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
	      INSERTorOVERkey_FSI
	   };
	   char varName[CDF_VAR_NAME_LEN+1], delim;
	   EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				 HELPkey_FSI);
	   status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
			    GET_, Zq(Z,zVAR_NUMDIMS_,
				       rVARs_NUMDIMS_), &numDims,
				  Zq(Z,zVAR_RECVARY_,
				       rVAR_RECVARY_), &recVary,
				  Zq(Z,zVAR_DIMVARYS_,
				       rVAR_DIMVARYS_), dimVarys,
				  Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
			    NULL_);
	   ReportStatus (status);
	   if (StatusBAD(status)) return FALSE;
	   PW.maxChars = (int) (2 + numDims);
	   EncodeVariances (PW.value, recVary, numDims, dimVarys);
	   delim = PickDelimiter(varName, strlen(varName));
	   sprintf (label, " %cVariable %c%s%c ", Zq(Z,'z','r'),
		    delim, varName, delim);
	   PromptWindow (NEWpw, &PW, (int) strlen(PW.value), (Logical) TRUE);
	   for (;;) {
	      if (EnterPW(&PW,VARVARYShelpID)) {
		if (DecodeVariances(PW.value,numDims,&recVary,dimVarys)) {
		  status = CDFlib (PUT_, Zq(Z,zVAR_RECVARY_,
					      rVAR_RECVARY_), recVary,
					 Zq(Z,zVAR_DIMVARYS_,
					      rVAR_DIMVARYS_), dimVarys,
				   NULL_);
		  ReportStatus (status);
		  if (StatusOK(status)) {
		    FreeIW (&IW, FatalError);
		    BuildVarMenu (Z, CDFname, &IW);
		    ItemWindow (UPDATEiw, &IW, IW.itemN);
		    break;
		  }
		}
		else
		  InputErrorWindow ("Illegal variances.", FALSE);
	      }
	      else
		break;
	   }
	   PromptWindow (DELETEpw, &PW);
	   break;
	 }

	 /*********************************************************************
	 * View/modify attribute entries.
	 *********************************************************************/
	 if (fieldN == Zq(Z,4,3)) {
	   ItemWindow (UNDISPLAYiw, &IW);
	   if (!EditVarEntries(Z,varN)) return FALSE;
	   ItemWindow (REDISPLAYiw, &IW);
	   break;
	 }

	 /*********************************************************************
	 * View/modify values.
	 *********************************************************************/
	 if (fieldN == Zq(Z,5,4)) {
	   ItemWindow (UNDISPLAYiw, &IW);
	   if (!EditVarValues(Z,varN,useFormat,&change)) return FALSE;
	   if (change) {
	     FreeIW (&IW, FatalError);
	     if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
	     ItemWindow (UPDATEiw, &IW, IW.itemN);
	   }
	   ItemWindow (REDISPLAYiw, &IW);
	   break;
	 }

	 /*********************************************************************
	 * More...
	 *********************************************************************/
	 if (fieldN == Zq(Z,6,5)) {
	   ItemWindow (UNDISPLAYiw, &IW);
	   if (!EditVarMore(Z,varN,useFormat,&change)) return FALSE;
	   if (change) {
	     FreeIW (&IW, FatalError);
	     if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
	     ItemWindow (UPDATEiw, &IW, IW.itemN);
	   }
	   ItemWindow (REDISPLAYiw, &IW);
	   break;
	 }

	 break;
       }

       /***********************************************************************
       * Create variable.  If variable is successfully created, the current
       * item is set to its name field.
       ***********************************************************************/
       case CREATEVARkey_EDIT: {
	 Logical created;
	 ItemWindow (UNDISPLAYiw, &IW);
	 if (!CreateVar(Z,&created)) return FALSE;
	 if (created) {
	   FreeIW (&IW, FatalError);
	   if (!BuildVarMenu(Z,CDFname,&IW)) return FALSE;
	   ItemWindow (UPDATEiw, &IW, IW.nItems - varJump);
	 }
	 ItemWindow (REDISPLAYiw, &IW);
	 break;
       }

       /***********************************************************************
       * Delete variable.
       * If variable is successfully deleted, the current item is set to...
       ***********************************************************************/
       case DELETEVARkey_EDIT: {
	 char varName[CDF_VAR_NAME_LEN+1], delim,
	      question[21+CDF_VAR_NAME_LEN+1];
	 if (IW.nItems == 0) {
	   InputErrorWindow (Zq(Z,"Nothing selected (no zVariables exist).",
				  "Nothing selected (no rVariables exist)."),
			     FALSE);
	   break;
	 }
	 varN = IW.itemN / varJump;
	 status = CDFlib (SELECT_, BOO(Z,zVAR_,rVAR_), varN,
			  GET_, BOO(Z,zVAR_NAME_,rVAR_NAME_), varName,
			  NULL_);
	 ReportStatus (status);
	 if (StatusBAD(status)) return FALSE;
	 delim = PickDelimiter (varName, strlen(varName));
	 sprintf (question, "Delete %sVariable %c%s%c ?",
		  BOO(Z,"z","r"), delim, varName, delim);
	 if (ConfirmWindow(7,question,NULL,FALSE,DELETEVARhelpID)) {
	   status = CDFlib (DELETE_, BOO(Z,zVAR_,rVAR_),
			    NULL_);
	   ReportStatus (status);
	   if (StatusOK(status)) {
	     FreeIW (&IW, FatalError);
	     BuildVarMenu (Z, CDFname, &IW);
	     ItemWindow (UPDATEiw, &IW, 0);
	   }
	 }
	 break;
       }

       /***********************************************************************
       * Display online help.
       ***********************************************************************/
       case HELPkey_FSI:
	 OnlineHelpWindow (ilhFile, Zq(Z,ZVARShelpID,RVARShelpID));
	 break;

       /***********************************************************************
       * Exit menu.
       ***********************************************************************/
       case EXITkey_FSI:
	 ItemWindow (DELETEiw, &IW);
	 FreeIW (&IW, FatalError);
	 return TRUE;
     }
   }
}

/******************************************************************************
* BuildVarMenu.
******************************************************************************/

Logical BuildVarMenu (Z, CDFname, IW)
Logical Z;
char *CDFname;
struct ItemWindowStruct *IW;
{
   CDFstatus status;
   long nVars, varN, dataType, numElems, maxRec, nRecords;
   long recVary, dimVarys[CDF_MAX_DIMS];
   long numDims, dimSizes[CDF_MAX_DIMS];
   int curCol, dimN, curItem;
   char varName[CDF_VAR_NAME_LEN+1], field[80+1];

   static char *eLines[] = { "Loading menu..." };
   static int exitChars[] = { NUL };
   STATIC_ struct EditWindowStruct EW = {
     NULL, 10, 30, 17, 0, NULL, 1, 1, eLines, 1, 0, NULL, FALSE, TRUE,
     exitChars, NUL, NUL, NUL, NUL, NUL, NUL, NUL
   };

   /***************************************************************************
   * Determine number of variables.
   ***************************************************************************/

   status = CDFlib (GET_, Zq(Z,CDF_NUMzVARS_,CDF_NUMrVARS_), &nVars,
		    NULL_);
   ReportStatus (status);
   if (StatusBAD(status)) return FALSE;

   if (nVars > MANY_VARs) EditWindow (NEWew, &EW, (Logical) TRUE);

   /***************************************************************************
   * Encode label/header.
   ***************************************************************************/

   status = CDFlib (GET_, Zq(Z,zVARs_MAXREC_,rVARs_MAXREC_), &maxRec,
		    NULL_);
   ReportStatus (status);
   if (StatusBAD(status)) return FALSE;

   nRecords = maxRec + 1;
   sprintf (IW->label, " CDF \"%s\" %cVariables ", CDFname, Zq(Z,'z','r'));

   if (Z) {
     sprintf (IW->hLines[0], "%ld zVariable%s, ", nVars,
	      (nVars == 1 ? "" : "s"));
     sprintf (&(IW->hLines[0][strlen(IW->hLines[0])]),
	      "(maximum of %ld zRecord%s)", nRecords,
	      (nRecords == 1 ? "" : "s"));
     strcpyX (IW->hLines[1],
	      "Name             DataSpec  Dimensions       Varys", 0);
   }
   else {
     status = CDFlib (GET_, rVARs_NUMDIMS_, &numDims,
			    rVARs_DIMSIZES_, dimSizes,
		      NULL_);
     ReportStatus (status);
     if (StatusBAD(status)) return FALSE;
     sprintf (IW->hLines[0], "%ld rVariable%s, ", nVars,
	      (nVars == 1 ? "" : "s"));
     EncodeDimensionality (&(IW->hLines[0][strlen(IW->hLines[0])]), numDims,
			   dimSizes);
     strcatX (IW->hLines[0], " dimensionality, ", 0);
     sprintf (&(IW->hLines[0][strlen(IW->hLines[0])]), "%ld rRecord%s",
	      nRecords, (nRecords == 1 ? "" : "s"));
     strcpyX (IW->hLines[1], "Name             DataSpec  Varys", 0);
   }

   /***************************************************************************
   * Allocate item section control/lines.
   ***************************************************************************/

   AllocIW (IW, (int) (nVars * Zq(Z,7,6)), (int) nVars, 80, FatalError);

   /***************************************************************************
   * Build each variable line.
   ***************************************************************************/

   curItem = 0;

   for (varN = 0; varN < nVars; varN++) {
      /************************************************************************
      * Inquire variable.
      ************************************************************************/
      status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
		       GET_, Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
			     Zq(Z,zVAR_DATATYPE_, rVAR_DATATYPE_), &dataType,
			     Zq(Z,zVAR_NUMELEMS_,rVAR_NUMELEMS_), &numElems,
			     Zq(Z,zVAR_RECVARY_,rVAR_RECVARY_), &recVary,
			     Zq(Z,zVAR_DIMVARYS_,rVAR_DIMVARYS_), dimVarys,
		       NULL_);
      ReportStatus (status);
      if (StatusBAD(status)) return FALSE;

      if (Z) {
	status = CDFlib (SELECT_, zVAR_, varN,
			 GET_, zVAR_NUMDIMS_, &numDims,
			       zVAR_DIMSIZES_, dimSizes,
			 NULL_);
	ReportStatus (status);
	if (StatusBAD(status)) return FALSE;
      }

      /************************************************************************
      * Setup variable name.
      ************************************************************************/

      curCol = 0;

      EncodeString (strlen(varName), varName, field, 0, VARNAME_FIELD_LEN);
      strcpyX (IW->iLines[(int)varN], field, 0);
      if (strlen(field) < (size_t) VARNAME_FIELD_LEN) {
	CatNcharacters (IW->iLines[(int)varN],
			VARNAME_FIELD_LEN - strlen(field), (int) ' ');
      }
      CatNcharacters (IW->iLines[(int)varN], VARNAME_FIELD_BLANKS, (int) ' ');

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen(field);

      curCol += VARNAME_FIELD_LEN + VARNAME_FIELD_BLANKS;
      curItem++;

      /************************************************************************
      * Setup data type & number of elements.
      ************************************************************************/

      strcpyX (field, DataTypeToken(dataType), 0);
      catchrX (field, (int) '/', 0);
      sprintf (&field[strlen(field)], "%ld", numElems);
      if (strlen(field) > (size_t) DATASPEC_FIELD_LEN) {
	strcpyX (field + DATASPEC_FIELD_LEN - 3, "...", 0);
      }
      strcatX (IW->iLines[(int)varN], field, 0);
      if (strlen(field) < (size_t) DATASPEC_FIELD_LEN) {
	CatNcharacters (IW->iLines[(int)varN],
			DATASPEC_FIELD_LEN - strlen(field), (int) ' ');
      }
      CatNcharacters (IW->iLines[(int)varN], DATASPEC_FIELD_BLANKS, (int) ' ');

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen(field);

      curCol += DATASPEC_FIELD_LEN + DATASPEC_FIELD_BLANKS;
      curItem++;

      /************************************************************************
      * If Z variable, setup dimensionality.
      ************************************************************************/

      if (Z) {
	sprintf (field, "%ld:[", numDims);
	for (dimN = 0; dimN < numDims; dimN++) {
	   sprintf (&field[strlen(field)], "%s%ld",
		    (dimN == 0 ? "" : ","), dimSizes[dimN]);
	}
	catchrX (field, (int) ']', 0);
	if (strlen(field) > (size_t) DIMENSIONS_FIELD_LEN) {
	  strcpyX (field + DIMENSIONS_FIELD_LEN - 3, "...", 0);
	}
	strcatX (IW->iLines[(int)varN], field, 0);
	if (strlen(field) < (size_t) DIMENSIONS_FIELD_LEN) {
	  CatNcharacters (IW->iLines[(int)varN],
			  DIMENSIONS_FIELD_LEN - strlen(field), (int) ' ');
	}
	CatNcharacters (IW->iLines[(int)varN], DIMENSIONS_FIELD_BLANKS,
			(int) ' ');
	IW->iLineNs[curItem] = (int) varN;
	IW->iCols[curItem] = curCol;
	IW->iLens[curItem] = strlen (field);
	curCol += DIMENSIONS_FIELD_LEN + DIMENSIONS_FIELD_BLANKS;
	curItem++;
      }

      /************************************************************************
      * Setup variances.
      ************************************************************************/

      sprintf (field, "%s/", TFvarianceToken(recVary));
      for (dimN = 0; dimN < numDims; dimN++) {
	 strcatX (field, TFvarianceToken(dimVarys[dimN]), 0);
      }
      if (strlen(field) > (size_t) VARIANCES_FIELD_LEN) {
	strcpyX (field + VARIANCES_FIELD_LEN - 3, "...", 0);
      }
      strcatX (IW->iLines[(int)varN], field, 0);
      if (strlen(field) < (size_t) VARIANCES_FIELD_LEN) {
	CatNcharacters (IW->iLines[(int)varN],
			VARIANCES_FIELD_LEN - strlen(field), (int) ' ');
      }
      CatNcharacters (IW->iLines[(int)varN], VARIANCES_FIELD_BLANKS, (int)' ');

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen (field);

      curCol += VARIANCES_FIELD_LEN + VARIANCES_FIELD_BLANKS;
      curItem++;

      /************************************************************************
      * Setup "entries" item.
      ************************************************************************/

      if (!Z) {
	CatNcharacters (IW->iLines[(int)varN],
			DIMENSIONS_FIELD_LEN + DIMENSIONS_FIELD_BLANKS,
			(int) ' ');
	curCol += DIMENSIONS_FIELD_LEN + DIMENSIONS_FIELD_BLANKS;
      }

      strcpyX (field, (Z ? "<zEntries>" : "<rEntries>"), 0);
      strcatX (IW->iLines[(int)varN], field, 0);
      CatNcharacters (IW->iLines[(int)varN], 1, (int) ' ');

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen(field);

      curCol += strlen(field) + 1;
      curItem++;

      /************************************************************************
      * Setup "values" item.
      ************************************************************************/

      strcpyX (field, "<values>", 0);
      strcatX (IW->iLines[(int)varN], field, 0);
      CatNcharacters (IW->iLines[(int)varN], 1, (int) ' ');

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen (field);

      curCol += strlen(field) + 1;
      curItem++;

      /************************************************************************
      * Setup "more" item.
      ************************************************************************/

      strcpyX (field, "<more>", 0);
      strcatX (IW->iLines[(int)varN], field, 0);

      IW->iLineNs[curItem] = (int) varN;
      IW->iCols[curItem] = curCol;
      IW->iLens[curItem] = strlen(field);

      curItem++;
   }

   if (nVars > MANY_VARs) EditWindow (DELETEew, &EW, TRUE);
   return TRUE;
}

/******************************************************************************
* EditVarValues.
******************************************************************************/

Logical EditVarValues (Z, varNum, useFormat, change)
Logical Z;
long varNum;
Logical useFormat;
Logical *change;
{
   CDFstatus status;
   long dataType, numElems, numDims, dimSizes[CDF_MAX_DIMS], recVary,
	dimVarys[CDF_MAX_DIMS], indices[CDF_MAX_DIMS], recNum, maxRec;
   int dimN;
   void *binary;
   char delim, *format, varName[CDF_VAR_NAME_LEN];
   static int vvCols[1+CDF_MAX_DIMS+1];
   static int vvLens[1+CDF_MAX_DIMS+1];
   static iLineNs[1+CDF_MAX_DIMS+1] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
   static char *vString;
   static char vLine[MAX_SCREENLINE_LEN+1];
   static char label[12+CDF_VAR_NAME_LEN+9+1];
   static char *iLines[] = { vLine };
   static char *header[] = {
     "Syntax: <recNum>:[<index1>,<index2>,...,<indexN>] = <value>"
   };
   AOSs3 (trailer,
     "Modify: ________   Next item: ____________   Increment: ____________",
     "Exit:   ________   Prev item: ____________   Decrement: ____________",
     "Help:   ________")
   static int exitChars[] = { MODIFYkey_EDIT, EXITkey_FSI, INCREMENTkey_EDIT,
			      DECREMENTkey_EDIT, HELPkey_FSI, NUL };
   STATIC_ struct ItemWindowStruct IW = {
     2, 0, 80, label, 1, header, 1, iLines, 0, iLineNs, vvCols, vvLens, 1,
     3, trailer, exitChars, REFRESHkey_FSI, FALSE
   };
   /***************************************************************************
   * No change yet.  Set to TRUE when the CDF is modified.
   ***************************************************************************/
   *change = FALSE;

   EncodeKeyDefinitions (3, trailer, MODIFYkey_EDIT, NEXTFIELDkey_EDIT,
			 INCREMENTkey_EDIT, EXITkey_FSI, PREVFIELDkey_EDIT,
			 DECREMENTkey_EDIT, HELPkey_FSI);

   status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varNum,
		    GET_, Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
			  Zq(Z,zVAR_NUMDIMS_,rVARs_NUMDIMS_), &numDims,
			  Zq(Z,zVAR_DIMSIZES_,rVARs_DIMSIZES_), dimSizes,
			  Zq(Z,zVAR_DATATYPE_,rVAR_DATATYPE_), &dataType,
			  Zq(Z,zVAR_NUMELEMS_,rVAR_NUMELEMS_), &numElems,
			  Zq(Z,zVAR_RECVARY_,rVAR_RECVARY_), &recVary,
			  Zq(Z,zVAR_DIMVARYS_,rVAR_DIMVARYS_), dimVarys,
		    NULL_);
   ReportStatus (status);
   if (StatusBAD(status)) return FALSE;

   binary = AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)),
			    FatalError);
   vString = (char *)
	     AllocateMemory ((size_t) (STRINGdataType(dataType) ?
				       numElems+2 : MAX_nonSTRING_VALUE_LEN),
			     FatalError);
   format = (useFormat ? GetFormatEntry(Z,varNum) : NULL);

   delim = PickDelimiter (varName, strlen(varName));
   sprintf (IW.label, " %cVariable %c%s%c Values ", Zq(Z,'z','r'), delim,
	    varName, delim);

   recNum = 0;
   for (dimN = 0; dimN < numDims; dimN++) indices[dimN] = 0;
   
   if (!BuildVarValueLine(Z,recNum,recVary,numDims,indices,
			  dimVarys,dataType,numElems,binary,
			  vString,vLine,&(IW.nItems),vvCols,
			  vvLens,IW.nColsTotal-2,format)) return FALSE;

   ItemWindow (NEWiw, &IW, 0);
   ItemWindow (READiw, &IW);
   for (;;) {
     switch (IW.key) {
       /***********************************************************************
       * Up or down arrow.
       ***********************************************************************/
       case INCREMENTkey_EDIT:
       case DECREMENTkey_EDIT:
	 if (IW.itemN == 0) {
	   /*******************************************************************
	   * Record number.  If the record variance is FALSE, incrementing
	   * and/or decrementing is illegal.
	   *******************************************************************/
	   if (recVary) {
	     status = CDFlib (GET_, Zq(Z,zVAR_MAXREC_,rVAR_MAXREC_), &maxRec,
			      NULL_);
	     ReportStatus (status);
	     if (StatusBAD(status)) return FALSE;
	     if (maxRec == -1) maxRec = 0;
	     if (IW.key == INCREMENTkey_EDIT)
	       recNum = (recNum >= maxRec ? 0 : recNum + 1);
	     else
	       recNum = (recNum == 0 ? maxRec :
				       (recNum > maxRec ? maxRec :
							  recNum - 1));
	     if (!BuildVarValueLine(Z,recNum,recVary,numDims,
				    indices,dimVarys,dataType,
				    numElems,binary,vString,vLine,
				    &(IW.nItems),vvCols,vvLens,
				    IW.nColsTotal-2,format)) return FALSE;
	     ItemWindow (UPDATEiw, &IW, IW.itemN);
	   }
	   else
	     ItemWindow (BEEPiw, &IW);
	 }
	 else
	   if (IW.itemN == IW.nItems - 1) {
	     /*****************************************************************
	     * Value (error - just ring bell).  The value is always the last
	     * item.
	     *****************************************************************/
	     ring_bell ();
	   }
	   else {
	     /*****************************************************************
	     * Must be a dimension index.  Calculate which dimension was
	     * selected.  There must be at least one dimension for this
	     * point to have been reached.
	     *****************************************************************/
	     dimN = IW.itemN - 1;
	     if (dimVarys[dimN]) {
	       if (IW.key == INCREMENTkey_EDIT)
		 indices[dimN] = (indices[dimN] + 1) % dimSizes[dimN];
	       else
		 indices[dimN] = (indices[dimN] - 1 +
				  dimSizes[dimN]) % dimSizes[dimN];
	       if (!BuildVarValueLine(Z,recNum,recVary,numDims,
				      indices,dimVarys,dataType,
				      numElems,binary,vString,
				      vLine,&(IW.nItems),vvCols,
				      vvLens,IW.nColsTotal-2,format)) return
								      FALSE;
	       ItemWindow (UPDATEiw, &IW, IW.itemN);
	     }
	     else
	       ItemWindow (BEEPiw, &IW);
	   }
	 break;
       /***********************************************************************
       * Modify key.
       ***********************************************************************/
       case MODIFYkey_EDIT:
	 if (IW.itemN == 0) {
	   /*******************************************************************
	   * Record number.  If the record variance is FALSE, a modification
	   * is illegal.
	   *******************************************************************/
	   if (recVary) {
	     static char *header[] = { "Enter record number..." };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static char value[MAX_RECORD_NUMBER_LEN+1];
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     STATIC_ struct PromptWindowStruct PW = {
	       NULL, 11, 0, 80, 1, header, MAX_RECORD_NUMBER_LEN, value,
	       1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
	       EOLkey_FSI, INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     sprintf (PW.value, "%ld", recNum + 1);
	     PromptWindow (NEWpw, &PW, (int) strlen(PW.value), (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PW,RECNUMBERhelpID)) {
		  long newRecNum;
		  if (sscanf(PW.value,"%ld",&newRecNum) == 1) {
		    if (newRecNum > 0) {
		      recNum = newRecNum - 1;
		      if (!BuildVarValueLine(Z,recNum,recVary,
					     numDims,indices,
					     dimVarys,dataType,
					     numElems,binary,
					     vString,vLine,
					     &(IW.nItems),vvCols,
					     vvLens,IW.nColsTotal-2,
					     format)) return FALSE;
		      ItemWindow (UPDATEiw, &IW, IW.itemN);
		      break;
		    }
		    else
		      InputErrorWindow ("Record number out of valid range.",
					FALSE);
		  }
		  else
		    InputErrorWindow ("Error decoding record number.", FALSE);
		}
		else
		  break;
	     }
	     PromptWindow (DELETEpw, &PW);
	     }
	   else
	     ItemWindow (BEEPiw, &IW);
	 }
	 else
	   if (IW.itemN == IW.nItems - 1) {
	     /*****************************************************************
	     * Value - prompt for new value.  The value is always the last
	     * item.
	     *****************************************************************/
	     static char *headerNONCHAR[] = {
	       "Enter new value..."
	     };
	     static char *headerCHAR[] = {
	       "Enter new value (delimiters required)..."
	     };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     STATIC_ struct PromptWindowStruct PW = {
		NULL, 11, 0, 80, 1, NULL, 0, NULL, 1, trailer, exitChars,
		REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
		INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     PW.hLines = (STRINGdataType(dataType) ? headerCHAR :
						     headerNONCHAR);
	     PW.maxChars = (STRINGdataType(dataType) ?
			    (int) (numElems + 2) : MAX_nonSTRING_VALUE_LEN);
	     PW.value = (char *) AllocateMemory ((size_t) (PW.maxChars + 1),
						 FatalError);
	     strcpyX (PW.value, vString, PW.maxChars);
	     PromptWindow (NEWpw, &PW,
	     		   (int) BOO(STRINGdataType(dataType),
				     strlen(PW.value)-1,
			             strlen(PW.value)), (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PW,VARVALUEhelpID)) {
		  long nElemsEntered;
		  void *newBinary;
		  if (DecodeValues(PW.value,dataType,
				   &nElemsEntered,&newBinary,EPOCH0_STYLE)) {
		    if (nElemsEntered == numElems) {
		      status = CDFlib (PUT_, Zq(Z,zVAR_DATA_,
						  rVAR_DATA_), newBinary,
				       NULL_);
		      ReportStatus (status);
		      FreeMemory (newBinary, FatalError);
		      if (StatusOK(status)) {
			if (!BuildVarValueLine(Z,recNum,recVary,
					       numDims,indices,
					       dimVarys,dataType,
					       numElems,binary,
					       vString,vLine,
					       &(IW.nItems),
					       vvCols, vvLens,
					       IW.nColsTotal-2,
					       format)) return FALSE;
			ItemWindow (UPDATEiw, &IW, IW.itemN);
			*change = TRUE;
			break;
		      }
		    }
		    else {
		      char tempS[MAX_MESSAGE_TEXT_LEN+1];
		      strcpyX (tempS, "Illegal number of elements ",
			       MAX_MESSAGE_TEXT_LEN);
		      if (nElemsEntered > numElems)
			strcatX (tempS, "(too many).", MAX_MESSAGE_TEXT_LEN);
		      else
			strcatX (tempS, "(too few).", MAX_MESSAGE_TEXT_LEN);
		      InputErrorWindow (tempS, FALSE);
		      FreeMemory (newBinary, FatalError);
		    }
		  }
		  else
		    InputErrorWindow ("Illegal value.", FALSE);
		}
		else
		  break;
	     }
	     FreeMemory (PW.value, FatalError);
	     PromptWindow (DELETEpw, &PW);
	   }
	   else {
	     /*****************************************************************
	     * Must be a dimension index.  Calculate which dimension was
	     * selected.  There must be at least one dimension this point
	     * to have been reached.
	     *****************************************************************/
	     static char *header[] = { "Enter dimension index..." };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static char value[MAX_DIMENSION_INDEX_LEN+1];
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     STATIC_ struct PromptWindowStruct PW = {
	       NULL, 11, 0, 80, 1, header, MAX_DIMENSION_INDEX_LEN, value,
	       1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
	       EOLkey_FSI, INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     dimN = IW.itemN - 1;
	     if (dimVarys[dimN]) {
	       sprintf (PW.value, "%ld", indices[dimN]+1);
	       PromptWindow (NEWpw, &PW, (int) strlen(PW.value),
			     (Logical) TRUE);
	       for (;;) {
		  if (EnterPW(&PW,DIMINDEXhelpID)) {
		    long newIndex;
		    if (sscanf(PW.value,"%ld",&newIndex) == 1) {
		      if (newIndex > 0 && newIndex <= dimSizes[dimN]) {
			indices[dimN] = newIndex - 1;
			if (!BuildVarValueLine(Z,recNum,recVary,
					       numDims,indices,
					       dimVarys,dataType,
					       numElems,binary,
					       vString,vLine,
					       &(IW.nItems),
					       vvCols,vvLens,
					       IW.nColsTotal-2,
					       format)) return FALSE;
			ItemWindow (UPDATEiw, &IW, IW.itemN);
			break;
		      }
		      else
			InputErrorWindow ("Dimension index out of range",
					  FALSE);
		    }
		    else
		      InputErrorWindow ("Error decoding dimension index.",
					FALSE);
		  }
		  else
		    break;
	       }
	       PromptWindow (DELETEpw, &PW);
	     }
	     else
	       ItemWindow (BEEPiw, &IW);
	   }
	 break;

       /***********************************************************************
       * Display online help.
       ***********************************************************************/
       case HELPkey_FSI:
	 OnlineHelpWindow (ilhFile, VARVALUEShelpID);
	 break;

       /***********************************************************************
       * Exit.
       ***********************************************************************/
       case EXITkey_FSI:
	 FreeMemory (vString, FatalError);
	 FreeMemory (binary, FatalError);
	 if (format != NULL) FreeMemory (format, FatalError);
	 ItemWindow (DELETEiw, &IW);
	 return TRUE;

       /***********************************************************************
       * Unknown key.
       ***********************************************************************/
       default:
	 ring_bell ();
     }
     ItemWindow (READiw, &IW);
   }
}

/******************************************************************************
* BuildVarValueLine.
******************************************************************************/

Logical BuildVarValueLine (Z, recNum, recVary, numDims, indices, dimVarys,
			   dataType, numElems, binary, vString, vLine, nItems,
			   vvCols, vvLens, nCols, format)
Logical Z;
long recNum;
long recVary;
long numDims;
long *indices;
long *dimVarys;
long dataType;
long numElems;
void *binary;
char *vString;
char *vLine;
int *nItems;
int *vvCols;
int *vvLens;
int nCols;
char *format;
{
   CDFstatus status;
   int dimN;
   Logical virtual;
   static char virtualT[] = " <virtual>";
   char tmp[80+1];
   int itemN = 0, availCols;

   /***************************************************************************
   * Encode record number.
   ***************************************************************************/

   vvCols[itemN] = 0;

   if (recVary)
     sprintf (tmp, "%ld", recNum + 1);
   else
     strcpyX (tmp, "*", 0);

   vvLens[itemN] = strlen(tmp);
   itemN++;

   strcpyX (vLine, tmp, 0);
   strcatX (vLine, ":[", 0);

   /***************************************************************************
   * Encode dimension indices.
   ***************************************************************************/

   for (dimN = 0; dimN < numDims; dimN++) {
      if (dimN != 0) strcatX(vLine, ",", 0);
      vvCols[itemN] = strlen(vLine);
      if (dimVarys[dimN])
	sprintf (tmp, "%ld", indices[dimN] + 1);
      else
	strcpyX (tmp, "*", 0);
      vvLens[itemN] = strlen(tmp);
      itemN++;
      strcatX (vLine, tmp, 0);
   }

   strcatX (vLine, "] = ", 0);

   /***************************************************************************
   * Encode value.
   ***************************************************************************/

   vvCols[itemN] = strlen(vLine);

   status = CDFlib (SELECT_, Zq(Z,zVAR_RECNUMBER_,rVARs_RECNUMBER_), recNum,
			     Zq(Z,zVAR_DIMINDICES_,
				  rVARs_DIMINDICES_), indices,
		    GET_, Zq(Z,zVAR_DATA_,rVAR_DATA_), binary,
		    NULL_);
   ReportStatus (status);
   if (StatusBAD(status)) return FALSE;

   virtual = (status == VIRTUAL_RECORD_DATA ? TRUE : FALSE);

   availCols = nCols - strlen(vLine) - (virtual ? strlen(virtualT) : 0);
   EncodeValuesFormat (dataType, numElems, binary, tmp, format,
		       -(virtual ? availCols : 0), availCols, EPOCH0_STYLE);
   if (virtual) strcatX (tmp, virtualT, 0);

   strcatX (vLine, tmp, 0);
   vvLens[itemN] = strlen(tmp);
   *nItems = itemN + 1;

   EncodeValuesFormat (dataType, numElems, binary, vString, format, 0,
		       BOO(STRINGdataType(dataType),(int)(numElems + 2),
						    MAX_nonSTRING_VALUE_LEN),
		       EPOCH0_STYLE);
   return TRUE;
}

/******************************************************************************
* EditVarMore.
******************************************************************************/

Logical EditVarMore (Z, varN, useFormat, change)
Logical Z;
long varN;
Logical useFormat;
Logical *change;
{
   CDFstatus status;
   AOSs5 (header, BLANKSforHEADER, BLANKSforHEADER, BLANKSforHEADER,
	  BLANKSforHEADER, BLANKSforHEADER)
   AOSs1 (trailer, "Select: ________   Exit: ________  Help: ________")
   static int exitChars[] = { SELECTkey_EDIT, EXITkey_FSI, HELPkey_FSI,
			      NUL };
   static char label[12+CDF_VAR_NAME_LEN+9+1];
   static char *items[] = {
     "     <modify pad value>      <modify extend records>",
     "     <allocate records>      <write initial records>"
   };
   static int iLineNs[] = { 0, 0, 1, 1 };
   static int iCols[] = { 5, 29, 5, 29 };
   static int iLens[] = { 18, 23, 18, 23 };
   STATIC_ struct ItemWindowStruct IW = {
      2, 10, 59, label, 5, header, 2, items, 4, iLineNs, iCols, iLens, 2,
      1, trailer, exitChars, REFRESHkey_FSI, FALSE
   };

   /***************************************************************************
   * No change yet.  Set to TRUE when the CDF is modified.
   ***************************************************************************/

   *change = FALSE;

   /***************************************************************************
   * Build variable `more' menu.
   ***************************************************************************/

   EncodeKeyDefinitions (1, trailer, SELECTkey_EDIT, EXITkey_FSI,
			 HELPkey_FSI);
   if (!BuildVarMoreMenu(Z,varN,&IW,useFormat)) return FALSE;

   /***************************************************************************
   * Display window.
   ***************************************************************************/

   ItemWindow (NEWiw, &IW, 0);

   /***************************************************************************
   * Read/process keystrokes until request to exit menu.
   ***************************************************************************/

   for (;;) {
     ItemWindow (READiw, &IW);
     switch (IW.key) {
       /***********************************************************************
       * Item selected.
       ***********************************************************************/
       case SELECTkey_EDIT: {
	 switch (IW.itemN) {
	   /*******************************************************************
	   * Modify pad value.
	   *******************************************************************/
	   case 0: {
	     long dataType, numElems;
	     void *binary;
	     char *format;
	     static char *headerNONCHAR[] = {
		"Enter new pad value..."
	     };
	     static char *headerCHAR[] = {
		"Enter new pad value (delimiters required)..."
	     };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     STATIC_ struct PromptWindowStruct PWt = {
		NULL, 10, 15, 50, 1, NULL, 0, NULL, 1, trailer, exitChars,
		REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
		INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
			      GET_, Zq(Z,zVAR_DATATYPE_,
					 rVAR_DATATYPE_), &dataType,
				    Zq(Z,zVAR_NUMELEMS_,
					 rVAR_NUMELEMS_), &numElems,
			      NULL_);
	     ReportStatus (status);
	     if (StatusBAD(status)) return FALSE;
	     binary = AllocateMemory ((size_t) (CDFelemSize(dataType) *
						numElems),
				      FatalError);
	     status = CDFlib (GET_, Zq(Z,zVAR_PADVALUE_,
					 rVAR_PADVALUE_), binary,
			      NULL_);
	     switch (status) {
	       case CDF_OK:
	       case NO_PADVALUE_SPECIFIED:
		 break;
	       default:
		 ReportStatus (status);
		 return FALSE;
	     }
	     PWt.hLines = (STRINGdataType(dataType) ? headerCHAR :
						      headerNONCHAR);
	     PWt.maxChars = (STRINGdataType(dataType) ?
			     (int) (numElems + 2) : MAX_nonSTRING_VALUE_LEN);
	     PWt.value = (char *) AllocateMemory ((size_t) (PWt.maxChars + 1),
						  FatalError);
	     format = (useFormat ? GetFormatEntry(Z,varN) : NULL);
	     EncodeValuesFormat (dataType, numElems, binary, PWt.value, format,
				 0, 0, EPOCH0_STYLE);
	     PromptWindow (NEWpw, &PWt,
			   (int) BOO(STRINGdataType(dataType),
			   	     strlen(PWt.value)-1,
			   	     strlen(PWt.value)), (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PWt,PADVALUEhelpID)) {
		  long nElemsEntered;
		  void *newBinary;
		  if (DecodeValues(PWt.value,dataType,
				   &nElemsEntered,&newBinary,EPOCH0_STYLE)) {
		    if (nElemsEntered == numElems) {
		      status = CDFlib (PUT_, Zq(Z,zVAR_PADVALUE_,
						  rVAR_PADVALUE_), newBinary,
				       NULL_);
		      ReportStatus (status);
		      if (StatusOK(status)) {
			if (!BuildVarMoreMenu(Z,varN,&IW,useFormat)) return
								     FALSE;
			ItemWindow (UPDATEiw, &IW, IW.itemN);
			FreeMemory (newBinary, FatalError);
			*change = TRUE;
			break;
		      }
		      FreeMemory (newBinary, FatalError);
		    }
		    else {
		      char tempS[MAX_MESSAGE_TEXT_LEN+1];
		      strcpyX (tempS, "Illegal number of elements ",
			       MAX_MESSAGE_TEXT_LEN);
		      if (nElemsEntered > numElems)
			strcatX (tempS, "(too many)", MAX_MESSAGE_TEXT_LEN);
		      else
			strcatX (tempS, "(too few).", MAX_MESSAGE_TEXT_LEN);
		      InputErrorWindow (tempS, FALSE);
		      FreeMemory (newBinary, FatalError);
		    }
		  }
		  else
		    InputErrorWindow ("Illegal value.", FALSE);
		}
		else
		  break;
	     }
	     FreeMemory (PWt.value, FatalError);
	     FreeMemory (binary, FatalError);
	     if (format != NULL) FreeMemory (format, FatalError);
	     PromptWindow (DELETEpw, &PWt);
	     break;
	   }

	   /*******************************************************************
	   * Number of `extend' records.
	   *******************************************************************/
	   case 1: {
	     static char *header[] = { "Enter number of extend records..." };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     static char value[MAX_nonSTRING_VALUE_LEN+1];
	     STATIC_ struct PromptWindowStruct PWt = {
		NULL, 10, 15, 50, 1, header, MAX_nonSTRING_VALUE_LEN, value,
		1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
		EOLkey_FSI, INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     strcpyX (value, "", MAX_nonSTRING_VALUE_LEN);
	     PromptWindow (NEWpw, &PWt, 0, (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PWt,EXTENDRECShelpID)) {
		  long nRecords;
		  if (sscanf(PWt.value,"%ld",&nRecords) == 1) {
		    status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
				     PUT_, Zq(Z,zVAR_EXTENDRECS_,
						rVAR_EXTENDRECS_), nRecords,
				     NULL_);
		    ReportStatus (status);
		    if (StatusOK(status)) {
		      if (!BuildVarMoreMenu(Z,varN,&IW,useFormat)) return
								   FALSE;
		      ItemWindow (UPDATEiw, &IW, IW.itemN);
		      *change = TRUE;
		      break;
		    }
		  }
		  else
		    InputErrorWindow ("Error decoding number of records.",
				      FALSE);
		}
		else
		  break;
	     }
	     PromptWindow (DELETEpw, &PWt);
	     break;
	   }

	   /*******************************************************************
	   * Allocate records.
	   *******************************************************************/
	   case 2: {
	     static char *header[] = {
	       "Enter number of records to allocate..."
	     };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     static char value[MAX_nonSTRING_VALUE_LEN+1];
	     STATIC_ struct PromptWindowStruct PWt = {
		NULL, 10, 15, 50, 1, header, MAX_nonSTRING_VALUE_LEN, value,
		1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
		EOLkey_FSI, INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     strcpyX (value, "", MAX_nonSTRING_VALUE_LEN);
	     PromptWindow (NEWpw, &PWt, 0, (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PWt,ALLOCATERECShelpID)) {
		  long nRecords;
		  if (sscanf(PWt.value,"%ld",&nRecords) == 1) {
		    status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
				     PUT_, Zq(Z,zVAR_ALLOCATERECS_,
						rVAR_ALLOCATERECS_), nRecords,
				     NULL_);
		    ReportStatus (status);
		    if (StatusOK(status)) {
		      if (!BuildVarMoreMenu(Z,varN,&IW,useFormat)) return
								   FALSE;
		      ItemWindow (UPDATEiw, &IW, IW.itemN);
		      *change = TRUE;
		      break;
		    }
		  }
		  else
		    InputErrorWindow ("Error decoding number of records.",
				      FALSE);
		}
		else
		  break;
	     }
	     PromptWindow (DELETEpw, &PWt);
	     break;
	   }

	   /*******************************************************************
	   * Write initial records.
	   *******************************************************************/
	   case 3: {
	     static char *header[] = { "Enter number of initial records..." };
	     AOSs1 (trailer,
		    "Enter: ________   Exit: ________  Help: ________")
	     static int exitChars[] = { ENTERkey_EDIT, EXITkey_FSI,
					HELPkey_FSI, NUL };
	     static char value[MAX_nonSTRING_VALUE_LEN+1];
	     STATIC_ struct PromptWindowStruct PWt = {
		NULL, 10, 15, 50, 1, header, MAX_nonSTRING_VALUE_LEN, value,
		1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI,
		EOLkey_FSI, INSERTorOVERkey_FSI
	     };
	     EncodeKeyDefinitions (1, trailer, ENTERkey_EDIT, EXITkey_FSI,
				   HELPkey_FSI);
	     strcpyX (value, "", MAX_nonSTRING_VALUE_LEN);
	     PromptWindow (NEWpw, &PWt, 0, (Logical) TRUE);
	     for (;;) {
		if (EnterPW(&PWt,INITIALRECShelpID)) {
		  long nRecords;
		  if (sscanf(PWt.value,"%ld",&nRecords) == 1) {
		    status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
				     PUT_, Zq(Z,zVAR_INITIALRECS_,
						rVAR_INITIALRECS_), nRecords,
				     NULL_);
		    ReportStatus (status);
		    if (StatusOK(status)) {
		      if (!BuildVarMoreMenu(Z,varN,&IW,useFormat)) return
								   FALSE;
		      ItemWindow (UPDATEiw, &IW, IW.itemN);
		      *change = TRUE;
		      break;
		    }
		  }
		  else
		    InputErrorWindow ("Error decoding number of records.",
				      FALSE);
		}
		else
		  break;
	     }
	     PromptWindow (DELETEpw, &PWt);
	     break;
	   }

	 }
	 break;
       }

       /***********************************************************************
       * Online help.
       ***********************************************************************/
       case HELPkey_FSI:
	 OnlineHelpWindow (ilhFile, VARMOREhelpID);
	 break;

       /***********************************************************************
       * Exit menu.
       ***********************************************************************/
       case EXITkey_FSI:
	 ItemWindow (DELETEiw, &IW);
	 return TRUE;
     }
   }
}

/******************************************************************************
* BuildVarMoreMenu.
******************************************************************************/

Logical BuildVarMoreMenu (Z, varN, IW, useFormat)
Logical Z;
long varN;
struct ItemWindowStruct *IW;
Logical useFormat;
{
  CDFstatus status;
  char varName[CDF_VAR_NAME_LEN+1];
  long dataType, numElems, maxRec, maxAllocRec, nAllocRecs, extendRecs,
       nIndexRecords, nIndexEntries, CDFformat;
  long numDims, dimSizes[CDF_MAX_DIMS];
  long recVary, dimVarys[CDF_MAX_DIMS];
  void *padBinary;
  int pad;
  char *format, delim;

  /****************************************************************************
  * Inquire variable.
  ****************************************************************************/

  status = CDFlib (SELECT_, Zq(Z,zVAR_,rVAR_), varN,
		   GET_, CDF_FORMAT_, &CDFformat,
			 Zq(Z,zVAR_NAME_,rVAR_NAME_), varName,
			 Zq(Z,zVAR_DATATYPE_,rVAR_DATATYPE_), &dataType,
			 Zq(Z,zVAR_NUMELEMS_,rVAR_NUMELEMS_), &numElems,
			 Zq(Z,zVAR_NUMDIMS_,rVARs_NUMDIMS_), &numDims,
			 Zq(Z,zVAR_DIMSIZES_,rVARs_DIMSIZES_), dimSizes,
			 Zq(Z,zVAR_RECVARY_,rVAR_RECVARY_), &recVary,
			 Zq(Z,zVAR_DIMVARYS_,rVAR_DIMVARYS_), dimVarys,
			 Zq(Z,zVAR_MAXREC_,rVAR_MAXREC_), &maxRec,
			 Zq(Z,zVAR_MAXallocREC_,
			      rVAR_MAXallocREC_), &maxAllocRec,
			 Zq(Z,zVAR_EXTENDRECS_,rVAR_EXTENDRECS_), &extendRecs,
		   NULL_);
  ReportStatus (status);
  if (StatusBAD(status)) return FALSE;

  if (CDFformat == SINGLE_FILE) {
    status = CDFlib (GET_, Zq(Z,zVAR_nINDEXRECORDS_,
				rVAR_nINDEXRECORDS_), &nIndexRecords,
			   Zq(Z,zVAR_nINDEXENTRIES_,
				rVAR_nINDEXENTRIES_), &nIndexEntries,
		     NULL_);
    ReportStatus (status);
    if (StatusBAD(status)) return FALSE;
  }

  /****************************************************************************
  * Encode label/header lines.
  ****************************************************************************/

  delim = PickDelimiter (varName, strlen(varName));
  sprintf (IW->label, " %cVariable %c%s%c `More' ", Zq(Z,'z','r'), delim,
	   varName, delim);

  sprintf (IW->hLines[0], " DataSpec: %s/%ld", DataTypeToken(dataType),
	   numElems);
  pad = VAR_MORE_MENU_1st_HALF_LEN - strlen(IW->hLines[0]);
  if (pad > 0) CatNcharacters (IW->hLines[0], pad, (int) ' ');
  strcatX (IW->hLines[0], "Dimensionality: ", 0);
  EncodeDimensionality (&(IW->hLines[0][strlen(IW->hLines[0])]), numDims,
			dimSizes);
  strcatX (IW->hLines[0], Zq(Z," (z)"," (r)"), 0);

  sprintf (IW->hLines[1], "  Records: %ld", maxRec + 1);
  pad = VAR_MORE_MENU_1st_HALF_LEN - strlen(IW->hLines[1]);
  if (pad > 0) CatNcharacters (IW->hLines[1], pad, (int) ' ');
  strcatX (IW->hLines[1], "     Variances: ", 0);
  EncodeVariances (&(IW->hLines[1][strlen(IW->hLines[1])]), recVary, numDims,
		   dimVarys);

  sprintf (IW->hLines[2], "   Extend: %ld (record%s)", extendRecs,
	   (extendRecs == 1 ? "" : "s"));
  pad = VAR_MORE_MENU_1st_HALF_LEN - strlen(IW->hLines[2]);
  if (pad > 0) CatNcharacters (IW->hLines[2], pad, (int) ' ');
  nAllocRecs = maxAllocRec + 1;
  sprintf (&(IW->hLines[2][strlen(IW->hLines[2])]),
	   "     Allocated: %ld (record%s)", nAllocRecs,
	   (nAllocRecs == 1 ? "" : "s"));
  format = (useFormat ? GetFormatEntry(Z,varN) : NULL);
  strcpyX (IW->hLines[3], "Pad value: ", 0);
  padBinary = AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)),
			      FatalError);
  status = CDFlib (GET_, Zq(Z,zVAR_PADVALUE_,rVAR_PADVALUE_), padBinary,
		   NULL_);
  switch (status) {
    case NO_PADVALUE_SPECIFIED: {
      static char defaultT[] = " (default)";
      int maxWidth = (IW->nColsTotal - 2) - strlen(IW->hLines[3]) -
		      strlen(defaultT);
      EncodeValuesFormat (dataType, numElems, padBinary,
			  &(IW->hLines[3][strlen(IW->hLines[3])]),
			  format, 0, maxWidth, EPOCH0_STYLE);
      strcatX (IW->hLines[3], defaultT, 0);
      break;
    }
    case CDF_OK: {
      int maxWidth = (IW->nColsTotal - 2) - strlen(IW->hLines[3]);
      EncodeValuesFormat (dataType, numElems, padBinary,
			  &(IW->hLines[3][strlen(IW->hLines[3])]),
			  format, 0, maxWidth, EPOCH0_STYLE);
      break;
    }
    default:
      ReportStatus (status);
      return FALSE;
  }
  FreeMemory (padBinary, FatalError);
  if (format != NULL) FreeMemory (format, FatalError);

  if (CDFformat == SINGLE_FILE) {
    sprintf (IW->hLines[4], " Indexing: %ld record%s, %ld entr%s",
	     nIndexRecords, (nIndexRecords == 1 ? "" : "s"),
	     nIndexEntries, (nIndexEntries == 1 ? "y" : "ies"));
  }
  else
    sprintf (IW->hLines[4], " Indexing: n/a");

  return TRUE;
}

/******************************************************************************
* CreateVar.
*     Returns FALSE is a fatal error is encountered - TRUE otherwise.  The
* variable not being created correctly is NOT considered a fatal error (eg.,
* an illegal name could have been specified).
******************************************************************************/

Logical CreateVar (Z, created)
Logical Z;
Logical *created;       /* Set to TRUE if a variable is created. */
{
  CDFstatus status;
  char varName[CDF_VAR_NAME_LEN+1];
  long recVary, dimVarys[CDF_MAX_DIMS];
  long numDims, dimSizes[CDF_MAX_DIMS];
  long dataType, numElems;
  long varNum;
  Logical done1, done2;
  static char labelOthers[15+CDF_VAR_NAME_LEN+1], delim;

  AOSs1 (trailerEnter1, "Enter: ________   Exit: ________  Help: ________")
  AOSs2A (trailerEnter2, "Enter: ________   Exit: ________", "Help: ________")
  AOSs2 (trailerSelect2, "Select: ________   Exit: ________", "Help: ________")

  static int exitCharsEnter[] = { ENTERkey_EDIT, EXITkey_FSI, HELPkey_FSI,
				  NUL };
  static int exitCharsSelect[] = { SELECTkey_EDIT, EXITkey_FSI, HELPkey_FSI,
				   NUL };

  static char *headerName[] = {
    "Enter name (with delimiters)...",
    "Syntax: <delim><char1><char2>...<charN><delim>",
    "Example: \"EPOCH\""
  };
  static char valueName[DELIMed_VAR_NAME_LEN+1];
  static char labelName[15+1];
  STATIC_ struct PromptWindowStruct PWname = {
    labelName, 7, 10, 60, 3, headerName, 1+CDF_VAR_NAME_LEN+1, valueName,
    1, trailerEnter1, exitCharsEnter, REFRESHkey_FSI, SOLkey_FSI,
    EOLkey_FSI, INSERTorOVERkey_FSI
  };
 
  static char *headerDim[] = {
    "Enter dimensionality...",
    "Syntax: <numDims>:[<dimSize1>,<dimSize2>,...,<dimSizeN>]",
    "Examples: 0:[], 1:[5], 2:[100,200], 3:[10,20,30]"
  };
  static char valueDim[MAX_DIMENSIONALITY_LEN+1];
  STATIC_ struct PromptWindowStruct PWdim = {
    labelOthers, 7, 10, 60, 3, headerDim, MAX_DIMENSIONALITY_LEN, valueDim,
    1, trailerEnter1, exitCharsEnter, REFRESHkey_FSI, SOLkey_FSI,
    EOLkey_FSI, INSERTorOVERkey_FSI
  };
 
  static char *headerVary[] = {
    "Enter variances...",
    "Syntax: <recVary>/<dimVary1><dimVary2>...<dimVaryN>",
    "Examples: T/, T/F, F/TF, T/TTT"
  };
  static char valueVary[MAX_VARIANCES_LEN+1];
  STATIC_ struct PromptWindowStruct PWvary = {
    labelOthers, 7, 10, 60, 3, headerVary, 0, valueVary, 1, trailerEnter1,
    exitCharsEnter, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
    INSERTorOVERkey_FSI
  };
 
  static char *headerDT[] = { "Select data type..." };
  static char *itemsDT[] = { DTiwSYMBOLS };
  static int iLineNsDT[] = { DTiwLINEnS };
  static int iColsDT[] = { DTiwCOLs };
  static int iLensDT[] = { DTiwLENs };
  STATIC_ struct ItemWindowStruct IWdt = {
    5, 23, 35, labelOthers, 1, headerDT, 7, itemsDT, 14, iLineNsDT, iColsDT,
    iLensDT, 7, 2, trailerSelect2, exitCharsSelect, REFRESHkey_FSI, FALSE
  };

  static char *headerNE[] = { "Enter number of elements (characters)..." };
  static char valueNE[MAX_NUMELEMS_LEN+1];
  STATIC_ struct PromptWindowStruct PWne = {
    NULL, 13, 37, 42, 1, headerNE, MAX_NUMELEMS_LEN, valueNE, 2, trailerEnter2,
    exitCharsEnter, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI,
    INSERTorOVERkey_FSI
  };

  /****************************************************************************
  * Set up.
  ****************************************************************************/

  *created = FALSE;

  EncodeKeyDefinitions (1, trailerEnter1,
			ENTERkey_EDIT, EXITkey_FSI, HELPkey_FSI);
  EncodeKeyDefinitions (2, trailerEnter2,
			ENTERkey_EDIT, EXITkey_FSI, HELPkey_FSI);
  EncodeKeyDefinitions (2, trailerSelect2,
			SELECTkey_EDIT, EXITkey_FSI, HELPkey_FSI);

  /****************************************************************************
  * Prompt for name.
  ****************************************************************************/

  strcpyX (PWname.value, "\"\"", DELIMed_VAR_NAME_LEN);
  sprintf (labelName, " New %cVariable ", Zq(Z,'z','r'));
  PromptWindow (NEWpw, &PWname, 1, (Logical) TRUE);
  for (;;) {
     if (EnterPW(&PWname,VARNAMEhelpID)) {
       if (DecodeDelimitedString(PWname.value,varName))
	 break;
       else
	 InputErrorWindow ("Illegal name (check delimiters).", FALSE);
     }
     else {
       strcpyX (varName, "", CDF_VAR_NAME_LEN);
       break;
     }
  }
  PromptWindow (DELETEpw, &PWname);
  if (strlen(varName) == 0) return TRUE;

  delim = PickDelimiter (varName, strlen(varName));
  sprintf (labelOthers, " %cVariable %c%s%c ", Zq(Z,'z','r'),
	   delim, varName, delim);

  /****************************************************************************
  * Prompt for data type/number of elements.
  ****************************************************************************/

  ItemWindow (NEWiw, &IWdt, 0);
  for (done1 = FALSE; !done1;) {
     if (EnterIW(&IWdt,VARDATATYPEhelpID)) {
       dataType = WhichDataType(&itemsDT[iLineNsDT[IWdt.itemN]]
					[iColsDT[IWdt.itemN]]);
       if (STRINGdataType(dataType)) {
	 strcpyX (PWne.value, "", MAX_NUMELEMS_LEN);
	 PromptWindow (NEWpw, &PWne, 0, (Logical) TRUE);
	 for (done2 = FALSE; !done2;) {
	    if (EnterPW(&PWne,VARNUMELEMShelpID)) {
	      if (sscanf(PWne.value,"%ld",&numElems) == 1)
		done2 = TRUE;
	      else
		InputErrorWindow ("Error decoding number of elements.", FALSE);
	    }
	    else {
	      dataType = -1;
	      done2 = TRUE;
	    }
	 }
	 PromptWindow (DELETEpw, &PWne);
       }
       else
	 numElems = 1;
       done1 = TRUE;
     }
     else {
       dataType = -1;
       done1 = TRUE;
     }
  }
  ItemWindow (DELETEiw, &IWdt);
  if (dataType == -1) return TRUE;

  /****************************************************************************
  * If zVariable, prompt for number/sizes of dimensions.  If rVariable,
  * determine number of dimensions.
  ****************************************************************************/

  if (Z) {
    strcpyX (PWdim.value, "", MAX_DIMENSIONALITY_LEN);
    PromptWindow (NEWpw, &PWdim, 0, (Logical) TRUE);
    for (;;) {
       if (EnterPW(&PWdim,ZDIMhelpID)) {
	 if (DecodeDimensionality(PWdim.value,&numDims,dimSizes))
	   break;
	 else
	   InputErrorWindow ("Illegal dimensionality.", FALSE);
       }
       else {
	 numDims = -1;
	 break;
       }
    }
    PromptWindow (DELETEpw, &PWdim);
    if (numDims == -1) return TRUE;
  }
  else {
    status = CDFlib (GET_, rVARs_NUMDIMS_, &numDims,
			   rVARs_DIMSIZES_, dimSizes,
		     NULL_);
    ReportStatus (status);
    if (StatusBAD(status)) return FALSE;
  }

  /****************************************************************************
  * Prompt for variances.
  ****************************************************************************/

  PWvary.maxChars = (int) (1 + 1 + numDims);
  strcpyX (PWvary.value, "", MAX_VARIANCES_LEN);
  PromptWindow (NEWpw, &PWvary, 0, (Logical) TRUE);
  for (;;) {
     if (EnterPW(&PWvary,VARVARYShelpID)) {
       if (DecodeVariances(PWvary.value,numDims,&recVary,dimVarys))
	 break;
       else 
	 InputErrorWindow ("Illegal variances.", FALSE);
     }
     else {
       recVary = -2;
       break;
     }
  }
  PromptWindow (DELETEpw, &PWvary);
  if (recVary == -2) return TRUE;

  /****************************************************************************
  * Create variable.
  ****************************************************************************/

  if (Z)
    status = CDFlib (CREATE_, zVAR_, varName, dataType, numElems, numDims,
				     dimSizes, recVary, dimVarys, &varNum,
		     NULL_);
  else
    status = CDFlib (CREATE_, rVAR_, varName, dataType, numElems, recVary,
				     dimVarys, &varNum,
		     NULL_);
  ReportStatus (status);
  if (StatusOK(status)) *created = TRUE;

  return TRUE;
}
