
	/*
	** This program parses an EMA response CSV file
	** to create an EatMon -events.txt file.
	** The portion to be converted (which day of activities)
	** is indicated by the date within the filename of
	** the .act file given at the command prompt.
	**
	** There are two types of activities:  self-reported planned
	** meals and self-reported meal lapses.  Both are eating activites;
	** the difference is whether or not the subject had intended to
	** eat or succumbed to an unintended temptation or pressure to eat.
	** The type is designated in the start of string as "planned" or
	** "lapse".
	** 
	** Each activity only has a single reported time (moment), not a
	** span (beginning and end).  Subjects reported #mins spent eating
	** but this data is not currently used (looks unreliable).
	**
	** Subject ID# is taken from field B.  Lapse meal days/times are
	** taken from field N.  Planned meal days/times from field T.
	*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define	DEBUG		0
#define	MAX_MEALS	100
#define	SWAP_INT(x,y)	{ swap_int=x; x=y; y=swap_int; }
#define	SWAP_STR(x,y)	{strcpy(swap_str,x); strcpy(x,y); strcpy(y,swap_str);}

	/* conversion functions unix-to-timestamp (below) */
void DateFromTimestamp();
int TimeStamp(unsigned char, unsigned char, unsigned char,
		unsigned char, unsigned char, unsigned char);


int main(int argc, char *argv[])

{
FILE	*fpt;
int	i,j,field,length;
int	a,b,c,d;
int	ValidEMA;
char	text[320],byte;
int	year,month,day,subID;
int	ema_year,ema_month,ema_day,ema_hour,ema_minute,ema_type;
char	meal_name[MAX_MEALS][80];
char	meal_start[MAX_MEALS][80],meal_end[MAX_MEALS][80];
int	meal_unixtime[MAX_MEALS];
int	TotalMeals;
char	events_filename[320];
char	start_line[320],end_line[320];
unsigned char	cyear,cmonth,cday,chour,cminute,csecond;
int	smallest;
char	swap_str[320];
int	swap_int;


if (argc != 3)
  {
  printf("Usage:  ema-to-events [ema.csv] [YYYY-MM-DD.act]\n");
  exit(0);
  }

	/* get subject ID# from path name */
strncpy(text,argv[2],3);
text[3]=0;
subID=atoi(text);
if (subID < 101  ||  subID > 141)
  {
  printf("Expected subject ID >= 101 and <= 141\n");
  exit(0);
  }

	/* get year, month, day from act filename */
strcpy(text,argv[2]);
i=strlen(text);
text[i-4]=text[i-7]=text[i-10]=0;
year=atoi(&(text[i-14]));
month=atoi(&(text[i-9]));
day=atoi(&(text[i-6]));
if (year < 2015  ||  year > 2025  ||  month < 1  ||  month > 12)
  {
  printf("Check act filename:  *YYYY-MM-DD.act\n");
  exit(0);
  }


	/* read the events file to get the START and END lines */
strcpy(events_filename,argv[2]);
events_filename[strlen(events_filename)-4]=0;
strcat(events_filename,"-events.txt");
if ((fpt=fopen(events_filename,"r")) == NULL)
  {
  printf("Unable to open %s for reading\n",events_filename);
  exit(0);
  }
fgets(start_line,320,fpt);
while (1)
  {
  if (fgets(end_line,320,fpt) == NULL)
    break;
  }
fclose(fpt);
start_line[strlen(start_line)-1]=0;
end_line[strlen(end_line)-1]=0;
if (strncmp(start_line,"START",5) != 0  ||  strncmp(end_line,"END",3) != 0)
  {
  printf("** ABORTING **\n");
  printf("%s does not have START and END lines?\n",events_filename);
  printf("%s\n%s\n",start_line,end_line);
  exit(0);
  }


	/* read the EMA file */
if ((fpt=fopen(argv[1],"r")) == NULL)
  {
  printf("Unable to open %s for reading\n",argv[1]);
  exit(0);
  }
TotalMeals=0;
field=0;
length=0;
while (1)
  {
  i=fread(&byte,1,1,fpt);
  if (i == 1  &&  byte == '\r')
    continue;
  if (i == 0  ||  byte == ','  ||  byte == '\n')
    {
    text[length]=0;
    if (DEBUG)
      printf("%d => %s\n",field,text);
    if (field == 0)
      {
      if (atoi(text) > 0)	/* survey number */
        ValidEMA=1;
      else
        ValidEMA=0;
      }
    if (field == 1)
      {
      if (atoi(text) == subID)
	ValidEMA=1;
      else
	ValidEMA=0;
      }
    if (ValidEMA == 1  &&
	(field == 13  ||  field == 19))	/* 13=lapse, 19=planned */
      {
      if (strlen(text) > 1)
        {
        a=0;
        while (text[a] != '/'  &&  text[a] != 0)
          a++;
        b=a+1;
        while (text[b] != '/'  &&  text[b] != 0)
          b++;
        c=b+1;
        while (text[c] != ' '  &&  text[c] != 0)
          c++;
        d=c+1;
        while (text[d] != ':'  &&  text[d] != 0)
          d++;
        text[a]=text[b]=text[c]=0;
        ema_month=atoi(&(text[0]));
        ema_day=atoi(&(text[a+1]));
        ema_year=atoi(&(text[b+1]));
        ema_hour=atoi(&(text[c+1]));
        ema_minute=atoi(&(text[d+1]));
        if (ema_year == year  &&  ema_month == month   &&  ema_day == day)
	  {
          if (field == 13)
  	    strcpy(meal_name[TotalMeals],"lapse");
  	  else
	    strcpy(meal_name[TotalMeals],"planned");
	  sprintf(meal_start[TotalMeals],"%02d:%02d:00",ema_hour,ema_minute);
	  sprintf(meal_end[TotalMeals],"%02d:%02d:59",ema_hour,ema_minute);
          TotalMeals++;
	  }
        }
      }
    field++;
    length=0;
    if (i == 0)
      break;
    if (byte == '\n')
      {
      if (ema_year != year  ||  ema_month != month  ||  ema_day != day)
        ValidEMA=0;
      if (ValidEMA)
        {
        }
      field=0;
      }
    continue;
    }
  text[length]=byte;
  length++;
  }
fclose(fpt);


	/* convert meal date/time to unix timestamps */
for (i=0; i<TotalMeals; i++)
  {
  strcpy(text,meal_start[i]);
  cyear=year;
  cmonth=month;
  cday=day;
  csecond=0;	/* precision recorded to minute */
  text[strlen(text)-3]=0;
  csecond=(unsigned char)atoi(&(text[strlen(text)+1]));
  text[strlen(text)-3]=0;
  cminute=(unsigned char)atoi(&(text[strlen(text)+1]));
  chour=(unsigned char)atoi(&(text[0]));
  meal_unixtime[i]=TimeStamp(cyear,cmonth,cday,chour,cminute,csecond);
  }

	/* sort meals by unix timestamps */
for (i=0; i<TotalMeals; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalMeals; j++)
    if (meal_unixtime[j] < meal_unixtime[smallest])
      smallest=j;
  if (smallest != i)
    {
    SWAP_STR(meal_name[i],meal_name[smallest]);
    SWAP_STR(meal_start[i],meal_start[smallest]);
    SWAP_STR(meal_end[i],meal_end[smallest]);
    SWAP_INT(meal_unixtime[i],meal_unixtime[smallest]);
    }
  }

	/* eliminate duplicates */
for (i=0; i<TotalMeals-1; i++)
  {
  if (strcmp(meal_start[i],meal_start[i+1]) == 0)
    {
    // strcpy(meal_name[i],"both");
    for (j=i+1; j<TotalMeals-i; j++)
      {
      strcpy(meal_name[j],meal_name[j+1]);
      strcpy(meal_start[j],meal_start[j+1]);
      strcpy(meal_end[j],meal_end[j+1]);
      meal_unixtime[j]=meal_unixtime[j+1];
      }
    TotalMeals--;
    i--;
    }
  }


if (0)	/* print out all meals */
  {
  printf("%s\n",start_line);
  for (i=0; i<TotalMeals; i++)
    printf("%s %s %s Unknown Unknown Unknown Unknown Unknown\n",
	meal_name[i],meal_start[i],meal_end[i]);
  printf("%s\n",end_line);
  }

if (1)	/* write new events file */
  {
  fpt=fopen(events_filename,"w");
  fprintf(fpt,"%s\n",start_line);
  for (i=0; i<TotalMeals; i++)
    fprintf(fpt,"%s %s %s Unknown Unknown Unknown Unknown Unknown\n",
	meal_name[i],meal_start[i],meal_end[i]);
  fprintf(fpt,"%s\n",end_line);
  fclose(fpt);
  }

}
	






	/* convert a seconds-since-Jan1,2000 timestamp into date components */
void DateFromTimestamp(unsigned int timestamp,
                        int     *Year,		  /* 0...256 (can be added to 2000 to get 4-digit year) */
                        int     *Month,		  /* 0...11 */
                        int     *Day,		  /* 0...30 */
                        int     *Hour,		  /* 0...23 */
                        int     *Min,		  /* 0...59 */
                        int     *Sec)		  /* 0...59 */

{
unsigned int    total_seconds;
unsigned int    days_in_month[12]={31,28,31,30,31,30,31,31,30,31,30,31};

total_seconds=timestamp;
*Year=0;
while (total_seconds >= 31536000)
  {
  if ((*Year)%4 == 0)
    {
    if (total_seconds < 31536000+86400)
      break;
    total_seconds-=(31536000+86400);
    }
  else
    total_seconds-=(31536000);
  (*Year)++;
  }
if ((*Year)%4 == 0)
  days_in_month[1]=29;	/* leap year */
*Month=0;
while (total_seconds >= days_in_month[*Month]*86400)
  {
  total_seconds-=(days_in_month[*Month]*86400);
  (*Month)++;
  }
*Day=0;
while (total_seconds >= 86400)
  {
  total_seconds-=(86400);
  (*Day)++;
  }
*Hour=(total_seconds/3600);
total_seconds-=((*Hour)*3600);
*Min=(total_seconds/60);
*Sec=(total_seconds%60);
}



	/* compute the time in seconds, since Jan 1 2000 12:00am */
	/* the month and day are 1-indexed */
int TimeStamp(unsigned char RTCYEARL,		/* 0...256 */
			  unsigned char	RTCMON,			/* 1...12 */
			  unsigned char	RTCDAY,			/* 1...31 */
			  unsigned char	RTCHOUR,		/* 0...23 */
			  unsigned char	RTCMIN,			/* 0...59 */
			  unsigned char	RTCSEC)			/* 0...59 */
{
const int   days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int         j;
int			elapsed;

elapsed=0;
for (j=0; j<RTCYEARL; j++)
  elapsed+=31536000;
j=(RTCYEARL+3)/4;
elapsed+=(j*86400);
for (j=1; j<RTCMON; j++)
  elapsed+=(days[j-1]*86400);
if (RTCYEARL%4 == 0  &&  RTCMON > 2)
  elapsed+=86400;
elapsed+=((RTCDAY-1)*86400);
elapsed+=(RTCHOUR*3600);
elapsed+=(RTCMIN*60);
elapsed+=RTCSEC;
return(elapsed);
}






