/*********************************************************************
*
*  Task DBX
*
* Task to extract part of a complex data base
*
* CODE 0: Extract Amplitude
* CODE 1: Extract Phase
* CODE 2: Extract Real Part
* CODE 3: Extract Imaginary Part
*
* Datatypes X_Data and TX_Data are allowed
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <signal.h>

#include "TISAN.H"

char TMPFILE[_MAX_PATH];  /* Must be global to be visible to BREAKREQ */

main(argc,argv)
short argc;
char *argv[];
   {
   char INFILE[_MAX_PATH], OUTFILE[_MAX_PATH];
   char BUFFER[sizeof(struct TXData)], TMPTYPE;
   double TCNT=0.;
   double VALUE, TIME;
   short ERRFLAG=0, FLAG;
   FILE *INSTR, *OUTSTR;
   struct complex Z;
   struct FILEHDR FileHeader;
   struct RData  *RDataPntr;
   struct TRData *TRDataPntr;
   struct XData  *XDataPntr;
   struct TXData *TXDataPntr;

   signal(SIGINT,BREAKREQ);   /* Setup ^C Interrupt handler */

   if (Ztskinit("DBX",argv[0])) Zexit(1);  /* Initialize task */

   if ((CODE < 0) || (CODE > 3))
      {
      Zencode(10,"DBX     : CODE adverb out of range (%d)\n",CODE);
      Zexit(1);
      }

   ZBuildFileName(M_inname,INFILE);     /* Build filenames */
   ZBuildFileName(M_outname,OUTFILE);
   ZBuildFileName(M_tmpname,TMPFILE);

   Zencode(2,"DBX     : Opening Input File '%s'\n",INFILE);
   if (((INSTR = Zopen(INFILE,O_readb)) == NULL) ||
       (!Zgethead(INSTR,&FileHeader))) Zexit(1);

/*
** Select proper data type for new file
*/
   switch (TMPTYPE = FileHeader.type)
      {
      case X_Data:
         FileHeader.type = R_Data;
         break;
      case TX_Data:
         FileHeader.type = TR_Data;
         break;
      default:
         Zencode(10,"DBX     : Invalid File Type.\n");
         Zexit(1);
      }

   Zencode(2,"DBX     : Opening Scratch File '%s'\n",TMPFILE);
   if ((OUTSTR = Zopen(TMPFILE,O_writeb)) == NULL) Zexit(1);

   if (Zputhead(OUTSTR,&FileHeader))
      {
      ERRFLAG=1;
      goto EXIT;
      }
   FileHeader.type = TMPTYPE; /* Restore currnt type */

   RDataPntr =  (struct RData *)BUFFER;        /* Data Structure Pointers */
   TRDataPntr = (struct TRData *)BUFFER;
   XDataPntr =  (struct XData *)BUFFER;
   TXDataPntr = (struct TXData *)BUFFER;

   while (Zread(INSTR,BUFFER,FileHeader.type))
      {
      switch (FileHeader.type)   /* Interpret input buffer */
         {
         case X_Data:
            Z.x = XDataPntr->z.x;
            Z.y = XDataPntr->z.y;
            FLAG = XDataPntr->f;
            break;
         case TX_Data:
            TIME =  TXDataPntr->t;
            Z.x = TXDataPntr->z.x;
            Z.y = TXDataPntr->z.y;
            break;
         }

      switch (CODE)    /* Select action */
         {
         case 0:   /* Amplitude */
            VALUE = cabs(Z);
            break;
         case 1:   /* Phase */
            VALUE = atan2(Z.y,Z.x);
            break;
         case 2:   /* Real Part */
            VALUE = Z.x;
            break;
         case 3:   /* Imaginary Part */
            VALUE = Z.y;
            break;
         }

      switch (FileHeader.type)  /* Write by data type */
         {
         case X_Data:                      /* Complex time series maps */
            RDataPntr->y = VALUE;  /* into real time sderies   */
            RDataPntr->f = FLAG;
            Zwrite(OUTSTR,BUFFER,R_Data);
            break;
         case TX_Data:                     /* Complex time labeled maps */
            TRDataPntr->y = VALUE; /* into real time labeled    */
            TRDataPntr->t = TIME;
            Zwrite(OUTSTR,BUFFER,TR_Data);
            break;
         }
      if (ferror(OUTSTR))
         {
         ERRFLAG = 1;
         break;
         }
      ++TCNT;
      } /* End WHILE */

   if (ferror(INSTR)) ERRFLAG = 1;
   if (!ERRFLAG) Zencode(2,"DBX     : %G Data Points Processed\n",TCNT);

EXIT:
   Zclose(INSTR);
   Zclose(OUTSTR);
   ERRFLAG = Znameout(OUTFILE,TMPFILE,ERRFLAG);
   Zexit(ERRFLAG);
   }

/***************************************************************
**
** Process ^C Interrupt
*/
short BREAKREQ()
   {
   fcloseall();
   unlink(TMPFILE);
   Zexit(3);
   }