
#define _CRT_SECURE_NO_WARNINGS	  /* disable compiler warnings for standard C functions like strcpy() */

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winuser.h>
#include <math.h>

#include "globals.h"

#define	TREND_WINDOW  150

int ReadFiles()

{
FILE	*fpt;
char	SyncFilename[320];
int		i,j,k;
double	zero[3],total;
double	yaw,pitch,roll,last_yaw,last_pitch,last_roll;
int		Participant,Course,p,c;
char	text[320],food[320];
float	kcals;

		/* read data file, determine total amount of data */
DataLoaded=0;
if ((fpt=fopen(DataFilename,"r")) == NULL)
  return(0);
TotalData=0;
if (strstr(DataFilename,"inertiacube") != NULL)
  {				/* file format is yaw pitch roll, units are orientation (deg) */
  while (1)
	{
	i=fscanf(fpt,"%lf %lf %lf",&yaw,&pitch,&roll);	  /* orientations (deg), not deg/sec */
	if (i != 3)
	  break;
	Data[0][TotalData]=Data[1][TotalData]=Data[2][TotalData]=Data[6][TotalData]=0.0;
	if (TotalData == 0)
	  Data[3][TotalData]=Data[4][TotalData]=Data[5][TotalData]=0.0;
	else		/* deg/sec calcualted from two consecutive orientations */
	  {
	  Data[3][TotalData]=(yaw-last_yaw)*15.0;		/* data is 15 Hz */
	  Data[4][TotalData]=(pitch-last_pitch)*15.0;
	  Data[5][TotalData]=(roll-last_roll)*15.0;
	  }
	last_yaw=yaw;
	last_pitch=pitch;
	last_roll=roll;
	TotalData++;
	}
  fclose(fpt);
  DataLoaded=1;
  }
else if (strstr(DataFilename,"stmicro_gyr") != NULL)
  {				/* file format is pitch roll, units are deg/sec */
  while (1)
	{
	i=fscanf(fpt,"%lf %lf",&(Data[4][TotalData]),&(Data[5][TotalData]));	  /* orientations (deg), not deg/sec */
	if (i != 2)
	  break;
	Data[0][TotalData]=Data[1][TotalData]=Data[2][TotalData]=Data[3][TotalData]=Data[6][TotalData]=0.0;
	TotalData++;
	}
  fclose(fpt);
  DataLoaded=1;
  }
else
  {				/* file format is x y z (accel units are volts) yaw pitch roll (gyro units are volts) scale (units are grams) */
  zero[0]=zero[1]=zero[2]=0.0;  /* used to calculate average values of yaw pitch roll */
  while (1)
	{
	i=fscanf(fpt,"%lf %lf %lf  %lf %lf %lf  %lf",
			  &(Data[0][TotalData]),&(Data[1][TotalData]),&(Data[2][TotalData]),	/* x y z */
			  &(Data[3][TotalData]),&(Data[4][TotalData]),&(Data[5][TotalData]),	/* yaw pitch roll */
			  &(Data[6][TotalData]));												/* scale */
	if (i != 7)
	  break;
	for (j=0; j<3; j++)
	  zero[j]+=Data[j+3][TotalData];
	TotalData++;
	}
  fclose(fpt);
  DataLoaded=1;
  for (j=0; j<3; j++)
	zero[j]/=(double)TotalData;
  ScaleAverage=0.0;
  for (i=0; i<TotalData; i++)
	ScaleAverage+=Data[6][i];
  ScaleAverage/=(double)TotalData;

		  /* convert data voltages to deg/sec (gyros) and gravities (accelerometers) */
		  /* gyro=LPY410al, 2.5mv per deg/sec, zero-point found by calculating the average data value of the whole recording */
		  /* accel=LIS344alh, Vdd=3.3v, 5/3.3=1.515 gravities per volt */
  for (i=0; i<TotalData; i++)
	{
	for (j=0; j<3; j++)
	  Data[j][i]=(Data[j][i]-1.65)*(5.0/3.3);	  /* 3.3v supply so 1/2(3.3)=1.65 reference */ /* 15/3.3=4.5454 instead, if chip wired to +-6g */
	for (j=3; j<6; j++)
	  Data[j][i]=(Data[j][i]-zero[j-3])*400.0;	  /* reference voltage calculated as average ADC value for while file */
	}
  }

		/* smooth the data */
for (i=0; i<7; i++)
  for (j=0; j<7; j++)
	SmoothedData[j][i]=Data[j][i];
for (i=TotalData-7; i<TotalData; i++)
  for (j=0; j<7; j++)
	SmoothedData[j][i]=Data[j][i];
for (i=7; i<TotalData-7; i++)
  {
  for (j=0; j<7; j++)
	{			/* simple averaging over a 1-second window (15 samples) centered on the datum */
	total=0.0;
	for (k=i-7; k<=i+7; k++)
	  if (k >= 0  &&  k < TotalData)
	    total+=Data[j][k];
	SmoothedData[j][i]=total/15.0;
	}
  }

		/* read sync file to determine video file name and time-offset between data and video */
if (strstr(DataFilename,"inertiacube") != NULL  ||  strstr(DataFilename,"stmicro_gyr") != NULL)
  {
  strcpy(SyncFilename,DataFilename);
  SyncFilename[strlen(DataFilename)-16]=0;
  strcat(SyncFilename,"_sync.txt");
  }
else
  {
  strcpy(SyncFilename,DataFilename);
  SyncFilename[strlen(DataFilename)-4]=0;
  strcat(SyncFilename,"_sync.txt");
  }
VideoLoaded=0;
if ((fpt=fopen(SyncFilename,"r")) != NULL)
  {
  fscanf(fpt,"%d",&VideoSyncOffset);
  fscanf(fpt,"%s",VideoFilename);
  if (strstr(VideoFilename,".") == NULL)	/* if no filename extension supplied assume it is .asf and add it */
	strcat(VideoFilename,".asf");
  fclose(fpt);
  VideoLoaded=OpenVideoFile(VideoFilename,&DISPLAY_ROWS,&DISPLAY_COLS);
  if (VideoLoaded)
	disp_image=(unsigned char *)calloc(DISPLAY_ROWS*DISPLAY_COLS*3,1);
  }

		/* read foods.txt file to get names of foods in meal */
FoodsLoaded=0;
TotalFoodsInMeal=0;
if ((fpt=fopen("foods.txt","r")) != NULL)
  {
  while (1)
	{
	i=fscanf(fpt,"%s",FoodsInMeal[TotalFoodsInMeal]);
	if (i != 1)
	  break;
	TotalFoodsInMeal++;
	}
  fclose(fpt);
  FoodsLoaded=1;
  }

		/* read food_log_with_kcals.txt to get kcals consumed of each food */
for (i=0; i<TotalFoodsInMeal; i++)
  {
  FoodKcals[i]=-1;	  /* -1 means don't know */
  FoodBites[i]=-1;
  FoodKPB[i]=-1.0;
  }
if ((fpt=fopen("../../food_log_with_kcals.txt","r")) != NULL)
  {
  for (i=0; i<4; i++)
	fscanf(fpt,"%s",text);	  /* header, don't need */
  Course=(int)(DataFilename[strlen(DataFilename)-23]-'0');
  Participant=(int)(DataFilename[strlen(DataFilename)-28]-'0')*100+
			  (int)(DataFilename[strlen(DataFilename)-27]-'0')*10+
			  (int)(DataFilename[strlen(DataFilename)-26]-'0')*1;
  while (1)
	{
	i=fscanf(fpt,"%d %d %s %f",&p,&c,food,&kcals);
	if (i != 4)
	  break;
	if (p != Participant  ||  c != Course)
	  continue;
	for (i=0; i<TotalFoodsInMeal; i++)
	  if (strcmp(FoodsInMeal[i],food) == 0)
		break;
	if (i == TotalFoodsInMeal)
	  {
	  MessageBox(NULL,"Non-matching food lists","foods.txt names do not match food_log_with_kcals.txt names",MB_OK | MB_APPLMODAL);
	  continue;
	  }
	FoodKcals[i]=(int)kcals;
	}
  fclose(fpt);
  }

		/* read scale.vid file to get video of scale data (if present) */
if ((fpt=fopen("scale.vid","rb")) != NULL)
  {
  if (scale_video != NULL)
	free(scale_video);
  scale_video=(unsigned char *)calloc(SCALE_ROWS*SCALE_COLS*TotalData,1);
  fread(scale_video,1,SCALE_ROWS*SCALE_COLS*TotalData,fpt);
  fclose(fpt);
  }

return(1);
}


int LoadGT()

{
int		i,j,k,BiteNumber,DuplicateBites;
FILE	*fpt;
char	text[320];

		/* read GT file, determine total amount of bites */
TotalGTBites=0;
if ((fpt=fopen(GTFilename,"r")) == NULL)
  return(0);
while (1)
  {
  i=fscanf(fpt,"%d  %d  %s %s %s %s",
			&BiteNumber,&(GTBiteIndex[TotalGTBites]),
			GTBiteHand[TotalGTBites],GTBiteUtensil[TotalGTBites],
			GTBiteContainer[TotalGTBites],GTBiteFood[TotalGTBites]);
  if (i != 6)
	break;
  TotalGTBites++;
  }
fclose(fpt);
		/* count any duplicates, delete them and warn user */
DuplicateBites=0;
for (i=0; i<TotalGTBites-1; i++)
  {
  for (j=i+1; j<TotalGTBites; j++)
	{
	if (GTBiteIndex[i] == GTBiteIndex[j])
	  {
	  for (k=j; k<TotalGTBites-1; k++)
		{
		GTBiteIndex[k]=GTBiteIndex[k+1];
		strcpy(GTBiteHand[k],GTBiteHand[k+1]);
		strcpy(GTBiteUtensil[k],GTBiteUtensil[k+1]);
		strcpy(GTBiteContainer[k],GTBiteContainer[k+1]);
		strcpy(GTBiteFood[k],GTBiteFood[k+1]);
		}
	  TotalGTBites--;
	  j--;
	  DuplicateBites++;
	  }
	}
  }
if (DuplicateBites > 0)
  {
  sprintf(text,"%d duplicate bites deleted",DuplicateBites);
  MessageBox(NULL,text,"Warning",MB_OK | MB_APPLMODAL);
  }
		/* calculate KPB and total bites for each food */
for (i=0; i<TotalFoodsInMeal; i++)
  {
  FoodBites[i]=0;
  FoodKPB[i]=(float)999.9;
  for (j=0; j<TotalGTBites; j++)
	if (strcmp(GTBiteFood[j],FoodsInMeal[i]) == 0)
	  FoodBites[i]++;
  if (FoodBites[i] > 0)
	FoodKPB[i]=(float)FoodKcals[i]/(float)FoodBites[i];
  }
return(1);
}



int SaveGT(char *filename)

{
int		i,j,smallest,temp;
char	temps[160];
FILE	*fpt;

		/* sort bites */
for (i=0; i<TotalGTBites-1; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalGTBites; j++)
	if (GTBiteIndex[j] < GTBiteIndex[smallest])
	  smallest=j;
  temp=GTBiteIndex[smallest]; GTBiteIndex[smallest]=GTBiteIndex[i]; GTBiteIndex[i]=temp;
  strcpy(temps,GTBiteHand[smallest]); strcpy(GTBiteHand[smallest],GTBiteHand[i]);
  strcpy(GTBiteHand[i],temps);
  strcpy(temps,GTBiteUtensil[smallest]); strcpy(GTBiteUtensil[smallest],GTBiteUtensil[i]);
  strcpy(GTBiteUtensil[i],temps);
  strcpy(temps,GTBiteContainer[smallest]); strcpy(GTBiteContainer[smallest],GTBiteContainer[i]);
  strcpy(GTBiteContainer[i],temps);
  strcpy(temps,GTBiteFood[smallest]); strcpy(GTBiteFood[smallest],GTBiteFood[i]);
  strcpy(GTBiteFood[i],temps);
  }
		/* write bites to file */
fpt=fopen(filename,"w");
if (fpt == NULL)
  {
  MessageBox(NULL,"Unable to open ground truth file.","Ground Truth File",MB_OK | MB_APPLMODAL);
  return(0);
  }
else
  {
  for (i=0; i<TotalGTBites; i++)
	fprintf(fpt, "%d\t%d\t%s\t%s\t%s\t%s\n", 
			i+1,GTBiteIndex[i],GTBiteHand[i],GTBiteUtensil[i],GTBiteContainer[i],GTBiteFood[i]);
  fclose(fpt);
  }
return(1);
}



int LoadMDBites(char *filename)

{
int		i;
FILE	*fpt;

TotalMDBites=0;
if ((fpt=fopen(filename,"r")) == NULL)
  return(0);
while (1)
  {
  i=fscanf(fpt,"%d",&(MDBiteIndex[TotalMDBites]));
  if (i != 1)
	break;
  TotalMDBites++;
  }
fclose(fpt);
return(1);
}



int LoadGestures(char *filename,
				 int *TotalGestures,
				 int *GestureStart,
				 int *GestureEnd,
				 int *GestureType)

{
int		i;
FILE	*fpt;
char	text[320];

		/* read gestures file, determine total amount of gestures */
*TotalGestures=0;
if ((fpt=fopen(filename,"r")) == NULL)
  return(0);
while (1)
  {
  i=fscanf(fpt,"%s  %d  %d",text,&GestureStart[*TotalGestures],&GestureEnd[*TotalGestures]);
  if (i != 3)
	break;
  if (strcmp(text,"bite") == 0)
	GestureType[*TotalGestures]=0;
  else if (strcmp(text,"drink") == 0)
	GestureType[*TotalGestures]=1;
  else if (strcmp(text,"other") == 0)
	GestureType[*TotalGestures]=2;
  else if (strcmp(text,"rest") == 0)
	GestureType[*TotalGestures]=3;
  else if (strcmp(text,"utensiling") == 0)
	GestureType[*TotalGestures]=4;
  else
	GestureType[TotalGTGestures]=-1;	/* unknown */
  (*TotalGestures)++;
  }
fclose(fpt);
return(1);
}

