/*********************************************************************
*
*  Task DBLIST
*
* I List the contents of a data base, including flagged values.
*
* CODE 0: Simple Single Column Output
* CODE 1: Multiple Column Output in FACTOR Columns
* CODE 2: Tabular Output with FACTOR columns
*
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <io.h>
#include <time.h>
#include <dos.h>
#include <process.h>
#include <ctype.h>
#include <signal.h>

#include "TISAN.H"

short FPERROR(void);
void BombOff(int);

struct FILESTRUCT File;

main(argc,argv)
int argc;
char *argv[];
   {
   char DataBuffer[sizeof(struct TXData)];        /* Largest Data Structure */
   char szInputFileName[_MAX_PATH];
   double Rval, DataTime, TimeCount=0.;
   struct complex Zval;
   int iColumnCount, iColBaseCount, iErrorValue=0;
   BOOL bTimeSequential = FALSE;
   struct FILEHDR FileHeader;
   struct RData  *RDataPntr;
   struct TRData *TRDataPntr;
   struct TXData *TXDataPntr;
   struct XData  *XDataPntr;
     
   signal(SIGINT,BREAKREQ);
   signal(SIGFPE,FPERROR);  /* Setup Floating Point Error Trap */

   if (zTaskInit("DBLIST",argv[0])) Zexit(1);
/*
** Check CODE value if applicable
*/
   if ((CODE < 0) || (CODE > 2)) CODE = 0;
   iColumnCount = Max(FACTOR,1);

   ZBuildFileName(M_inname,szInputFileName);
   zMessage(2,"DBLIST  : Opening Input File '%s'\n",szInputFileName);
   if (zFileOpen(&File, szInputFileName, OF_READ, 0)) Zexit(1);
   if (!zGetHeader(&File,&FileHeader)) BombOff(1);

   switch (FileHeader.type)
      {
      case R_Data:
         bTimeSequential = TRUE;
         zMessage(3,"DBLIST  : Real Time Series File\n");
         break;
      case TR_Data:
         zMessage(3,"DBLIST  : Real Time Stamped Data File\n");
         break;
      case X_Data:
         bTimeSequential = TRUE;
         zMessage(3,"DBLIST  : Complex Time Series File\n");
         break;
      case TX_Data:
         zMessage(3,"DBLIST  : Complex Time Stamped Data File\n");
         break;
      default:
         zMessage(10,"DBLIST  : Invalid file type\n");
         BombOff(1);
      }

   if (bTimeSequential && (TRANGE[0] < TRANGE[1]))
      {
      TimeCount = floor((TRANGE[0] - FileHeader.b) / FileHeader.m);
      if (TimeCount > 0.)
         {
         if (zIndexedRead(&File, (long)(TimeCount - 1.),
                          DataBuffer, FileHeader.type))
            BombOff(1);
         }
      else
         TimeCount = 0.;
      }

   if (!strlen(YFORMAT)) strcpy(YFORMAT,"%G "); /* Default output formats */
   if (!strlen(TFORMAT)) strcpy(TFORMAT,"%G ");

   if (strlen(TITLE))  zMessage(4,"DBLIST  : %s\n",TITLE);
   if (strlen(TLABEL)) zMessage(4,"DBLIST  : %s\n",TLABEL);
   if (strlen(YLABEL)) zMessage(4,"DBLIST  : %s\n",YLABEL);

   RDataPntr =  (struct RData *)DataBuffer;
   TRDataPntr = (struct TRData *)DataBuffer;
   XDataPntr =  (struct XData *)DataBuffer;
   TXDataPntr = (struct TXData *)DataBuffer;

   iColumnCount = iColBaseCount = (int)FACTOR;
   zMessage(4,"DBLIST  : ");
   while (!zIndexedRead(&File, -1L, DataBuffer, FileHeader.type))
      {
      switch (FileHeader.type)
         {
         case R_Data:
            Rval = RDataPntr->y;
            DataTime = TimeCount*FileHeader.m + FileHeader.b;
            ++TimeCount;
            break;
         case TR_Data:
            Rval = TRDataPntr->y;
            DataTime = TRDataPntr->t;
            break;
         case X_Data:
            Zval = XDataPntr->z;
            DataTime = TimeCount*FileHeader.m + FileHeader.b;
            ++TimeCount;
            break;
         case TX_Data:
            Zval = TXDataPntr->z;
            DataTime = TXDataPntr->t;
            break;
         }
      if ((((DataTime <= TRANGE[1]) && (DataTime >= TRANGE[0])) ||
          (TRANGE[0] >= TRANGE[1])))
         {
         switch (CODE)
            {
            case 0: /* Simple 2-Columnar Format */
               switch (FileHeader.type)
                  {
                  case R_Data:
                  case TR_Data:
                     zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Rval);
                     break;
                  case X_Data:
                  case TX_Data:
                     zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Zval.x);
                     zMessage(5,YFORMAT,Zval.y);
                     break;
                  }
               zMessage(5,"\nDBLIST  : ");
               break;
            case 1:
               switch (FileHeader.type)
                  {
                  case R_Data:
                  case TR_Data:
                     zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Rval);
                     break;
                  case X_Data:
                  case TX_Data:
                     zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Zval.x);
                     zMessage(5,YFORMAT,Zval.y);
                     break;
                  }
               if (!(--iColumnCount))
                  {
                  zMessage(5,"\nDBLIST  : ");
                  iColumnCount = iColBaseCount;
                  }
               break;
            case 2:
               switch (FileHeader.type)
                  {
                  case R_Data:
                  case TR_Data:
                     if (iColumnCount == iColBaseCount)
                        zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Rval);
                     break;
                  case X_Data:
                  case TX_Data:
                     if (iColumnCount == iColBaseCount)
                        zMessage(5,TFORMAT,DataTime);
                     zMessage(5,YFORMAT,Zval.x);
                     zMessage(5,YFORMAT,Zval.y);
                     break;
                  }
               if (!(--iColumnCount))
                  {
                  zMessage(5,"\nDBLIST  : ");
                  iColumnCount = iColBaseCount;
                  }
               break;
            }  /* End Switch */
         } /* End IF */
      if ((TRANGE[0] < TRANGE[1]) && bTimeSequential &&
          (DataTime  > TRANGE[1])) break;
      } /* End WHILE */
   if (File.iEoF < 0) iErrorValue = 1;
   zMessage(5,"\nDBLIST  : \n");

   iErrorValue = zFileClose(&File, TRUE) ? 1 : iErrorValue ;
   Zexit(iErrorValue);
   }

/***************************************************************
**
** Process ^C Interrupt
*/
short BREAKREQ()
   {
   zFileClose(&File, TRUE);
   Zexit(3);
   }

short FPERROR()
   {
   zFileClose(&File, TRUE);
   Zexit(1);
   }

void BombOff(i)
int i;
   {
   zFileClose(&File, TRUE);
   Zexit(i);
   }