#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

FILE *fp;
char filename[100];

unsigned long long ByteSwapLL (unsigned long long nLongLongNumber)
{
   union u {
            unsigned long long vi;
            unsigned long l[sizeof(unsigned long long)/2];
            unsigned char c[sizeof(unsigned long long)];
           }; 
   union u un; 
   union u swap;
   
   un.vi = nLongLongNumber; 
   swap.l[0] = un.l[0];
   un.c[0] = un.c[7];
   un.c[1] = un.c[6];
   un.c[2] = un.c[5];
   un.c[3] = un.c[4];
   un.c[4] = swap.c[3];
   un.c[5] = swap.c[2];
   un.c[6] = swap.c[1];
   un.c[7] = swap.c[0];
   return (un.vi); 
}

unsigned long ByteSwapL (unsigned long nLongNumber)
{
   union u {
            unsigned long vi;
            unsigned int i[sizeof(unsigned long)/2];
            unsigned char c[sizeof(unsigned long)];
           }; 
   union u un; 
   union u swap;
   
   un.vi = nLongNumber; 
   swap.i[0] = un.i[0];
   un.c[0] = un.c[3];
   un.c[1] = un.c[2];
   un.c[2] = swap.c[1];
   un.c[3] = swap.c[0];
   return (un.vi); 
}

unsigned short ByteSwapS (unsigned short nShortNumber)
{
   union u {
            unsigned short s;
            unsigned char c[sizeof(unsigned short)];
           }; 
   union u un; 
   union u swap;
   
   un.s = nShortNumber; 
   swap.s = nShortNumber;
   un.c[0] = un.c[1];
   un.c[1] = swap.c[0];
   return (un.s); 
}

/*
unsigned long ByteSwap1 (unsigned long nLongNumber)
{
   union u {unsigned long vi; unsigned char c[sizeof(unsigned long)];}; 
   union v {unsigned long ni; unsigned char d[sizeof(unsigned long)];};
   union u un; 
   union v vn; 
   un.vi = nLongNumber; 
   vn.d[0]=un.c[3]; 
   vn.d[1]=un.c[2]; 
   vn.d[2]=un.c[1]; 
   vn.d[3]=un.c[0]; 
   return (vn.ni); 
}
*/
int main(int argc, char *argv[])
{
 int numRead;
 char *ascTime;
 long long unsigned test;

 unsigned long start_time;
 double runningTime;
 struct tm *start_time_struct;
 float meas_freq;
 double sampleRate;
 double accSeconds;
 double fracSeconds;

 unsigned long number_of_measurements;
 
 double calibration_bias1;
 double calibration_offset1;
 double calibration_bias2;
 double calibration_offset2;
 double calibration_bias3;
 double calibration_offset3;
 
 short unsigned *accel1,*accel2,*accel3;
 double *gaccel1,*gaccel2,*gaccel3;


if (argc < 2)
  {
    printf("Need a filename!\n");
    return 0;
  }

fp = fopen(argv[1], "rb");
if (fp == NULL)
   exit(EXIT_FAILURE);



 numRead = fread(&start_time,sizeof(start_time),1,fp);
 fread(&meas_freq,sizeof(meas_freq),1,fp);
 fread(&number_of_measurements,sizeof(number_of_measurements),1,fp);
 fread(&calibration_bias1,sizeof(calibration_bias1),1,fp); 
 fread(&calibration_offset1,sizeof(calibration_offset1),1,fp);
 fread(&calibration_bias2,sizeof(calibration_bias2),1,fp); 
 fread(&calibration_offset2,sizeof(calibration_offset2),1,fp);
 fread(&calibration_bias3,sizeof(calibration_bias3),1,fp); 
 fread(&calibration_offset3,sizeof(calibration_offset3),1,fp);
/* 
 accel1 = fread(fid,number_of_measurements,'uint16');
 accel2 = fread(fid,number_of_measurements,'uint16');
 accel3 = fread(fid,number_of_measurements,'uint16');
*/

*(unsigned long *)&meas_freq = (unsigned long)ByteSwapL(*((unsigned long *)&meas_freq));
start_time = (unsigned long)ByteSwapL((unsigned long)start_time);
number_of_measurements = (unsigned long)ByteSwapL(number_of_measurements);
start_time_struct = gmtime((time_t *)&start_time);
ascTime = asctime(start_time_struct);
*(unsigned long long *)&calibration_bias1 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_bias1));
*(unsigned long long *)&calibration_offset1 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_offset1));
*(unsigned long long *)&calibration_bias2 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_bias2));
*(unsigned long long *)&calibration_offset2 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_offset2));
*(unsigned long long *)&calibration_bias3 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_bias3));
*(unsigned long long *)&calibration_offset3 = (unsigned long long)ByteSwapLL(*((unsigned long long *)&calibration_offset3));
//printf("Start time is:%s",ascTime);
//printf("Time = %lu\n",start_time);
//printf("Freq = %f\n",meas_freq);
//printf("Number = %lu\n",number_of_measurements);
//printf("Cal bias1 = %f\n",calibration_bias1);
//printf("Cal offset1 = %f\n",calibration_offset1);
//printf("Cal bias2 = %f\n",calibration_bias2);
//printf("Cal offset2 = %f\n",calibration_offset2);
//printf("Cal bias3 = %f\n",calibration_bias3);
//printf("Cal offset3 = %f\n",calibration_offset3);

accel1 = calloc(number_of_measurements,sizeof(*accel1));
numRead = fread(accel1,sizeof(*accel1),number_of_measurements,fp);
//printf("Accel1 = %d\n",numRead);
accel2 = calloc(number_of_measurements,sizeof(*accel2));
numRead = fread(accel2,sizeof(*accel2),number_of_measurements,fp);
//printf("Accel2 = %d\n",numRead);
accel3 = calloc(number_of_measurements,sizeof(*accel3));
numRead = fread(accel3,sizeof(*accel3),number_of_measurements,fp);
//printf("Accel3 = %d\n",numRead);

gaccel1 = calloc(number_of_measurements,sizeof(*gaccel1));
gaccel2 = calloc(number_of_measurements,sizeof(*gaccel2));
gaccel3 = calloc(number_of_measurements,sizeof(*gaccel3));

runningTime=(double)(start_time-1303135200);
sampleRate = 1.0/(double)meas_freq;

for (numRead = 0;numRead<number_of_measurements;numRead++)
{
 accel1[numRead] = ByteSwapS(accel1[numRead]);
 accel2[numRead] = ByteSwapS(accel2[numRead]);
 accel3[numRead] = ByteSwapS(accel3[numRead]);

 gaccel1[numRead] = calibration_bias1*((double)accel1[numRead]/65535.0)+calibration_offset1;
 gaccel2[numRead] = calibration_bias2*((double)accel2[numRead]/65535.0)+calibration_offset2;
 gaccel3[numRead] = calibration_bias3*((double)accel3[numRead]/65535.0)+calibration_offset3;

 accSeconds = sampleRate*(double)numRead;
// runningTime = start_time + (long long unsigned)accSeconds;
// fracSeconds = accSeconds - trunc(accSeconds);

 printf("%20f%10.2f%10.2f%10.2f\n",runningTime+accSeconds,gaccel1[numRead],gaccel2[numRead],gaccel3[numRead]);

// printf("%20f%10f%10.2f%10.2f%10.2f\n",runningTime+accSeconds,fracSeconds,gaccel1[numRead],gaccel2[numRead],gaccel3[numRead]);
// printf("%d,%hu,%hu,%hu\n",numRead,accel1[numRead],accel2[numRead],accel3[numRead]);

}
free(accel1);
free(accel2);
free(accel3);
free(gaccel1);
free(gaccel2);
free(gaccel3);
fclose(fp);

return 0;
}//End of Main

