/****************************************************************************/
/* Summary  : Standalone (PicoDOS, Linux, Cygwin) version of decode command */
/* Filename : decodeMain.c                                                  */
/* Author   : Robert Herlien (rah)					    */
/* Project  : BEDS (Benthic Event Detection System			    */
/* Revision : 1.0							    */
/* Created  : 2/6/2013							    */
/****************************************************************************/
/* Modification History:						    */
/* 6feb2013 rah - created						    */
/****************************************************************************/

#include <mbariTypes.h>		/* MBARI type definitions		*/
#include <mbariConst.h>		/* MBARI constants			*/
#include <beds.h>		/* BEDS general definitions		*/
#include <decode.h>		/* Definitions to decode BEDS files	*/
#include <decodeMain.h>
#ifdef CFX
#include <fileUtils.h>		/* BEDS file I/O definitions		*/
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>


/********************************/
/*	External Data		*/
/********************************/

Extern MBool	printDataRecs;
Extern MBool	totalsOnly;
Extern MBool	pressOnly;
Extern MBool	sysRecOnly;
Extern double	epsilon;


/********************************/
/*	Module Local Data	*/
/********************************/

typedef struct
{
    Flt32	a;
    Flt32	b;
    char	*units;
} ADConversion;

MLocal ADConversion adConv[] =
{ {12.11, 0.0, "Batt Volts"},  {12.11, 0.0, "Batt Volts"}, 
  {50.0, 12.5, "bar"}, {50.0, 12.5, "psia"},
  {100.0, 50.0, "degC"}, {47.175, 23.82, "%"},
  {1.0, 0.0, "Volts"}
};

#ifndef CFX

/************************************************************************/
/* Function    : adcEngValue						*/
/* Purpose     : Convert ADC counts into final Engineering value with units*/
/* Inputs      : Channel number, ADC Count				*/
/* Outputs     : Voltage/Pressure/Temp/RH as Flt32, units as string	*/
/************************************************************************/
Flt32 adcEngValue(Nat16 chan, Nat16 counts, char **unitp)
{
    if (chan >= NumberOf(adConv))
	chan = HUMIDITY_CHAN + 1;

   if (unitp != NULL)
       *unitp = adConv[chan].units;

   return((adConv[chan].a * RAW_TO_VOLTS(counts)) - adConv[chan].b);

} /* adcEngValue() */

#endif

/************************************************************************/
/* Function    : getMotWord						*/
/* Purpose     : Get 16 bit word in Motorola (big endian) format	*/
/* Inputs      : Ptr to word						*/
/* Outputs     : 16 bit value						*/
/************************************************************************/
MLocal Nat16 getMotWord(Byte *p)
{
    return(((*p << 8) | p[1]) & 0xffff);
}

/************************************************************************/
/* Function    : getMotLong						*/
/* Purpose     : Get 32 bit long in Motorola (big endian) format	*/
/* Inputs      : Ptr to word						*/
/* Outputs     : 32 bit value						*/
/************************************************************************/
MLocal Nat32 getMotLong(Byte *p)
{
    return(((Nat32)getMotWord(p) << 16) | getMotWord(p+2));
}

/************************************************************************/
/* Function    : readWord						*/
/* Purpose     : Get 16 bit word from input stream in big endian format	*/
/* Inputs      : FILE Ptr						*/
/* Outputs     : 16 bit value						*/
/************************************************************************/
Nat16 readWord(FILE *fp)
{
    Byte	b[2];

    fread(b, 2, 1, fp);
    return(getMotWord(b));
}

/************************************************************************/
/* Function    : readLong						*/
/* Purpose     : Get 32 bit long from input stream in big endian format	*/
/* Inputs      : FILE Ptr						*/
/* Outputs     : 32 bit value						*/
/************************************************************************/
Nat32 readLong(FILE *fp)
{
    Byte	b[4];

    fread(b, 4, 1, fp);
    return(getMotLong(b));
}

/************************************************************************/
/* Function    : usage							*/
/* Purpose     : Print usage message					*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
MLocal void usage(void)
{
    printf("\nDECODE [-d] [-t] [-s] [-p] [-e epsilon] <filename>\tDecode a BEDS binary file\n"
	   "\t[-d] Print full data records (else prints summaries each second)\n"
	   "\t[-t] Print only totals, not individual records (except header)\n"
	   "\t[-s] Print only System Records\n"
	   "\t[-p] Print only Pressure Records\n"
	   "\t[-e epsilon] Use epsilon to validate quaternions (default 0.05)\n" );
    printf("\nDECODE [-h]\tPrint this message\n");
}

#ifdef CFX			/* Standalone PicoDOS version		*/

/************************************************************************/
/* Function    : main							*/
/* Purpose     : Main entry point					*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
int main(int argc, char **argv)
{
    int		i, maxOpt = 0;

    for (i = 1; i < argc; i++)
    {
	if ((argv[i][0] == '-') || (argv[i][0] == '/'))
	{
	    if (toupper(argv[i][1]) == 'H')
	    {
		usage();
		exit(0);
	    }
	    else if (toupper(argv[i][1]) == 'D')
		printDataRecs = TRUE;
	    else if (toupper(argv[i][1]) == 'T')
		totalsOnly = TRUE;
	    else if (toupper(argv[i][1]) == 'P')
		pressOnly = TRUE;
	    else if (toupper(argv[i][1]) == 'S')
		sysRecOnly = TRUE;

	    maxOpt = i;
	}
    }

    maxOpt++;
    if (maxOpt >= argc)
    {
	printf("No input file specified");
	usage();
    }

    for (i = maxOpt; i < argc; i++)
	if (!dirScan(argv[i], dsDecodeFile, NULL))
		exit(0);

    return(0);
}

#else			/* Linux or Cygwin version			*/

/************************************************************************/
/* Function    : main							*/
/* Purpose     : Main entry point					*/
/* Inputs      : None							*/
/* Outputs     : None							*/
/************************************************************************/
int main(int argc, char **argv)
{
    int		c;

    while ((c = getopt(argc, argv, "dtpshe:")) > 0)
	switch(c)
	{
	  case 'd':
	      printDataRecs = TRUE;
	      break;
	  case 't':
	      totalsOnly = TRUE;
	      break;
	  case 'p':
	      pressOnly = TRUE;
	      break;
	  case 's':
	      sysRecOnly = TRUE;
	      break;
	  case 'e':
	      epsilon = atof(optarg);
	      break;
 	  case 'h':
	      usage();
	      exit(0);
	}

    
    if (optind >= argc)
    {
	printf("No input file specified");
	usage();
    }
    else while (optind < argc)
    {
	decodeFile(argv[optind]);
	optind++;
    }

    return(0);
}

#endif
