/* ************************************
 * *                                  *
 * *         IRIS  System             *
 * * Raw Product Data Type Conversion *
 * *                                  *
 * ************************************
 * File: iris/examiners/data_convert.c
 * 
 *           COPYRIGHT (c) 1998, 1999, 2000, 2001  BY
 *       SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED. 
 */
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sigtypes.h"
#include "dsp.h"
#include "headers.h"
#include "product.h"
#include "iris_task.h"
#include "ingest.h"
#include "setup.h"

#include "user_lib.h"
#include "dsp_lib.h"
#include "misc_lib.h"

#include "examiners.h"

/* Function prototypes used just within this file
 */

static void usage( void );

static void convert_raw
  (struct product_hdr *phead_a,
   SINT4 iSize_a );

/* ====================================================================
 * This is a program to print out product data.
 */
int main( int iargc_a, char *sargv_a[] )
{
  MESSAGE istatus;
  struct product_hdr *pphead;
  SINT4 isize, ichannel;
  SINT4 ii;
  char spath[PATHNAME_SIZE], sproductfile[FILENAME_SIZE];

  UINT2 lok;

  /* -------------------------------------------------------------------- */

  setlocale( LC_ALL, "" );

  if (iargc_a < 2)
     usage();

  for( ii=1 ; ii<iargc_a ; ii++ )
    {
      int ilen = strlen( sargv_a[ii] ) - 1 ;
      if( (sargv_a[ii][0] == '-' || sargv_a[ii][0] == '/') && (ilen>0) )
        {
          if( 0 == strncmp( &sargv_a[ii][1], "help", ilen ) )
             usage();
          else
             usage();
        }
    }

  set_product_dir( PROD_RAW, spath ) ;
  strcat( spath, sargv_a[1] );
  strcpy( sproductfile, sargv_a[1] );

  istatus = imapopen( spath, TRUE, (void **)&pphead, &isize, &ichannel );
  if ( istatus != SS_NORMAL )
    {
      sig_signal( istatus );
      exit(EXIT_FAILURE);
    }

  /* First do some checking based on the product header: */
  show_product( pphead, NULL, isize, sproductfile, &lok );
  if (!lok) exit(EXIT_FAILURE);

  if ( pphead->pcf.iptype != PROD_RAW) 
    {
      printf("data_convert requires a raw product.\n");
      exit(EXIT_FAILURE);
    }

  convert_raw( pphead, isize ) ;

  istatus = imapclose( pphead, isize, ichannel );

  return EXIT_SUCCESS;
}


static void usage( void )
{
  fprintf( stderr, "Usage data_convert [-help] filename\n");
  exit(EXIT_FAILURE) ;
}

/* ==============================================================
 * Print information and convert RAW product.  Entered with a pointer
 * to the beginning (first 6144-byte record) of the full product.
 */
static void convert_raw
  (struct product_hdr *phead_a,
   SINT4 iFileSize_a )
{
#define RAYSIZE MAX_BINS
  UINT2 iOldDType, iNewDType ;
  struct dsp_data_mask DataMask;
  SINT4 iIndex, iFilePos, iLastSweep, iDataCount;
  struct ingest_header *inghdr ;


  /* The first two "records" of the product consist of a product
   * header structure and an ingest header structure.  Each is
   * padded out to one record.
   */
  inghdr = (struct ingest_header *)(((UINT1*)phead_a) + TAPE_RECORD_LEN) ;

  /* Make sure that this file really looks like a raw product.  Check
   * the ID's in the product and ingest headers.
   */
  if((phead_a->hdr.id    != ST_PRODUCT_HDR) ||
     (inghdr->hdr.id     != ST_INGEST_HDR ) ||
     (inghdr->tcf.hdr.id != ST_TASK_CONF  ) ) {
       printf( "File headers contain invalid ID's\n" ) ;
     }

  /* Print out a few values from the ingest header.
   */
  printf( "Information from INGEST Header\n" ) ;
  printf( "------------------------------\n" ) ;

  showsummary( inghdr ) ;

  /* Count up the number of parameters that were recorded.  This is
   * needed in order to skip through the sweeps properly.
   */
  DataMask = inghdr->tcf.dsp.DataMask ;
  iDataCount = 0;
  for (iIndex=0; iIndex<NUM_DEFINED_DATA; iIndex++)
    {
      if (lDspMaskTest( &DataMask, iIndex )) iDataCount++;
    }

  /* Check which moment and starting range should be used.
   */
  askmoments( "Data to convert from: ", &DataMask, &iOldDType, DB_KDP ) ;
  {
    struct dsp_data_mask AllMask;
    memset( &AllMask, -1, sizeof(AllMask) );
    askmoments( "Data to convert to: ", &AllMask, &iNewDType, DB_PHIDP ) ;
  }

  if (lDspMaskTest( &inghdr->tcf.dsp.DataMask, iNewDType ))
    {
      printf( "Sorry, new data type is already in the file.\n" );
      return;
    }
  DspMaskClear( &DataMask, iOldDType );
  DspMaskSet  ( &DataMask, iNewDType );

  inghdr->tcf.dsp.DataMask = DataMask;
  PutRawPsiMask( &phead_a->pcf.psi.raw, &DataMask );

  /* Loop through all the data records of the product.  Find the first
   * one for each sweep and convert the data types.
   */
  iFilePos = 2*TAPE_RECORD_LEN;
  iLastSweep = 0;
  while( iFilePos<iFileSize_a )
    {
      struct raw_prod_bhdr *pBHdr;
      pBHdr = (struct raw_prod_bhdr *)(((UINT1*)phead_a) + iFilePos ) ;
      if (iLastSweep != pBHdr->isweep)
	{
	  struct ingest_data_header *pIngestList, *pOneIngest;
	  iLastSweep = pBHdr->isweep;
	  pIngestList = (struct ingest_data_header *)(void*)(pBHdr + 1);
	  for (iIndex=0; iIndex<iDataCount; iIndex++)
	    {
	      pOneIngest = &pIngestList[iIndex];
	      if (pOneIngest->idata == iOldDType)
		{
		  pOneIngest->idata = iNewDType;
		}
	    }
	}
      iFilePos += TAPE_RECORD_LEN;
    }
  printf( "Conversion completed.\n" );

}

