/*=========================================================================
*  File:  USERPR.FOR
*
* Purpose:
*	Example of user program for NORDRAD FORTRAN API.
*
*	Program flow:
*	- Store a product
*	- search for the product just stored
*	- read the first product returned by the search
*
* Preconditions:
*	A binary file suitable as NORDRAD data file must be available.
*	NORDRAD Host name or IP-address and a valid user id + 
*	password is also necessary.
*
*	On the working directory of the executing program the file
*	nraderr.h should be found.
*
*	The program will prompt for:
*		- NORDRAD Host name HOST
*		- ACL, (user id and password valid on HOST)
*		- API StoreProduct source file name
*		- API Search area name
*		- API Search destination file
*		- API GetProduct destination file
*
* History:
*	ver  date    who  rem
*	1.0  940930  ARg  Created 
*
* Compilation command (in a VAX/VMS environment):
*	cc userpr.c		-- produces userpr.obj
*
* Linking command (in a VAX/VMS environment):
*	link userpr/opt
*					-- produces userpr.exe
*
*	This link command uses an option file, userpr.opt
*	containing:
*	userpr, -
*	apiext, -
*	comp, -
*	decode, -
*	encode, -
*	export, -
*	fil, -
*	import, -
*	netcom, -
*	nradapi, -
*	nradutil, -
*	SYS$LIBRARY:UCX$IPC.OLB/LIBRARY,-
*	SYS$SHARE:VAXCRTL.EXE/SHARE
*
* In a UNIX environment the makefile userpr.mk can be used to produce
* the executable program. (make -f userpr.mk)
*=========================================================================*/
#ifdef VMS
#include <types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stat.h>
#include <in.h>
#include "api.h"
#include "utl.h"
#include "nradutil.h"
#else
#ifdef __MSDOS__
#include "api.h"
#include "utl.h"
#include "nradutil.h"
#endif
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
/* #include <sys/socketvar.h> */
#include <netinet/in.h>
#ifndef __MSDOS__
#include "api.h"
#include "utl.h"
#include "nradutil.h"
#endif
#endif

void BuildCurrTime(char *pTimeStr)
  {
  long lTimeInSec;
  struct tm *pTimeParts;
  INT16 iCentury, iMonth;
    
  time(&lTimeInSec);
  pTimeParts = localtime(&lTimeInSec);
  if (pTimeParts->tm_year < 70)
    iCentury = 2000 + pTimeParts->tm_year;
  else
    iCentury = 1900 + pTimeParts->tm_year;
  iMonth = pTimeParts->tm_mon+1;
  sprintf(pTimeStr,"%04d-%02d-%02d %02d:%02d:%02d.00",
                       iCentury,
		       iMonth,
                       pTimeParts->tm_mday,
                       pTimeParts->tm_hour, 
                       pTimeParts->tm_min,
                       pTimeParts->tm_sec);
  }	/* void BuildCurrTime(char *pTimeStr) */
/*----------------------------------------------------------
*  GetProdTypeStr - Convert Product type values from integers
*                   to string values to present for user.
*---------------------------------------------------------*/
char *GetProdTypeStr(unsigned char bVal,char *pProdTypeStr)
  {
  switch (bVal)
    {
     case  PROD_NONE:
       strcpy(pProdTypeStr,"NONE");
       break;
     case  PROD_FOREIGN:
       strcpy(pProdTypeStr,"FOREIGN");
       break;
     case  PROD_GEOMAP:
       strcpy(pProdTypeStr,"GEOMAP");
       break;
     case  PROD_RRSTATUS:
       strcpy(pProdTypeStr,"RRSTATUS");
       break;
     case  PROD_RRPPI_Z:
       strcpy(pProdTypeStr,"RRPPI_Z");
       break;
     case  PROD_RRPPI_W:
       strcpy(pProdTypeStr,"RRPPI_W");
       break;
     case  PROD_RRPPI_T:
       strcpy(pProdTypeStr,"RRPPI_T");
       break;
     case  PROD_RRCAPPI_Z:
       strcpy(pProdTypeStr,"RRCAPPI_Z");
       break;
     case  PROD_RRCAPPI_W:
       strcpy(pProdTypeStr,"RRCAPPI_W");
       break;
     case  PROD_RRCAPPI_T:
       strcpy(pProdTypeStr,"RRCAPPI_T");
       break;
     case  PROD_RRPSC_Z:
       strcpy(pProdTypeStr,"RRPSC_Z");
       break;
     case  PROD_RRPSC_W:
       strcpy(pProdTypeStr,"RRPSC_W");
       break;
     case  PROD_RRPSC_T:
       strcpy(pProdTypeStr,"RRPSC_T");
       break;
     case  PROD_RRETM_Z:
       strcpy(pProdTypeStr,"RRETM_Z");
       break;
     case  PROD_RRVMI_Z:
       strcpy(pProdTypeStr,"RRVMI_Z");
       break;
     case  PROD_RRVMI_W:
       strcpy(pProdTypeStr,"RRVMI_W");
       break;
     case  PROD_RRVMI_T:
       strcpy(pProdTypeStr,"RRVMI_T");
       break;
     case  PROD_RRHMI_Z:
       strcpy(pProdTypeStr,"RRHMI_Z");
       break;
     case  PROD_RRHMI_W:
       strcpy(pProdTypeStr,"RRHMI_W");
       break;
     case  PROD_RRHMI_T:
       strcpy(pProdTypeStr,"RRHMI_T");
       break;
     case  PROD_RRHMAX_Z:
       strcpy(pProdTypeStr,"RRHMAX_Z");
       break;
     case  PROD_RRHMAX_W:
       strcpy(pProdTypeStr,"RRHMAX_W");
       break;
     case  PROD_RRHMAX_T:
       strcpy(pProdTypeStr,"RRHMAX_T");
       break;
     case  PROD_RRVSI_Z:
       strcpy(pProdTypeStr,"RRVSI_Z");
       break;
     case  PROD_RRVSI_W:
       strcpy(pProdTypeStr,"RRVSI_W");
       break;
     case  PROD_RRVSI_T:
       strcpy(pProdTypeStr,"RRVSI_T");
       break;
     case  PROD_RRSRT_Z:
       strcpy(pProdTypeStr,"RRSRT_Z");
       break;
     default:
       sprintf(pProdTypeStr,"%d",bVal);
       break;
    }
  return pProdTypeStr;  
  }
  

/*----------------------------------------------------------
*  ShowPd  - Display specified ApiProduct data 
*              
*---------------------------------------------------------*/
void ShowPd(struct ApiProdDescrStruc  *pShowProdDescr)
  {
  char ProdTypeStr[30];
  /* ProdDescr  */
  
  printf("     Type=%s\n",
	 GetProdTypeStr(pShowProdDescr->bProd,ProdTypeStr));
  printf("     Time=%s\n",
	 pShowProdDescr->cTimeStr);  
  printf("     Resolution=%d\n",
	 pShowProdDescr->iResolution);  
  printf("     Area=%s\n",
	 pShowProdDescr->cArea);  
  switch (pShowProdDescr->bProd)
    {
    case  PROD_FOREIGN:
      printf("     Comment=%s\n",
	     pShowProdDescr->uData.Foreign.cComment);  
      break;  
    case  PROD_GEOMAP: 
      printf("     MapType=%d\n",
	     pShowProdDescr->uData.GeoMap.bMapType);  
      printf("     MapGraphic=%d\n",
             pShowProdDescr->uData.GeoMap.bMapGraphic);  
      break;
    case  PROD_RRSTATUS:
      printf("     Status node=%s\n",
              pShowProdDescr->uData.RrStatus.cStatusNode);  
      break;
    case  PROD_RRPPI_Z: 
    case  PROD_RRPPI_W: 
    case  PROD_RRPPI_T:
      break;  
    case  PROD_RRCAPPI_Z:
    case  PROD_RRCAPPI_W:
    case  PROD_RRCAPPI_T:
      printf("     Height=%d\n",
             pShowProdDescr->uData.RrType.uRr.RrCappi.iHeight);  
      break;
    case  PROD_RRPSC_Z:  
    case  PROD_RRPSC_W:  
    case  PROD_RRPSC_T:  
    case  PROD_RRETM_Z:  
    case  PROD_RRVMI_Z:  
    case  PROD_RRVMI_W:  
    case  PROD_RRVMI_T:
      break;  
    case  PROD_RRHMI_Z:  
    case  PROD_RRHMI_W:  
    case  PROD_RRHMI_T:  
      printf("     HmiWall=%d\n",
             pShowProdDescr->uData.RrType.uRr.RrHmi.bHmiWall);  
      break;  
    case  PROD_RRHMAX_Z: 
    case  PROD_RRHMAX_W: 
    case  PROD_RRHMAX_T:
      break;
    case  PROD_RRVSI_Z:  
    case  PROD_RRVSI_W:  
    case  PROD_RRVSI_T:
      printf("     VsiWall=%d\n",
             pShowProdDescr->uData.RrType.uRr.RrVsi.bVsiWall);  
      printf("     Start lat=%s\n",
              pShowProdDescr->uData.RrType.uRr.RrVsi.cStartLat);  
      printf("     Start long=%s\n",
              pShowProdDescr->uData.RrType.uRr.RrVsi.cStartLong);  
      printf("     End lat=%s\n",
              pShowProdDescr->uData.RrType.uRr.RrVsi.cEndLat);  
      printf("     End long=%s\n",
              pShowProdDescr->uData.RrType.uRr.RrVsi.cEndLong);  
      printf("     Vsi name=%s\n",
              pShowProdDescr->uData.RrType.uRr.RrVsi.cVsiName);  
      break;
    case  PROD_RRSRT_Z:
      printf("     Period.Days=%d\n",
              pShowProdDescr->uData.RrType.uRr.Duration.iDays);  
      printf("     Period.Secs=%d\n",
              pShowProdDescr->uData.RrType.uRr.Duration.iSecs);  
      break;
    }
  if ((pShowProdDescr->bProd >= PROD_RRPPI_Z) &&
      (pShowProdDescr->bProd <= PROD_RRSRT_Z))
    {  
    printf("     RrMode=%d\n",
             pShowProdDescr->uData.RrType.bRrMode);  
    }
  }	/* void ShowPd(struct ApiProdDescrStruc  *pShowProdDescr) */

/*----------------------------------------------------------
*  GetSearchAvi  - Fetch product descriptions stored sequently
*                  in a file, for instance a result file from
*                  a SearchProduct or Receive.
*---------------------------------------------------------*/
void GetSearchAvi(char *SearchDataFileStr,
		  struct ApiAviStruc *pBuf)
  {
  FILE	*pDataFile;
  int	iBytesRead,iAviSize;

  pDataFile = fopen(SearchDataFileStr,"r");
  if (pDataFile == NULL)
    {
    perror("File open error");
    printf("Filename: %s\n",SearchDataFileStr);
    return;
    }
  
  iAviSize  = sizeof(struct ApiAviStruc);       
  iBytesRead = fread(pBuf,
  		     1,
		     iAviSize,
		     pDataFile);
  if (iBytesRead != iAviSize)
     {
     perror("File read error");
     printf("Filename: %s\n",SearchDataFileStr);
     }	/* if (iBytesRead != iAviSize) */

   fclose(pDataFile);
  }	/* void GetSearchAvi(char *SearchDataFileStr,... */


/*----------------------------------------------------------
*  Init Net Activity on Socket.
*---------------------------------------------------------*/

main(int argc,char *argv[])
  {
   struct tm              	*pTime;
   struct ApiProdDescrStruc  	*pApiProdDescr;
   struct SearchCritStruc 	*pSearchCrit;
   struct ApiAviStruc     	*pApiAvi;
   struct ApiAviStruc     	ApiAvi;
   struct ApiProdDescrStruc  	ApiProdDescr;
   struct SearchCritStruc 	SearchCrit;
   struct ErrorDataStruc  	ErrMsg;
   char   DestFileNameStr[MAX_FILE_NAME_SIZE];
   char   SourceFileNameStr[MAX_FILE_NAME_SIZE];
   char   SearchLimFileStr[MAX_FILE_NAME_SIZE];
   char   AccessCtrlStr[MAX_ACCESSCTRL_SIZE];
   char   HostNameStr[60];
   char   TmpStr[80];
   char	  *pTmpStr;
   INT32  iRc, iErrInd;
   INT32  iWaitTime = 120;
#ifdef __BORLANDC__
      extern unsigned _stklen = 10*1024;
#endif
/* extern	int	errno; */


/*---------------------------------
*	Main program
*---------------------------------*/

	/* Init the error code table */

	UtlInitErrMsgTab();

	pApiProdDescr  = &ApiProdDescr;
	pSearchCrit = &SearchCrit;
	pApiAvi	= &ApiAvi;
	pTmpStr = &TmpStr;

	printf ("\nUSERPR simple test of UNIX API  ");
	printf ("v 1.0 94-09-30/ARg\n");

	printf ("For all API calls.\n");
	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	   printf ("Please enter NORDRAD Host name or IP address:");
	   pTmpStr = gets(TmpStr);
	   }	/* while (strlen(pTmpStr) == 0) */

	strcpy(HostNameStr,pTmpStr);

	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	  printf ("Please enter ACL Access string:");
	  pTmpStr = gets(TmpStr);
	  }	/* while (strlen(pTmpStr) == 0) */
	strcpy(AccessCtrlStr,pTmpStr);

/*  --------------------------
*  Store a product in NORDRAD
*  --------------------------*/

	printf ("Preparing for STORE.\n");
	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	  printf ("Please enter Source file name:");
	  pTmpStr = gets(TmpStr);
	  }	/* while (strlen(pTmpStr) == 0) */
	strcpy(SourceFileNameStr,pTmpStr);

	/*  Make a 'Foreign' product descriptor */

	ApiProdDescr.bProd	= PROD_FOREIGN;
        memset(ApiProdDescr.uData.Foreign.cComment,0,
               sizeof(ApiProdDescr.uData.Foreign.cComment));
	strcpy(ApiProdDescr.uData.Foreign.cComment,"Comment string");

	BuildCurrTime(ApiProdDescr.cTimeStr);

	memset(ApiProdDescr.cArea,0,sizeof(ApiProdDescr.cArea));
        strcpy(ApiProdDescr.cArea,"DUMMY");

	ApiProdDescr.iResolution = 1000;
	
	/*  Call to StoreProduct */

	printf ("Calling StoreProduct\n");
	printf ("        AC: %s<\n",AccessCtrlStr);
	printf ("      HOST: %s<\n",HostNameStr);
	printf ("SOURCEFILE: %s<\n",SourceFileNameStr);
	printf (" PRODUCT ----->\n");
	ShowPd(&ApiProdDescr);

	StoreProduct(AccessCtrlStr,
		     HostNameStr,
		     pApiProdDescr,
		     SourceFileNameStr,
		     iWaitTime,
		     &iRc);

	printf("Result for StoreProduct\n");

	if (iRc != APIOK)
	    {
	    iErrInd = UtlSearchErrMsgTab(iRc,
					 ErrMsg.ConstName,
					 ErrMsg.ErrTxt);
	    if (iErrInd >= 0)
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld ",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("Const=%s\n  Msg=%s \n\n",
		      ErrMsg.ConstName,
		      ErrMsg.ErrTxt);
	       }
	    else
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld\n",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("No error message for this error code\n\n");
	       }
	    }
        else
	    {
	    printf("Status = APIOK\n");
	    }

/*  ----------------------
*  Search for the product
*  ----------------------*/

	printf ("Preparing for SEARCH.\n");
	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	  printf ("Please enter Search limit file name:");
	  pTmpStr = gets(TmpStr);
	  }	/* while (strlen(pTmpStr) == 0) */

	strcpy(SearchLimFileStr,pTmpStr);

	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	  printf ("Please enter Search destination file name:");
	  pTmpStr = gets(TmpStr);
	  }	/* while (strlen(pTmpStr) == 0) */

	strcpy(DestFileNameStr,pTmpStr);
	
        SearchCrit.bName = 4;	/* NameExact */ 
        SearchCrit.bTime = 0; 	/* TimeNone  */
        SearchCrit.bArea = 0; 	/* AreaNone  */
        SearchCrit.bResolution = 0;	/* ReolutionNone */

	printf ("Calling SearchProduct\n");
	printf ("        AC: %s<\n",AccessCtrlStr);
	printf ("      HOST: %s<\n",HostNameStr);
	printf ("      SLIM: %s<\n",SearchLimFileStr);
	printf ("  DESTFILE: %s<\n",DestFileNameStr);
	printf ("   SC.NAME: %d<\n", SearchCrit.bName);
	printf ("   SC.TIME: %d<\n", SearchCrit.bTime);
	printf ("   SC.AREA: %d<\n", SearchCrit.bArea);
	printf ("SC.RESOLUTION: %d<\n", SearchCrit.bResolution);
	printf (" PRODUCT ----->\n");
	ShowPd(&ApiProdDescr);

	SearchProduct(AccessCtrlStr,
		      HostNameStr,
		      pApiProdDescr,
		      pSearchCrit,
		      SearchLimFileStr,
                      DestFileNameStr,
		      iWaitTime,
		      &iRc);
		      
	printf("Result for SearchProduct\n");

	if (iRc != APIOK)
	    {
	    iErrInd = UtlSearchErrMsgTab(iRc,
					 ErrMsg.ConstName,
					 ErrMsg.ErrTxt);
	    if (iErrInd >= 0)
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld ",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("Const=%s\n  Msg=%s \n\n",
		      ErrMsg.ConstName,
		      ErrMsg.ErrTxt);
	       }
	    else
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld\n",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("No error message for this error code\n\n");
	       }
	    }
        else
	    {
	    printf("Status = APIOK\n");
	    }

        /* Read the first returned product */
	
	GetSearchAvi(DestFileNameStr,
		     (struct ApiAviStruct *) &ApiAvi);

/*  ---------------
*  	Read the  product
*  --------------- */

	printf ("Preparing for GET.\n");
	pTmpStr = "";

	while (strlen(pTmpStr) == 0)
	  {
	  printf ("Please enter GetProduct destination file name:");
	  pTmpStr = gets(TmpStr);
	  }	/* while (strlen(pTmpStr) == 0) */

	strcpy(DestFileNameStr,pTmpStr);

	printf ("Calling GetProduct\n");
	printf ("        AC: %s<\n",AccessCtrlStr);
	printf ("      HOST: %s<\n",HostNameStr);
	printf ("  DESTFILE: %s<\n",DestFileNameStr);
	printf ("IN_AVI.NODE: %s<\n",ApiAvi.cNodeName);
	printf (" IN_AVI.PD ----->\n");
	ShowPd(&ApiProdDescr);

	GetProduct(AccessCtrlStr,
		   HostNameStr,
		   pApiAvi,
		   DestFileNameStr,
		   iWaitTime,
		   &iRc);

	printf("Result for GetProduct\n");

	if (iRc != APIOK)
	    {
	    iErrInd = UtlSearchErrMsgTab(iRc,
					 ErrMsg.ConstName,
					 ErrMsg.ErrTxt);
	    if (iErrInd >= 0)
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld ",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("Const=%s\n  Msg=%s \n\n",
		      ErrMsg.ConstName,
		      ErrMsg.ErrTxt);
	       }
	    else
	       {
	       printf("Status(hex)=%lx, Status(dec)=%ld\n",
		      (INT32) iRc,
		      (INT32) iRc);
	       printf("No error message for this error code\n\n");
	       }
	    }
        else
	    {
	    printf("Status = APIOK\n");
	    }

	printf ("\n\nOK, that was it!\n");
}	/* main(int argc,char *argv[]) */

